《计算机图形学》卷二《着色、光照与纹理》目录
《计算机图形学》卷二《着色、光照与纹理》目录:16 章 48 节,只替换卷一封版的着色环节——逐顶点 Lambert 改为插值法线后逐像素求值,把光照模型、BRDF 与能量守恒、法线贴图、阴影、环境光遮蔽、微表面 PBR、sRGB 与色调映射、程序化纹理与后处理全部写成可逐像素断言的整数。本页给出分工、六档可运行性口径、卷二新基线与全书 16 章 48 节完整清单。
tag
《计算机图形学》卷二《着色、光照与纹理》目录:16 章 48 节,只替换卷一封版的着色环节——逐顶点 Lambert 改为插值法线后逐像素求值,把光照模型、BRDF 与能量守恒、法线贴图、阴影、环境光遮蔽、微表面 PBR、sRGB 与色调映射、程序化纹理与后处理全部写成可逐像素断言的整数。本页给出分工、六档可运行性口径、卷二新基线与全书 16 章 48 节完整清单。
《计算机图形学》卷二《着色、光照与纹理》全 50 篇。卷一已经把装配、深度与覆盖封版成一组可复现的整数,本卷只替换着色环节:第一部分(第 1–4 章)从经验模型推到可断言的着色——Lambert 与漫反射、Phong 与高光、着色频率与插值,BRDF 与能量守恒、常见 BRDF 的定点化、材质的组合与混合,法线的变换、切线空间、法线贴图的解压与重建,阴影贴图的原理、分辨率偏差与走样、软阴影与 PCF;第二部分(第 5–8 章)处理间接与纹理——环境光遮蔽、SSAO 的采样与噪声、环境贴图与球谐,微表面理论、金属度-粗糙度工作流、能量守恒的验证,线性空间与 sRGB、色调映射、色彩管理的整数化,纹理坐标与寻址模式、过滤与 mipmap 的构造、各向异性过滤;第三部分(第 9–12 章)做程序化纹理与数值一致——值噪声与 Perlin、分形噪声与 fBm、程序化纹理的整数化,卷积与模糊、Bloom 与泛光、色调与调色,时间抗锯齿、抖动与蓝噪声、抗锯齿的度量,最后把浮点的容差口径、图像 digest 与误差度量、CPU 与 GPU 的比对做成可验证的判据;第四部分(第 13–16 章)把材质与光照工程化并装配成完整着色链路,做三种消费的联调并交付卷三。按章节提供仿真、逻辑内核与原型;配套工程与累计快照已有验证;具体范围以对应目录说明为准,按章复现、全部事实与练习另行验收。全书围绕程序化场景《烛影山谷》与工具链 lantern 展开。
四张调试缓冲不该各写各的导出代码。本节把它们收进一个统一导出器:每张图写出 8 位 PNG、一份 sha256、一条「回读像素 == 内存缓冲」断言,再用纯 xml.etree 拼一张内嵌 base64 的 SVG 联系表,最后用 ET.fromstring 回读校验结构与内嵌字节。
二值覆盖掩码只回答「涂过没有」,调试要问「涂了几次」。本节把覆盖率存成整数计数,用双重计数与二值化基线两条不变量把它钉住;线框复用第 7 章的整数 Bresenham 只描正面三角形,并在浏览器里用加法混合让 GPU 独立算出同一份计数,再逐像素对齐。
深度缓冲不是距离,直接 gray = z*255/ONE 会把整帧压进 20 个灰度级、闲置 236 级。本节先把这个浪费量化,再用按距离等分的 8x32 分段映射把每级钉在 0.157 世界单位;法线图由插值后的顶点法线编码进 RGB,两条负例必须被模长判据拒绝。
画家算法不逐像素做深度测试,只把三角形按质心深度从远到近画、后画者胜。本节在可分离场景里让画家与 z-buffer 逐字节相同,在相交场景里让它们出现 63 个差异像素,并说清差异的来源是质心排序在交叉处判错了局部前后。脚本用「深度 = 绘制序号的相反数」把画家算法搭在共享光栅化器上。
只裁近平面时投影坐标会飞出视口 64 倍,整数包围盒加剪刀矩形把扫描窗口压回视口且逐字节不改像素;保护带 G=0 就能让 80.7% 的三角形免裁,G=256 提到 93.4%。本节实测原始包围盒 4922869 单元、夹紧后 244708、扫描 223753 单元覆盖 43730 像素。
近平面裁剪会把三角形裁成四边形甚至五边形,重建它靠的是扇形三角化的整数恒等式:三个扇形三角形的面积和精确等于多边形面积,逆序则精确变号。本节实测英雄三角形 3→4→5 的逐步计数、面积比恰为 t^2 = 1/4 的解析解,以及「丢弃 vs 裁剪」两帧覆盖异或为 0 而颜色差 171。
视锥六个面在视图空间解析写成四条整数系数,与投影矩阵同源;Sutherland–Hodgman 的交点用 fdiv 定标、算术右移降精度,于是面积守恒成为精确整数恒等式。本节实测六平面系数、487 个顶点的分类、英雄三角形 3 裁成 5 的逐步计数,以及裁剪前后两帧覆盖异或为 0。
两个几乎重合的面若在深度缓冲里落进同一格,深度测试就分不出前后,像素随视角抖动——这就是深度冲突。本节用两块相距 13/65536 的平行墙,把朴素线性 z、标准透视 z、逆转 z 三种映射的冲突像素数摆在一起,解释逆转 z 为何要把深度测试从 < 翻成 >,并如实说明定点缓冲与浮点缓冲下它的差别。
线宽不能用开方算距离:把 d <= r 两边平方,得到一条纯整数的覆盖判据 cross^2 <= r^2*|AB|^2,端帽用最近端点的距离平方兜底。本节实测五个线宽的覆盖数、水平与竖直的对称性,并用 N x N 子样本把覆盖率收敛到解析面积 194514 千分像素^2。
半像素误差界可以写成一条不含除法的整数判据:2*|k*major - i*minor| <= major。本节在 89439 个采样点上穷举验证:Bresenham 与半像素 DDA 的实测 max|e| 恰好是 0.5 像素,floor 取整的 DDA 有 1922 组越界;界在 651 组上被恰好达到,说明它已不能再收紧。
《计算机图形学》卷一附录 A:scene_spec.json 的 71 个字段全表(相机、方向光、点光源、地形、球体、渲染参数,全部为整数)、Q16.16 与 Q6 子像素的定点约定、四条舍入铁律、定点不变量清单、两条一致性纪律的判据表,以及全书数据集索引与一个可跑的定点约定自检脚本。
开曲面没有厚度:从背面看,一块 4x4 的布帘 32 个三角形全是背面,单面渲染得到一张空图。双面材质的做法不是不剔除,而是把背面三角形的几何法线取反再着色;本节实测单趟与两遍渲染逐字节相同,并给出「忘了取反」的指纹——背面图像恰好是正面图像的左右镜像。
背面剔除的判定只是一次整数符号比较,可它省下的到底是什么?本节把代价拆成像素测试数与覆盖像素数两笔,实测 896 个三角形下测试数从 161448 降到 140493(省 129‰),覆盖集合分毫不变,而地形这类开曲面在掠射处仍有 2477 个像素会因剔除而换色。
屏幕空间边函数 E(A,B,C) 的符号就是三角形的朝向。本节在《烛影山谷》的 896 个三角形上实测 606 正面、290 背面、0 退化,与光栅化器剔除的 290 完全一致;再证明世界空间几何法线与视线方向的点积是同一条判据,并用 det<0 的镜像矩阵说明手性反转时法线必须跟着翻。
直线的光栅化先要把方向折进一个八分圆,再决定每一步的取整语义:floor 会系统性偏下并漏掉终点,半像素偏置才落到最近像素。本节用定点 DDA 与整数 Bresenham 扫过 2079 组斜率,量出两者的分歧只出现在平局且步长无截断的 129 组,并用覆盖掩码的 sha256 把 Python 与 TypeScript 逐字节对齐。
多个三角形覆盖同一个像素时,谁的颜色留下由深度测试决定。本节把 6.2 插出的深度送进 z-buffer,说清严格 `<` 与 `<=` 的差别:前者让共享边像素的归属由绘制顺序决定——这不是「与顺序无关」,只是把赢家换成先画的那个;再用一份 64×48 场景让 WebGL2 与 CPU 定点内核对照,并给出必被拒绝的负例。
把 6.1 的三条边函数归一化就得到重心坐标:权重 w0/w1/w2 是像素对三个顶点的贡献比例。本节证明不变量 w0+w1+w2 恒等于面积(定点残差严格为 0),用权重线性插值颜色与深度,说清分子非负时 Python 的 `//` 与截断除同义,最后让 TypeScript 复现出逐字节相同的像素缓冲。
从整数边函数 E(A,B,P) 的「有向面积 2 倍」含义出发,推出三个边函数同号即在三角形内;实测屏幕空间 y 向下时 area > 0 对应的环绕方向、Q6 子像素精度与像素中心取法,并用子像素扰动实验区分恒等实现,最后看 `>= 0` 如何让共享边像素被重复认领。