01 / 导读
导读
引用
Gambetta, G. (2021). Computer Graphics from Scratch: A Programmer's Introduction to 3D Rendering. No Starch Press. Free official edition: https://gabrielgambetta.com/computer-graphics-from-scratch/
章节概要
引言
引言把主题限定在计算机图形学的一个分支:三维场景的渲染。Gambetta 曾在大学讲授这门三年级课程五年,本书面向从高中生到专业工程师的读者;对于每个业界标准算法,他都选择最容易理解的版本,同时避免含糊其辞。书中唯一假定的基本操作,是设置单个像素颜色的函数。本书构建两个渲染器——光线追踪器和光栅化器——使用与具体语言无关的伪代码,并附有可运行的 JavaScript 演示链接;它有意不讲 OpenGL、Vulkan、Metal 或 DirectX 等 API。
第1章:入门概念
这一短章定义画布及其坐标系、唯一的绘图操作 PutPixel,以及颜色的表示方法:减色模型与加色模型、颜色深度,以及带截断的颜色缩放与相加等运算。最后介绍场景及其三维坐标系,这是全书两个部分共同的基础。
第2章:基础光线追踪
第一部分从一个类比开始:透过固定的捕虫网观察风景,逐格照抄每个网格中看到的颜色来作画。由此推导出固定的相机和视口、从画布像素到视口点的映射、射线方程、球面方程,以及求两者交点的二次方程。结果是第一个光线追踪器,它把球体画成纯色的圆。
第3章:光照
光线追踪器加入了光照。本章定义点光源、平行光和环境光,然后用漫反射(利用表面法线以及与光线的夹角)为哑光表面建模,用由镜面指数控制的镜面项为光亮表面建模,并把它们合成为完整的光照方程。球体由此显得立体。
第4章:阴影与反射
物体之间开始相互影响。阴影的计算方法是从每个点向每个光源发射射线并检查是否有遮挡;反射则通过递归追踪反射射线来计算,并设置递归上限,以免在镜面之间无限反弹。
第5章:扩展光线追踪器
本章概述超出本书范围的功能:可任意放置并旋转的相机、性能技术(并行化、缓存、阴影优化、空间数据结构、子采样)、三角形等其他图元、构造实体几何、带折射的透明效果以及超采样。本章最后解释了为什么光线追踪一直难以实时运行,从而引出第二部分。
第6章:直线
第二部分再次从空白画布出发。本章用 PutPixel 开发绘制任意斜率线段的算法,并引入 Interpolate 辅助函数,在整数步长上计算线性函数的值;作者强调本书后续各处都会用到这个函数。
第7章:填充三角形
在直线的基础上,本章先绘制线框三角形,再绘制填充三角形:先对顶点排序,再把三角形看作一摞水平线段,其端点沿边插值得到。
第8章:着色三角形
填充算法被扩展为在三角形上插值一个强度值:先沿各边,再沿每条水平线段插值,从而产生平滑的渐变。作者指出,同样的方法可以插值任何在屏幕上线性变化的顶点属性,后续章节正是利用了这一点。
第9章:透视投影
本书转向三维,用相似三角形推导透视投影方程,考察其性质(直线投影后仍为直线),并投影立方体的顶点,以线框形式画出立方体。本章留下两个问题:几何数据与投影代码混在一起,以及位于相机后方的点。
第10章:描述与渲染场景
这一长章把物体表示为由顶点和三角形组成的模型,在场景中放置同一模型的多个实例,并应用模型变换和相机变换,使相机可以移动。随后引入齐次坐标,把旋转、缩放、平移、投影以及视口到画布的映射都表示为矩阵,从而把一整串变换压缩为少数几次矩阵乘法。
第11章:裁剪
为了处理位于相机后方或视野之外的几何体,本章定义由五个平面围成的裁剪体,然后用包围球裁剪整个物体,并通过计算线段与平面的交点来裁剪单个三角形,给出伪代码,并讨论裁剪在渲染管线中的位置。
第12章:隐藏面消除
为了渲染实体,本章比较画家算法与深度缓冲,解释为什么缓冲区存储的是 1/Z 而不是 Z,并加入背面剔除——用一个简单的代数测试跳过背向相机的三角形。
第13章:着色
第3章的光照方程现在被应用到三角形上。本章区分光照与着色,并介绍速度与质量之间的三种折中:平面着色、Gouraud 着色(插值顶点光照)和 Phong 着色(插值法线并逐像素计算光照)。
第14章:纹理
本章以一个木箱纹理为贯穿示例,把图像"画"到三角形上。它说明在透视下简单插值纹理坐标为何会出错,推导出透视校正纹理映射,再用双线性过滤、多级渐远纹理(mipmap)和三线性过滤提高质量。
第15章:扩展光栅化器
最后一章概述更多技术:法线贴图、环境贴图,以及光栅化器中实现阴影的两种方法——模板阴影(在模板缓冲中对阴影体计数)和阴影贴图。
附录:线性代数;后记
附录以实用的方式介绍书中用到的点、向量、点积与叉积,以及矩阵及其乘法。后记建议了后续可以学习的主题,包括全局光照、基于物理的渲染、体素渲染和细节层次算法。
核心概念
第1章:入门概念
- 画布与
PutPixel:由像素组成的矩形网格,以及设置单个像素颜色这一唯一操作,其他一切都在此基础上构建。 - 加色模型:把颜色表示为红、绿、蓝三种相加的强度,与屏幕发光的方式一致。
第2–5章:光线追踪
- 射线与球体求交:把射线方程代入球面方程,得到一个二次方程,其根就是交点。
- 漫反射与镜面反射:哑光表面按法线与光线之间的夹角散射光,光亮表面则在镜面反射方向附近增加高光。
- 阴影射线与递归反射:向光源方向和反射方向追踪额外的射线,以模拟物体之间的相互影响。
第6–8章:直线与三角形
- 线性插值(
Interpolate):计算线性函数等间距的取值,是光栅化器的主力工具。 - 扫描线填充三角形:把三角形画成位于插值得到的边界之间的一条条水平线段。
- 属性插值:把任何逐顶点的值(强度、深度、纹理坐标)在三角形上传递开。
第9–11章:投影、场景与裁剪
- 透视投影:除以深度,使远处的点显得更靠近视野中心。
- 齐次坐标:增加第四个坐标,使平移和投影也能像旋转和缩放一样写成矩阵乘法。
- 裁剪体:由五个平面围成、可以安全投影的区域;其外的几何体被移除或切除。
第12–15章:可见性、着色与纹理
- 深度缓冲:逐像素的记录(此处记录 1/Z),无论绘制顺序如何都只保留最近的表面。
- Gouraud 着色与 Phong 着色:前者插值在顶点处计算的光照,后者插值法线并逐像素计算光照。
- 透视校正纹理映射与多级渐远纹理:在投影下正确插值纹理坐标,并使用预先过滤的小尺寸纹理来避免失真。
评析
优点
- 真正从零开始。 本书只以
PutPixel为起点,从简单的几何中推导出每一种技术,使读者明白每个方程的来历。透过捕虫网作画的类比让光线追踪的设置变得直观。 - 两个渲染器的对比。 为同一场景同时构建光线追踪器和光栅化器,使本书能够对比两者的长处:阴影和递归反射在光线追踪器中十分自然,而纹理和速度则是光栅化器的优势。第13章明确沿用了第3章的光照模型。
- 与语言无关的伪代码和在线演示。 大多数章节都链接到可在浏览器中运行的 JavaScript 实现,读者可以把自己的代码与参考实现对照,并看到每一步的视觉效果。
- 章节短小集中,总结清晰。 每章都以一段总结结束,说明构建了什么、还剩下哪些局限,使整体进度易于跟随和复习。
局限
- 没有练习题。 书中没有习题,练习只能来自实现渲染器本身,因此教师需要自行布置作业。
- 简化的光照模型。 光照模型(环境光、漫反射、Phong 式镜面反射)是经验性的而非基于物理;全局光照和基于物理的渲染只在后记中被提及。
- 不涉及 GPU 和图形 API。 本书有意不讲 OpenGL、Vulkan、DirectX 或着色器编程,需要掌握实际实时图形技能的学生必须另找资料。
- 高级主题仅作概述。 第5章和第15章以概览形式介绍加速结构、折射、法线贴图和阴影技术,没有给出完整的算法或分析。
在课程中的定位
在本课程的图形学书单中,Gambetta 的书是渲染学习的起点;同为入门读物的 Rogers、Sharp 和 Preece 的 Interaction Design 涵盖的是课程中人机交互的一面,而非渲染。在阅读 Marschner 和 Shirley 的 Fundamentals of Computer Graphics 或 Angel 和 Shreiner 的 Interactive Computer Graphics 之前,本书是很好的先导读物;这两本通常被认为是更完整的课程教材,后者讲授 WebGL 编程,正是本书刻意跳过的 API 层面。
在进阶学习方面,Real-Time Rendering(Akenine-Möller 等)把光栅化这一半延伸到现代 GPU 技术,Physically Based Rendering(Pharr、Jakob 和 Humphreys)则把光线追踪这一半推进到基于物理的光传输——本书后记正是把这一主题列为下一步。已有图形学基础的学生可以快速浏览 Gambetta,或直接转向更高阶的教材。
如何使用本书
本书适合能用任何一种语言编程、并记得高中代数和少许三角函数的读者;所需的线性代数在附录中讲解,如果不熟悉向量和矩阵,值得先读附录。
一个实用的方法是用自己选择的语言亲手实现每个渲染器,只借助某个库或浏览器画布来设置像素,遇到效果不对时再与链接的演示对照。第一部分(第2–4章)几次学习就能完成,并能很快看到图像效果;第5章是一份可选扩展的清单。第二部分(第6–14章)篇幅更长,第6–8章必须彻底理解,因为 Interpolate 和属性插值是此后一切内容的基础。第9–12章构成光栅化器的几何核心;从第13–14章开始,画面才变得逼真。第15章可以当作阅读清单。
由于没有练习题,自学的读者可以自己设定任务:实现第5章和第15章中概述的扩展,例如在光线追踪器中支持三角形、可移动的相机,或在光栅化器中实现阴影贴图。
版本与来源
本导读依据作者官方网站 https://gabrielgambetta.com/computer-graphics-from-scratch/ 上的免费在线版 Computer Graphics from Scratch,其内容即 2021 年 No Starch Press 出版的正文。内容取材于目录、引言全文、每一章(全部小节标题、章节开头和章末总结,并细读了射线与球体求交、投影方程以及使用 1/Z 的深度缓冲等核心推导)、线性代数附录和后记。
