透视矫正与法线向量变换
三维空间内的模型要最终呈现在屏幕上,必须经过透视投影变换。透视投影让我们看到了”近大远小”的真实世界,但它的代价是故意扭曲了空间的均匀性——透视除法(除以
这种非线性会导致两个在渲染管线中必须解决的问题:
- 屏幕空间插值失真:在屏幕空间直接对深度或纹理坐标做线性插值,得到的不是三维空间中正确线性插值的结果,纹理会出现扭曲。
- 法线向量失效:变换后直接用原变换矩阵作用于法线向量,法线将不再垂直于表面,导致光照计算全部出错。
问题 1 通过透视矫正(Perspective Correction)解决,问题 2 通过法线矩阵(Normal Matrix)解决。下面分别讨论。
透视矫正
问题根源
为了理解为什么需要透视矫正,我们先看透视投影下插值为什么会失真。
在这张图中,我们将 2D 空间内的一条线段
现在取
根源在于:透视投影中的”透视除法”(除以
推导透视矫正公式
既然直接线性插值不对,我们能否找到透视前后两个插值系数之间的映射关系?如果能,就可以在屏幕空间做插值时”纠偏”回来。
如上图,虚拟相机在观察坐标系中沿
我们要找的就是
第一步:建立相似三角形关系。
第二步:写出线性插值定义。
屏幕空间内
观察空间内
第三步:消元求解。
将公式
将公式
将公式
从公式
至此我们得到了
第四步:发现关键不变量。
将公式
对公式
即:
又定义屏幕空间内
比较
结论一:
第五步:推广到任意属性
观察空间中任意属性
将透视映射关系
通分整理:
将公式
即:
又定义屏幕空间内
比较
结论二:
透视矫正的实践流程
综合以上推导,GPU 在光栅化阶段进行透视矫正插值的实际操作流程为:
- 对三角形每个顶点的属性
,计算 和 。 - 在屏幕空间对
和 分别做重心坐标线性插值。 - 对插值出的
取倒数得到该像素的真实深度 。 - 将插值出的
乘以 ,得到该像素的真实属性值 。
这样就在屏幕空间内得到了与观察空间插值完全等价的结果,同时保持了光栅化的高效性。
为什么不在观察空间直接插值? 你可能会问:既然屏幕空间插值会失真,直接在透视之前的观察空间做插值不就行了?答案是不可行,因为光栅化本身就是一个屏幕空间操作。GPU 的固定功能光栅化器在裁剪空间/NDC 中确定三角形覆盖了哪些屏幕像素,生成片元时天然处于屏幕坐标。若想在观察空间插值,就需要对每个像素反算其对应的 3D 观察空间位置——这等价于光线追踪的求交操作,完全背离了光栅化管线以屏幕空间为核心的效率优势。透视矫正正是以最小的数学代价,在屏幕空间内”模拟”出观察空间插值的正确结果。
法线向量变换
透视矫正解决了属性插值的问题。但透视投影的非线性变换还带来了第二个问题:变换后的法线向量不再垂直于表面,而我们做光照计算时严重依赖法线方向。这个问题不仅限于透视投影——任何包含非均匀缩放、剪切或透视的变换都会破坏法线的正交性。
为什么法线在变换后会失效?
法线向量和位置/方向向量是不同类型的几何量。位置向量和切向量可以直接用变换矩阵
以一个简单的二维例子来说明。考虑二维空间中的一条线段,方向向量为
对该平面施加一个非均匀缩放变换矩阵
即将
取线段方向
- 变换后的线段方向:
- 如果直接用
变换法向量: - 验证正交性:
法向量已经不再垂直于变换后的线段了!
而正确的变换后法向量应该是
问题来了:对于任意变换矩阵
答案是肯定的。下面推导这个矩阵
法线矩阵的推导
设原始空间中平面的一条切向量为
经过变换矩阵
代入
将点积写成矩阵乘法形式(将向量视为列向量,对第一个向量取转置):
我们已知
其中
由此:
这就是法线矩阵(Normal Matrix)——变换矩阵
完整的变换规则为:
注意:变换后的法向量
通常不再是单位向量,着色前需要在 Shader 中重新归一化( normalize)。
验证与特例
回到前面的二维例子来验证。非均匀缩放矩阵
原始法向量
下面讨论几种常见的特殊情况:
| 变换类型 | ||
|---|---|---|
| 纯旋转 | ||
| 均匀缩放( |
||
| 非均匀缩放 / 剪切 | 必须计算完整的 |
|
| 平移 | 不影响方向向量 | 取 |
总结
透视投影引入的非线性变换,给渲染管线带来了两个必须应对的挑战:
- 透视矫正:揭示了
和 在透视变换后仍然保持线性这一关键性质,使得 GPU 可以在屏幕空间内高效地完成正确的属性插值,无需回到观察空间重算。 - 法线矩阵:指出了法向量与位置/切向量在变换规则上的本质差异——法线需要用
而非 本身来变换,才能在所有变换下(尤其是非均匀缩放和剪切变换)保持与表面的正交关系,确保光照计算正确。
两者结合,使得光栅化管线在享受透视投影带来的真实感的同时,保持了数学上的正确性和工程上的高效性。
这次的插图来自画师 烏
图片地址:https://www.pixiv.net/artworks/130723113
关于透视矫正的文献地址:https://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf