Processing math: 100%

透视投影

[53:10]

透视投影的主要过程

透视投影的过程是先将Frustum(截锥体)转换为Cuboid(长方体),然后再用上面的方法对长方体做正交投影:

💡 我的理解

  1. 在Frustum(截锥体)-> Cuboid(长方体)之前应该有一步平移的过程,让Frustum的中心轴与z轴重合。类似于正交投影中的第一步。因此真正的过程应该是这样的:
    平移(正交投影的第一步) ===> Frustum(截锥体)-> Cuboid(长方体) ===> 缩放(正交投影的第二步)
  2. 课程中用挤压来解决“Frustum(截锥体)-> Cuboid(长方体)”的过程,方便理解的同时却也引入的歧义。因为这里的Frustum是视锥体,跟几何锥体还是有区别的。这也是为什么挤压之后z会变。

要把Frustum转换为Cubuid是仿射变换的过程,主要方法仍是求出仿射变换的矩阵。

在正交投影中,是根据正交变换的过程,将仿射变换矩阵分解为S, R, T三个部分,依次计算出S, R, T再将它们合并。

在透视投影中,仍然不涉及旋转,但是平移和缩放的过程是揉合在一起的,难以拆分,因此采用选取特殊点的方式,直接求出投视投影的变换矩阵。

Mpersportho

侧面分析

从侧面看,存在相似三角形(图中很容易看出)

通过相似三角形,可以得到:

y=nzyx=nzx

💡 这个公式成立的前提是frustum的中心轴与z轴重合,这也印证了前面提到的“frustum->cuboid之前应该先平移”。

我们的目的是将 (x,y,z) 转换为 (x,y,z)

现在可以得到:

(xyz1)(nx/zny/zunknown1)

为坐标乘以 z,得:

(xyz1)(nx/zny/zunknown1)==(nxnystill,,unknownz)

想要将 (xyz1) 投影为 (nxnyunknownz),需要求一个投影矩阵:

M(4×4)persportho(xyz1)=(nxnyunknownz)

我们已经知道一些数据了,所以能求出M的一些值(显然,由上式可得):

M(4×4)persportho=(n0000n00????0010)

n面分析和f面分析

M已经被解决不少了,但还差一些,不过,我们还有一些坐标点不变的性质可以使用:

  • Frustum的n(近处)面,所有坐标是不变化的。

  • f面的Z轴坐标值,是不变化的;

  • Z轴穿过的中心点的坐标值,是不变化的。

n面,所有坐标点不变,那么取一个n面上随便一点,该点的Z轴坐标值为n,即:

(xyn1)

为坐标乘以n:

(nxnyn2n)

既然这一点在投影前后不会变化,我们可以列出下面的式子:

(nxnyn2n)=(n0000n00????0010)(xyn1)

上式其实只剩下下面这个式子要求:

n2=(?,?,?,?)(xyn1)

具体来说,是这样的:

n2=(0,0,A,B)(xyn1)

于是可以得到:

An+B=n2

同理,在f面上,变换后点(0,0,f)不变,可以得到:

Af+B=f2

联立上述AB方程,解得:

A=n+fB=nf

所以我们推导出了透视投影的一个变换矩阵:

M(4×4)persportho=(n0000n0000n+fnf0010)

透视投影矩阵

透视投影的最终的变换矩阵是 M = M(正交)M(透视)

为什么透视投影会z会后移

从数学上

定义z'为变换后的z坐标,那么z' = (n+f)-nf/z

f=zz=(n+f)nf/zz

zf=z2+(n+f)znf

zf是一个开口向下的二次曲线。它与x轴的交点在z=n处和z=f处。当z位于(f, n)区间时,zf>0。

由于f<0且n<0,当z位于(f, n)区间时,z<0,因此f<0,即z'-z<0

z'<z,因此z会变远。

从直觉上

一开始会觉得有点奇怪,违反直觉。细想之后觉得是很合理。
因为透视投影要表现出近大远小的效果。近大不止是x轴和y轴的大,z轴上也会大。即同一个物体,如果放得近,它在z轴上会更大点。
空间上也是如此,透视前的空间,把它以z=0分成前后均匀的两半,近的那一半,在透视后必然要占更大的z轴范围,因此z会往后。


本文出自CaterpillarStudyGroup,转载请注明出处。
https://caterpillarstudygroup.github.io/GAMES101_mdbook/