【Games101】如何将屏幕坐标的重心坐标矫正至观察空间-公式推导

📅 2026/7/6 23:51:10 👁️ 阅读次数 📝 编程学习
【Games101】如何将屏幕坐标的重心坐标矫正至观察空间-公式推导

在光栅化三角形时,我们常使用重心坐标来判断点是否在三角形内、插值法线、插值纹理坐标,然而在光栅化三角形时计算出来的是在屏幕坐标下的重心坐标,而在运用透视投影时实际需要的应该是在观察坐标下的重心坐标,虽然不进行矫正在某种情况下看不出差别。本文将基于Games101所给的的投影矩阵进行矫正公式的推导。
首先,透视投影矩阵 \(M_{perspective}\) 如下:

\[M_{perspective}= M_{正交} \times \begin{bmatrix}n & 0 & 0 & 0\\0 & n & 0 & 0\\0 & 0 & n+f & -n \times f \\ 0 & 0 & 1 & 0 \end{bmatrix} = \begin{bmatrix}\frac{2n}{r-l} & 0 & -\frac{r+l}{r-l} & 0\\0 & \frac{2n}{t-b} & -\frac{t+b}{t-b} & 0\\0 & 0 & \frac{n+f}{n-f} & \frac{-2nf}{n-f} \\ 0 & 0 & 1 & 0 \end{bmatrix}\]

根据正交投影的性质,可知正交投影并不会改变 \(x、y、z\) 的值,实际改变 \(x、y、z\) 的是矩阵M,其中:

\[M=\begin{bmatrix} n & 0 & 0 & 0\\0 & n & 0 & 0\\0 & 0 & n+f & -n \times f \\ 0 & 0 & 1 & 0 \end{bmatrix}\]

并且对于齐次坐标下的点P=\((x, y, z, 1)^T\),经透视投影后有\(P^{'}\)

\[M\times P=\begin{bmatrix} nx \\ ny \\ z(n+f)-nf \\ z \end{bmatrix}=z\times \begin{bmatrix} \frac{nx}{z} \\ \frac{ny}{z} \\ \frac{z(n+f)-nf}{z} \\ 1 \end{bmatrix}=z\times P^{'}\]

可以看出,经透视变换后 \(x->\frac{nx}{z}\)...。

假设观察坐标下有 点 \(P,A,B,C\) ,其在屏幕坐标下为别为 \(P^{'},A^{'},B^{'},C^{'}\)\(A,B,C\) 构成 三角形,\(P\) 在三角形\(ABC\)内。
根据重心坐标定义有:

\[P^{'}=\begin{bmatrix} A{'} \ \ \ B^{'} \ \ \ C^{'} \end{bmatrix} \times \begin{bmatrix} \alpha^{'} \\ \beta^{'} \\ \gamma^{'} \end{bmatrix} \]

同时,有 \(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\) ,带入上式中有:

\[\frac{1}{P.z}M\times P = \begin{bmatrix} \frac{1}{A.z}M\times A \ \ \ \ \frac{1}{B.z}M\times B \ \ \ \ \frac{1}{C.z}M\times C \end{bmatrix} \times \begin{bmatrix} \alpha^{'} \\ \beta^{'} \\ \gamma^{'} \end{bmatrix} \]

很容易得到以下式子:

\[\frac{1}{P.z}\times P = \begin{bmatrix} \frac{1}{A.z}\times A \ \ \ \ \frac{1}{B.z}\times B \ \ \ \ \frac{1}{C.z}\times C \end{bmatrix} \times \begin{bmatrix} \alpha^{'} \\ \beta^{'} \\ \gamma^{'} \end{bmatrix} \]

进一步,由于\(P.z,A.z,B.z,C.z\) 为标量,从而有:

\[ P = \begin{bmatrix}A \ \ \ \ B \ \ \ \ C \end{bmatrix} \times \begin{bmatrix} \frac{\alpha^{'}}{A.z}\\ \frac{\beta^{'}}{B.z} \\ \frac{\gamma^{'} }{C.z} \end{bmatrix} \times \frac{1}{P.z} \]

而这正是P的重心坐标形式。但是,我们根本不知道\(P\)的任何信息。
所幸,我们知道,重心坐标实际上就是 \(A,B,C\)的凸组合,有\(\alpha+\beta+\gamma=1\) ,因此,有:

\[(\frac{\alpha^{'}}{A.z}+\frac{\beta^{'}}{B.z} +\frac{\gamma^{'} }{C.z})\times \frac{1}{P.z}=1 \]

从而很轻易得到 \(\frac{1}{P.z}\)
最终得到观察坐标下的重心坐标 \(\alpha,\beta,\gamma\) 分别为:

\[\alpha=\frac{\alpha^{'}}{A.z}/(\frac{\alpha^{'}}{A.z}+\frac{\beta^{'}}{B.z} +\frac{\gamma^{'} }{C.z}) \]

\[\beta=\frac{\beta^{'}}{A.z}/(\frac{\alpha^{'}}{A.z}+\frac{\beta^{'}}{B.z} +\frac{\gamma^{'} }{C.z}) \]

\[\gamma=\frac{\gamma^{'}}{A.z}/(\frac{\alpha^{'}}{A.z}+\frac{\beta^{'}}{B.z} +\frac{\gamma^{'} }{C.z}) \]

并且,观察坐标下的 \(z\) 就等于经透视变换后的 \(w\) 分量。