一、概述
光栅化过程中的透视投影变换(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

最低0.47元/天 解锁文章
3771

被折叠的 条评论
为什么被折叠?



