一、概述
光栅化过程中的透视投影变换(perspective transformation) 保持变换前后的直线仍然为直线、平面仍然为平面。但是在屏幕空间直接对顶点属性(如颜色、纹理坐标等)进行插值将会得到错误的结果。
为了简化说明错误的原因,现在以二维空间的直线投影到一维直线为例,同样的原理可以应用到将三维空间中的图元投影到二维屏幕坐标空间时。如下图1所示,二维空间中的线段AB的端点A和B投影至一维直线的a和b。A和B的属性值为0和1,因此投影点a和b的强度值为0和1。设c为线段ab的中点,如果在投影平面进行插值,那么c的属性值应为0.5。但是如果将c进行逆投影变换至线段AB上的C,可以看到C并不一定是线段AB的中点。
图1 透视投影
本文接下来列举两种方法进行透视投影校正插值。
二、方法一:插值Z值
顶点的Z值可以看作是顶点的一种属性,在三维空间中随顶点线性变换。
如下图2所示,假设进行投影变换时相机位于原点且看向坐标轴Z的正向,投影平面距离相机的距离为d。A和B的Z值分别为Z1和Z2,世界坐标空间中的插值参数为t。a和b为A和B在屏幕空间中的投影点,屏幕空间中的插值参数为s。
图2
根据相似三角形,可以得到:
X
1
Z
1
=
u
1
d
⇒
X
1
=
u
1
Z
1
d
(1)
\frac{X_1}{Z_1} = \frac{u_1}{d} \Rightarrow X_1 = \frac{u_1 Z_1}{d}\tag{1}
Z1X1=du1⇒X1=du1Z1(1)
X 2 Z 2 = u 2 d ⇒ X 2 = u 2 Z 2 d (2) \frac{X_2}{Z_2} = \frac{u_2}{d} \Rightarrow X_2 = \frac{u_2 Z_2}{d} \tag{2} Z2X2=du2⇒X2=du2Z2(2)
X t Z t = u s d ⇒ Z t = d X t u s (3) \frac{X_t}{Z_t} = \frac{u_s}{d} \Rightarrow Z_t = \frac{d X_t}{u_s} \tag{3} ZtXt=dus⇒Zt=usdXt(3)
在屏幕空间插值u值可以得到:
u
s
=
u
1
+
s
(
u
2
−
u
1
)
(4)
u_s = u_1 + s(u_2 - u_1) \tag{4}
us=u1+s(u2−u1)(4)
在世界坐标系插值X值和Z值得到:
X
t
=
X
1
+
t
(
X
2
−
X
1
)
(5)
X_t = X_1+t (X_2 - X_1) \tag{5}
Xt=X1+t(X2−X1)(5)
Z t = Z 1 + t ( Z 2 − Z 1 ) (6) Z_t = Z_1+t (Z_2 - Z_1) \tag{6} Zt=Z1+t(Z2−Z1)(6)
将(4)、(5)和(6)代入(3)可得:
Z
1
+
t
(
Z
2
−
Z
1
)
=
d
(
X
1
+
t
(
X
2
−
X
1
)
)
u
1
+
s
(
u
2
−
u
1
)
(7)
Z_1+t (Z_2 - Z_1) = \frac{d(X_1+t (X_2 - X_1))}{u_1 + s(u_2 - u_1) } \tag{7}
Z1+t(Z2−Z1)=u1+s(u2−u1)d(X1+t(X2−X1))(7)
将(1)和(2)代入(7)可得:
Z
1
+
t
(
Z
2
−
Z
1
)
=
d
(
u
1
Z
1
d
+
t
(
u
2
Z
2
d
−
u
1
Z
1
d
)
)
u
1
+
s
(
u
2
−
u
1
)
Z
1
+
t
(
Z
2
−
Z
1
)
=
u
1
Z
1
+
t
(
u
2
Z
2
−
u
1
Z
1
)
u
1
+
s
(
u
2
−
u
1
)
(8)
Z_1+t (Z_2 - Z_1) = \frac{d \left( \frac{u_1 Z_1}{d} + t \left( \frac{u_2 Z_2}{d} - \frac{u_1 Z_1}{d} \right) \right)}{u_1 + s(u_2 - u_1)} \\ \hphantom{Z_1+t (Z_2 - Z_1)} = \frac{u_1 Z_1 + t(u_2 Z_2 - u_1 Z_1)}{u_1 + s(u_2 - u_1)} \tag{8}
Z1+t(Z2−Z1)=u1+s(u2−u1)d(du1Z1+t(du2Z2−du1Z1))Z1+t(Z2−Z1)=u1+s(u2−u1)u1Z1+t(u2Z2−u1Z1)(8)
整理(8)可得:
t
=
s
Z
1
s
Z
1
+
(
1
−
s
)
Z
2
(9)
t = \frac{s Z_1}{s Z_1 + (1-s) Z_2 } \tag{9}
t=sZ1+(1−s)Z2sZ1(9)
将(9)代入(6)可得:
Z
t
=
Z
1
+
s
Z
1
s
Z
1
+
(
1
−
s
)
Z
2
(
Z
2
−
Z
1
)
(10)
Z_t = Z_1+\frac{s Z_1}{s Z_1 + (1-s) Z_2 } (Z_2 - Z_1) \tag{10}
Zt=Z1+sZ1+(1−s)Z2sZ1(Z2−Z1)(10)
整理(10)可得:
Z
t
=
1
1
Z
1
+
s
(
1
Z
2
−
1
Z
1
)
(11)
Z_t = \frac{1}{\frac{1}{Z_1} + s(\frac{1}{Z_2} - \frac{1}{Z_1}) } \tag{11}
Zt=Z11+s(Z21−Z11)1(11)
从(11)可得出,为了得到屏幕空间的c点处的Z值,可以通过使用屏幕空间的插值参数s对 1 Z 1 \frac{1}{Z_1} Z11和 1 Z 2 \frac{1}{Z_2} Z21进行插值,然后再取倒数。
对于将世界坐标系投影至二维屏幕空间的情形,假设在屏幕空间计算得到的重心坐标为
α
′
、
β
′
和
γ
′
\alpha' 、\beta' 和\gamma'
α′、β′和γ′,由(11)类推可得插值的Z值为:
Z
t
=
1
α
′
Z
1
+
β
′
Z
2
+
γ
′
Z
3
(12)
Z_t = \frac{1}{\frac{\alpha'}{Z_1} + \frac{\beta'}{Z_2} + \frac{\gamma'}{Z_3}} \tag{12}
Zt=Z1α′+Z2β′+Z3γ′1(12)
三、方法一:插值其它属性值
以上图2所示,A和B的属性值为I1和I2,在世界坐标对I值进行插值,可得:
I
t
=
I
1
+
t
(
I
2
−
I
1
)
(13)
I_t = I_1+t (I_2 - I_1) \tag{13}
It=I1+t(I2−I1)(13)
将(9)代入(13)可得:
I
t
=
I
1
+
s
Z
1
s
Z
1
+
(
1
−
s
)
Z
2
(
I
2
−
I
1
)
I
t
=
I
1
Z
2
+
s
(
I
2
Z
1
−
I
1
Z
2
)
Z
2
+
s
(
Z
1
−
Z
2
)
I
t
=
I
1
Z
2
+
s
(
I
2
Z
1
−
I
1
Z
2
)
Z
1
Z
2
Z
2
+
s
(
Z
1
−
Z
2
)
Z
1
Z
2
I
t
=
I
1
Z
1
+
s
(
I
2
Z
2
−
I
1
Z
1
)
1
Z
1
+
s
(
1
Z
2
−
1
Z
1
)
(14)
I_t = I_1+\frac{s Z_1}{s Z_1 + (1-s) Z_2 } (I_2 - I_1) \\ \hphantom{I_t} = \frac{I_1 Z_2 + s(I_2 Z_1 - I_1 Z_2)}{Z_2 + s(Z_1 - Z_2)} \\ \hphantom{I_t} = \frac{\frac{I_1 Z_2 + s(I_2 Z_1 - I_1 Z_2)}{Z_1 Z_2}}{\frac{Z_2 + s(Z_1 - Z_2)}{Z_1 Z_2}} \\ \hphantom{I_t} = \frac{\frac{I_1}{Z_1} + s(\frac{I_2}{Z_2} - \frac{I_1}{Z_1})}{\frac{1}{Z_1} + s(\frac{1}{Z_2} - \frac{1}{Z_1})} \tag{14}
It=I1+sZ1+(1−s)Z2sZ1(I2−I1)It=Z2+s(Z1−Z2)I1Z2+s(I2Z1−I1Z2)It=Z1Z2Z2+s(Z1−Z2)Z1Z2I1Z2+s(I2Z1−I1Z2)It=Z11+s(Z21−Z11)Z1I1+s(Z2I2−Z1I1)(14)
可以看出(14)的分母即为
1
Z
t
\frac{1}{Z_t}
Zt1,即:
I
t
=
I
1
Z
1
+
s
(
I
2
Z
2
−
I
1
Z
1
)
1
Z
t
(15)
I_t = \frac{\frac{I_1}{Z_1} + s(\frac{I_2}{Z_2} - \frac{I_1}{Z_1})}{\frac{1}{Z_t}} \tag{15}
It=Zt1Z1I1+s(Z2I2−Z1I1)(15)
(15)表示屏幕空间中的c点的属性可以通过两步完成:
第一步,先在屏幕空间对
I
1
Z
1
\frac{I_1}{Z_1}
Z1I1和
I
2
Z
2
\frac{I_2}{Z_2}
Z2I2进行插值;
第二步,将第一步的值除以
1
Z
t
\frac{1}{Z_t}
Zt1,而Zt的值可以通过在屏幕空间对
1
Z
1
\frac{1}{Z_1}
Z11和
1
Z
2
\frac{1}{Z_2}
Z21进行插值得到。
四、方法二
如下图3所示,相机位于原点,P点为世界坐标系中的三角形ABC内的一点,P’为透视投影后的三角形A‘B’C‘内对应的点。
图3
点A、B、C和P的齐次坐标经过变换矩阵M后为A’、B’、C’和P’:
(
A
′
w
a
w
a
)
=
M
(
A
1
)
(16)
\begin{pmatrix} A' w_a \\ w_a \end{pmatrix} = \mathbf{M} \begin{pmatrix} A \\ 1 \end{pmatrix} \tag{16}
(A′wawa)=M(A1)(16)
( B ′ w b w b ) = M ( B 1 ) (17) \begin{pmatrix} B' w_b \\ w_b \end{pmatrix} = \mathbf{M} \begin{pmatrix} B \\ 1 \end{pmatrix}\tag{17} (B′wbwb)=M(B1)(17)
( C ′ w c w c ) = M ( C 1 ) (18) \begin{pmatrix} C' w_c \\ w_c \end{pmatrix} = \mathbf{M} \begin{pmatrix} C \\ 1 \end{pmatrix}\tag{18} (C′wcwc)=M(C1)(18)
( P ′ w p w p ) = M ( P 1 ) (19) \begin{pmatrix} P' w_p \\ w_p \end{pmatrix} = \mathbf{M} \begin{pmatrix} P \\ 1 \end{pmatrix}\tag{19} (P′wpwp)=M(P1)(19)
世界坐标系中P点的重心坐标为
α
\alpha
α、
β
\beta
β、
γ
\gamma
γ,屏幕坐标系中的P’点的重心坐标为
α
′
\alpha'
α′、
β
′
\beta'
β′、
γ
′
\gamma'
γ′,
P
=
α
A
+
β
B
+
γ
C
(20)
P = \alpha A + \beta B + \gamma C \tag{20}
P=αA+βB+γC(20)
P ′ = α ′ A ′ + β ′ B ′ + γ ′ C ′ (21) P' = \alpha' A' + \beta' B' + \gamma' C' \tag{21} P′=α′A′+β′B′+γ′C′(21)
因为
α
+
β
+
γ
=
1
\alpha + \beta + \gamma = 1
α+β+γ=1,因此根据(20)可得:
(
P
1
)
=
α
(
A
1
)
+
β
(
B
1
)
+
γ
(
C
1
)
(22)
\begin{pmatrix} P \\ 1 \end{pmatrix} = \alpha\begin{pmatrix} A \\ 1 \end{pmatrix} + \beta\begin{pmatrix} B \\ 1 \end{pmatrix} + \gamma\begin{pmatrix} C \\ 1 \end{pmatrix} \tag{22}
(P1)=α(A1)+β(B1)+γ(C1)(22)
在(22)两边同乘以M可得:
M
(
P
1
)
=
α
M
(
A
1
)
+
β
M
(
B
1
)
+
γ
M
(
C
1
)
(23)
\mathbf{M} \begin{pmatrix} P \\ 1 \end{pmatrix} = \alpha \mathbf{M} \begin{pmatrix} A \\ 1 \end{pmatrix} + \beta \mathbf{M} \begin{pmatrix} B \\ 1 \end{pmatrix} + \gamma \mathbf{M} \begin{pmatrix} C \\ 1 \end{pmatrix} \tag{23}
M(P1)=αM(A1)+βM(B1)+γM(C1)(23)
将(16)、(17)、(18)、(19)代入(23)可得:
P
′
w
p
=
α
A
′
w
a
+
β
B
′
w
b
+
γ
C
′
w
c
(24)
P' w_p = \alpha A' w_a + \beta B' w_b + \gamma C' w_c \tag{24}
P′wp=αA′wa+βB′wb+γC′wc(24)
w p = α w a + β w b + γ w c (25) w_p = \alpha w_a + \beta w_b + \gamma w_c \tag{25} wp=αwa+βwb+γwc(25)
由(24)和(25)可得:
P
′
=
α
A
′
w
a
+
β
B
′
w
b
+
γ
C
′
w
c
α
w
a
+
β
w
b
+
γ
w
c
(26)
P' = \frac{\alpha A' w_a + \beta B' w_b + \gamma C' w_c}{\alpha w_a + \beta w_b + \gamma w_c} \tag{26}
P′=αwa+βwb+γwcαA′wa+βB′wb+γC′wc(26)
由(21)和(26)可得:
α
′
=
α
w
a
α
w
a
+
β
w
b
+
γ
w
c
β
′
=
β
w
b
α
w
a
+
β
w
b
+
γ
w
c
γ
′
=
γ
w
c
α
w
a
+
β
w
b
+
γ
w
c
(27)
\alpha' = \frac{\alpha w_a}{\alpha w_a + \beta w_b + \gamma w_c} \\ \beta' = \frac{\beta w_b}{\alpha w_a + \beta w_b + \gamma w_c} \\ \gamma' = \frac{\gamma w_c}{\alpha w_a + \beta w_b + \gamma w_c} \tag{27}
α′=αwa+βwb+γwcαwaβ′=αwa+βwb+γwcβwbγ′=αwa+βwb+γwcγwc(27)
现在我们得到了
α
′
\alpha'
α′、
β
′
\beta'
β′、
γ
′
\gamma'
γ′,但是我们需要的是
α
\alpha
α、
β
\beta
β、
γ
\gamma
γ,设
k
=
1
α
w
a
+
β
w
b
+
γ
w
c
(28)
k = \frac{1}{\alpha w_a + \beta w_b + \gamma w_c} \tag{28}
k=αwa+βwb+γwc1(28)
由(27)可得到
α
′
=
α
w
a
k
β
′
=
β
w
b
k
γ
′
=
γ
w
c
k
(29)
\alpha' = \alpha w_a k \\ \beta' = \beta w_b k \\ \gamma' = \gamma w_c k \tag{29}
α′=αwakβ′=βwbkγ′=γwck(29)
因为
α
+
β
+
γ
=
1
\alpha + \beta + \gamma = 1
α+β+γ=1,由(29)得:
1
=
α
+
β
+
γ
=
α
′
w
a
k
+
β
′
w
b
k
+
γ
′
w
c
k
(30)
1 = \alpha + \beta + \gamma = \frac{\alpha'}{w_a k} + \frac{\beta '}{w_b k} + \frac{\gamma '}{w_c k} \tag{30}
1=α+β+γ=wakα′+wbkβ′+wckγ′(30)
由(30)可得:
k
=
α
′
w
a
+
β
′
w
b
+
γ
′
w
c
(31)
k = \frac{\alpha'}{w_a} + \frac{\beta '}{w_b} + \frac{\gamma '}{w_c} \tag{31}
k=waα′+wbβ′+wcγ′(31)
将(31)代入(29)可得:
α
=
α
′
w
a
α
′
w
a
+
β
′
w
b
+
γ
′
w
c
β
=
β
′
w
b
α
′
w
a
+
β
′
w
b
+
γ
′
w
c
γ
=
γ
′
w
c
α
′
w
a
+
β
′
w
b
+
γ
′
w
c
(32)
\alpha = \frac{\frac{\alpha'}{w_a}}{\frac{\alpha'}{w_a} + \frac{\beta '}{w_b} + \frac{\gamma '}{w_c}} \\ \beta = \frac{\frac{\beta'}{w_b}}{\frac{\alpha'}{w_a} + \frac{\beta '}{w_b} + \frac{\gamma '}{w_c}} \\ \gamma = \frac{\frac{\gamma'}{w_c}}{\frac{\alpha'}{w_a} + \frac{\beta '}{w_b} + \frac{\gamma '}{w_c}} \tag{32}
α=waα′+wbβ′+wcγ′waα′β=waα′+wbβ′+wcγ′wbβ′γ=waα′+wbβ′+wcγ′wcγ′(32)
由(32)得到的 α 、 β 、 γ \alpha 、\beta 、\gamma α、β、γ即为世界坐标系空间中的重心坐标。
现在以方法二进行Z值的插值,假设屏幕坐标空间中的重心坐标为
α
′
\alpha'
α′、
β
′
\beta'
β′、
γ
′
\gamma'
γ′,由(32)可得
Z
t
=
α
′
Z
1
w
a
+
β
′
Z
2
w
b
+
γ
′
Z
3
w
c
α
′
w
a
+
β
′
w
b
+
γ
′
w
c
(33)
Z_t = \frac{\frac{\alpha' Z_1}{w_a} + \frac{\beta' Z_2}{w_b} + \frac{\gamma' Z_3}{w_c}}{\frac{\alpha'}{w_a} + \frac{\beta '}{w_b} + \frac{\gamma '}{w_c}} \tag{33}
Zt=waα′+wbβ′+wcγ′waα′Z1+wbβ′Z2+wcγ′Z3(33)
五、对比两种方法
对比两种方法得到的插值坐标,即(12)和(33),我们会发现它们得到的结果是相等的,我们对这一点不应该感到惊奇,现在证明这一点。
(12)和(33)如下
Z
t
=
1
α
′
Z
1
+
β
′
Z
2
+
γ
′
Z
3
(12)
Z_t = \frac{1}{\frac{\alpha'}{Z_1} + \frac{\beta'}{Z_2} + \frac{\gamma'}{Z_3}} \tag{12}
Zt=Z1α′+Z2β′+Z3γ′1(12)
Z
t
=
α
′
Z
1
w
a
+
β
′
Z
2
w
b
+
γ
′
Z
3
w
c
α
′
w
a
+
β
′
w
b
+
γ
′
w
c
(33)
Z_t = \frac{\frac{\alpha' Z_1}{w_a} + \frac{\beta' Z_2}{w_b} + \frac{\gamma' Z_3}{w_c}}{\frac{\alpha'}{w_a} + \frac{\beta '}{w_b} + \frac{\gamma '}{w_c}} \tag{33}
Zt=waα′+wbβ′+wcγ′waα′Z1+wbβ′Z2+wcγ′Z3(33)
GAMES101中的透视投影矩阵为:
M
proj
=
[
2
n
r
−
l
0
r
+
l
r
−
l
0
0
2
n
t
−
b
t
+
b
t
−
b
0
0
0
n
+
f
n
−
f
2
f
n
f
−
n
0
0
1
0
]
M_{\text{proj}} = \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{2fn}{f-n} \\ 0 & 0 & 1 & 0 \end{bmatrix}
Mproj=
r−l2n0000t−b2n00r−lr+lt−bt+bn−fn+f100f−n2fn0
假设世界坐标系空间中一点Q(x_q,y_q,z_q,1),Q点经过透视投影矩阵Mproj进行透视投影变换后的坐标为Qm(x_p,y_p,z_p,w_p),其中分量w_p的值即为透视投影变换前的z值,即w_p=z_q。因此在(33)中Z1=w_a,Z2=w_b,Z3=w_c,则(33)等同为:
Z
t
=
1
α
′
Z
1
+
β
′
Z
2
+
γ
′
Z
3
(34)
Z_t = \frac{1}{\frac{\alpha'}{Z_1} + \frac{\beta'}{Z_2} + \frac{\gamma'}{Z_3}} \tag{34}
Zt=Z1α′+Z2β′+Z3γ′1(34)
对比(34)和(12),发现两者完全相同,因此由两种方法得出的插值结果相等。
六、参考资料
1、https://www.cs.ucr.edu/~craigs/courses/2018-fall-cs-130/lectures/perspective-correct-interpolation.pdf
2、https://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf