01 / 从连续三角形到离散样本
光栅器通常先计算三角形在屏幕上的轴对齐包围盒,再测试盒内各采样点是否落在三条边的同一侧。通过测试的样本产生候选片元。
判断的是采样点,而不是“像素方块与三角形是否相交”。单点采样会让边界呈阶梯状,多重采样则能估计一个像素被几何覆盖的比例。
02 / 重心坐标连接三个顶点
三角形内任意点都能写成三个顶点的加权和,权重 α、β、γ 之和为 1。点在三角形内部时,三个权重均不小于 0。
P = αA + βB + γC
α + β + γ = 1
α + β + γ = 1
同一组权重可插值颜色、深度、法线和纹理坐标。靠近某个顶点时,该顶点权重更大,因此属性自然平滑过渡。
法线插值后要重新归一化。多个单位向量的线性组合通常不再是单位长度,直接参与光照会让亮度产生偏差。
03 / 纹理坐标需要透视校正
直接在屏幕空间线性插值纹理坐标,会把倾斜表面当成与屏幕平行,导致纹理像在表面上滑动。正确方法是结合各顶点裁剪坐标的 w 插值。
u = (Σ λᵢ · uᵢ / wᵢ) / (Σ λᵢ / wᵢ)
这就是透视校正插值。现代 GPU 默认对大多数顶点输出执行它;只有明确标记为不插值或屏幕线性时,行为才会改变。
| 插值模式 | 效果 | 用途 |
|---|---|---|
| 透视校正 | 符合三维投影 | 纹理坐标、世界位置 |
| 屏幕线性 | 屏幕上等速变化 | 部分屏幕空间效果 |
| 不插值 | 整图元取同一值 | 材质编号、离散标记 |
04 / 深度测试解决谁挡住谁
每个候选片元带有深度值。典型深度缓冲保存当前最靠近相机的样本,新片元只有通过比较才更新颜色与深度。
传统深度:newDepth < storedDepth → 通过
反向 Z:newDepth > storedDepth → 通过
反向 Z:newDepth > storedDepth → 通过
深度分布在透视投影后不是线性的,精度大量集中在近裁剪面附近。合理推远近裁剪面、使用浮点深度和反向 Z,都可减少远距离 Z-fighting。
背面剔除
投影后三个顶点的顺时针或逆时针顺序代表正反面。对封闭物体剔除背面能减少不可能可见的片元,但镜像变换可能翻转绕序。
05 / 共享边必须只归属一个三角形
相邻三角形共用一条边。若两边都不包含边界,会出现缝隙;若两边都包含,又可能重复覆盖。硬件采用一致的边界规则(常称 top-left rule),让共享边恰好归属其中一个三角形。
- 退化三角形面积为 0,不产生有效覆盖。
- 超小三角形可能没有覆盖任何采样点,因此完全消失。
- 浮点误差与不一致顶点位置会产生真正的几何裂缝。
光栅化的核心不是“给三角形填色”:它是在离散采样网格上估计连续几何的覆盖和属性。