透视变换中变换后的Z坐标和变换前Z坐标的关系

建议开始前阅读前文:http://www.songho.ca/opengl/gl_projectionmatrix.html

前言

在GAMES101的第四课中,闫令琪老师推导了由透视坐标(Perspective Projection)变换为正射坐标(Orthographic Projection Matrix)的矩阵。

在课后,闫老师留下了一个问题:对于 nn 到 ff 的范围内的 zz,在经过变换后,中间的 zz 会变大,变小还是不变?

OpenGL 中的透视投影

在OpenGL中,我们将一个右手系的透视区域

投影为一个棱长为2,中心为左手系原点的正方体正射投影区域的矩阵如下

问题转化

在这个模型中,闫老师的问题可以转化为,

对变化前的 zz,∃k\exists k,使得(−n)×k+(−f)×(1−k)=z(-n) \times k + (-f) \times (1-k) = z

对变化后的 z′z',∃m\exists m,使得(−1)×m+1×(1−m)=z′(-1) \times m + 1 \times (1-m) = z'

求 kk 和 mm 的大小关系。

实际上,用更通俗的语言说,就是求变换前和变换后的 zz 在前后两个平面的 zz 坐标中的插值大小。

任取一个 k∈(0,1)k \in (0, 1),则 z=−kn−f(1−k)=k(f−n)−fz=-kn-f(1-k) = k(f - n) - f(即 kk 越大,zz 越靠近 −n-n)。

根据变换矩阵,我们可以求得点 (0,0,z,1)(0, 0, z, 1) 变换后的坐标为 (0,0,−(f+n)f−n×z+−2fnf−n,−z)(0, 0, \frac{-(f+n)}{f-n} \times z +\frac{-2fn}{f-n}, -z)

因此,

z′=f+nf−n+2fnz(f−n)=f+nf−n+2fn(k(f−n)−f)(f−n)z' = \frac{f+n}{f-n} + \frac{2fn}{z(f-n)} = \frac{f+n}{f-n} + \frac{2fn}{(k(f-n)-f)(f-n)}

同样的插值在 (−1,1)(-1, 1) 中的结果为 1−2k1-2k。

令函数 F(k)=[f+nf−n+2fn(k(f−n)−f)(f−n)]−(1−2k)F(k) = [\frac{f+n}{f-n} + \frac{2fn}{(k(f-n)-f)(f-n)}] - (1 - 2k)

我们只需要讨论它在 k∈(0,1)k \in (0, 1) 上的符号即可判断 zz 的变换情况。如果F(k)>0F(k) > 0,说明 zz 在被变换后插值更大,更接近 −n-n 一侧,反之则更接近 −f-f 一侧。

因为

F′(k)=2−2fn(k(f−n)−f)2F'(k) = 2 - \frac{2 f n}{(k(f-n) - f)^2}

F′′(k)=4fn(k(f−n)−f)3<0,k∈(0,1)F''(k) = \frac{4fn}{(k(f-n)-f)^3} < 0, k \in (0, 1)

而

F′(0)=2−2nf>0F'(0) = 2 - \frac{2n}{f} > 0

F′(1)=2−2fn<0F'(1) = 2 - \frac{2f}{n} < 0

因此, F(k)F(k) 在 (0,1)(0, 1) 上先单调递增,再单调递减。而 F(0)=F(1)=0F(0) = F(1) = 0,因此,∀k∈(0,1)\forall k \in (0, 1),F(k)>0F(k) > 0。

所以,对任意的变换后的 zz,比起变换前的 zz 来说,要更接近 nn 平面的一侧。