在光栅化三角形时,我们常使用重心坐标来判断点是否在三角形内、插值法线、插值纹理坐标,然而在光栅化三角形时计算出来的是在屏幕坐标下的重心坐标,而在运用透视投影时实际需要的应该是在观察坐标下的重心坐标,虽然不进行矫正在某种情况下看不出差别。本文将基于Games101所给的的投影矩阵进行矫正公式的推导。
首先,透视投影矩阵 \(M_{perspective}\) 如下:
根据正交投影的性质,可知正交投影并不会改变 \(x、y、z\) 的值,实际改变 \(x、y、z\) 的是矩阵M,其中:
并且对于齐次坐标下的点P=\((x, y, z, 1)^T\),经透视投影后有\(P^{'}\):
可以看出,经透视变换后 \(x->\frac{nx}{z}\)...。
假设观察坐标下有 点 \(P,A,B,C\) ,其在屏幕坐标下为别为 \(P^{'},A^{'},B^{'},C^{'}\) 且 \(A,B,C\) 构成 三角形,\(P\) 在三角形\(ABC\)内。
根据重心坐标定义有:
同时,有 \(P^{'}=\frac{1}{P.z}M\times P\) , \(A^{'}=\frac{1}{A.z}M\times A\), \(B^{'}=\frac{1}{B.z}M\times B\), \(C^{'}=\frac{1}{C.z}M\times C\) ,带入上式中有:
很容易得到以下式子:
进一步,由于\(P.z,A.z,B.z,C.z\) 为标量,从而有:
而这正是P的重心坐标形式。但是,我们根本不知道\(P\)的任何信息。
所幸,我们知道,重心坐标实际上就是 \(A,B,C\)的凸组合,有\(\alpha+\beta+\gamma=1\) ,因此,有:
从而很轻易得到 \(\frac{1}{P.z}\)。
最终得到观察坐标下的重心坐标 \(\alpha,\beta,\gamma\) 分别为:
并且,观察坐标下的 \(z\) 就等于经透视变换后的 \(w\) 分量。