在GAMES101-Lecture4 Transformation Matrices 一节中,闫老师介绍了正交投影和透视投影。
在讲透视投影变换矩阵
M
p
e
r
s
p
→
o
r
t
h
o
M_{persp→ortho}
Mpersp→ortho时,同学们对矩阵中的z分量是变化的还是不变的有很多争论。即下图中z分量经过投影变换后的z'底是保持不变依旧等于z,还是"unknown"大家有不同的看法。基于查阅的资料,我将在本文中谈一下自己对于这个问题的理解,并对投影变换矩阵的计算公式进行解释。

将指定立方体内部的点映射(变换)到正则立方体(canonical cube) 内。正则立方体是一个中心点在原点,(x,y,z)三个分量都在[-1,1]范围内的正方体。
如将下图所示,左侧立方体内部的点,先经过平移(Translate),再经过放缩(Scale)变换后,即可投影到正则立方体内。

正交投影矩阵可以由平移矩阵和放缩矩阵相乘得到:

将视体内部的点映射(变换)到 正则立方体(canonical cube) 内。视体 通常是一个 方平截头体,可由fov, aspect_ratio, zNear和zFar这几个参数确定。
如下图所示:

前面已经简单介绍过 正交投影 了,正交投影 相对简单,只要进行平移+放缩两次变换即可得到。透视投影 相对复杂,
透视投影包含两步:
为什么不直接使用平移+放缩+非仿射变换 求得透视投影矩阵,而是需要先将透视投影转为立方体,再进行一次正交投影这两步(这两步称之为透视规范化)?
这是因为:
在计算透视投影矩阵之前需要明确一点:目标投影矩阵M必须是一个固定的矩阵,针对视体内的任何一点,都使用相同的一个矩阵,条件(1)。
我们称第一步中从视体变换到立方体的矩阵
M
p
e
r
s
p
→
o
r
t
h
o
M{persp→ortho}
Mpersp→ortho为透视规范化矩阵。
对于空间内的点(x,y,z)(这里的x,y,z是变量,因为空间需要进行投影变换的点不只一个),其变换后的点为(x',y',z')。
其中:
x
′
=
n
z
x
,
y
′
=
n
z
y
,
z
′
=
?
x'=\frac{n}{z}x, y'=\frac{n}{z}y, z'=?
x′=znx,y′=zny,z′=?
z'不变:即:
x
′
=
n
z
x
,
y
′
=
n
z
y
,
z
′
=
z
x'=\frac{n}{z}x, y'=\frac{n}{z}y, z'=z
x′=znx,y′=zny,z′=z
我们可以逆向算出对应的透视规范化矩阵
M
p
e
r
s
p
→
o
r
t
h
o
M{persp→ortho}
Mpersp→ortho
M
p
e
r
s
p
→
o
r
t
h
o
=
(
n
/
z
0
0
0
0
n
/
z
0
0
0
0
1
0
0
0
0
1
)
M{persp→ortho} = (n/z0000n/z0000100001)
矩阵中n=zNear是一个常数,然而矩阵中的z是一个变量(即n/z中的z),对于视体中的每一个不同的点,都需要一个特定的z值,这并不满足条件(1),这不是我们想要的结果。我们想要一个固定的、不随目标点变化的矩阵。
z'改变:根据a.中的分析可以得出,假如令z'=z,那么对于视体中的每个点都需要一个透视规范化矩阵M,不能满足条件(1)。
因此我们需要令透视正则变换后的各点z'值发生变化,以消除透视规范化矩阵M中的变量z。
一个简单的方式是,我们先假设此时不知道z'等于什么,并令x',y'和齐次坐标中的w'都乘以z。那么 透视规范化矩阵
M
p
e
r
s
p
→
o
r
t
h
o
M{persp→ortho}
Mpersp→ortho 可以写为:
M
p
e
r
s
p
→
o
r
t
h
o
=
(
n
0
0
0
0
n
0
0
?
?
A
B
0
0
1
0
)
M{persp→ortho} = (n0000n00??AB0010)
另外由于在投影变换后还需要进行阴影遮挡判断、隐藏面消除和明暗处理等操作,因此我们需要保证原始空间中z值小的点,在投影正则化变换后的z'值依旧小,原始空间中z值大的点,在投影正则化变换后的z'值依旧大,条件(2)。
条件(2)也说明,z'只能跟原始点齐次坐标中的z和w相关,跟x,y无关,因此可以得到那么透视规范化矩阵
M
p
e
r
s
p
→
o
r
t
h
o
M{persp→ortho}
Mpersp→ortho 可以写为:
M
p
e
r
s
p
→
o
r
t
h
o
=
(
n
0
0
0
0
n
0
0
0
0
A
B
0
0
1
0
)
M{persp→ortho} = (n0000n0000AB0010)
除此以外,我们还需要令原来在z=zNear平面上的点,经过变换后依旧在z=zNear平面上,原来在z=zFar平面上的点依旧在z=zFar平面上。这是因为,我们需要保证 边界上的点变换后依旧在边界上,条件(3)。
假如不能保证满足条件(3),那么在经过投影正则化变化后,有可能原来在zFar外面的点,在变换后到了立方体内了!原本 视体 外需要被裁剪掉的点,变换到了立方体内,这可能导致裁剪错误。
因此根据条件(3),可以得到下面两个公式:
(
0
0
A
B
)
∗
(
x
y
n
1
)
=
n
2
(0\ 0\ A\ B) * (xyn1)
同时:
(
0
0
A
B
)
∗
(
x
y
f
1
)
=
f
2
(0\ 0\ A\ B) * (xyf1)
根据这两个公式即可求得
A
=
n
+
f
,
B
=
−
n
f
A=n+f, B=-nf
A=n+f,B=−nf
这就是投影变换中
M
p
e
r
s
p
→
o
r
t
h
o
M{persp→ortho}
Mpersp→ortho的由来。
投影变换的目标是:根据给出的 视体 参数(fov, aspect_ratio, zNear, zFar等参数),计算得到一个投影变换矩阵M,这个矩阵需要满足三个条件:
条件(1),这个矩阵是唯一固定的,即这个矩阵中的元素值只跟视体相关,跟视体中点的坐标无关;条件(2),经过变换后,必须保证各个点的z值相对关系不变,即假如点a的z值大于点b的z值,那么经过变换点a的z'依旧大于点b变换后的z'。那么z'不能与(x,y,z,w)中的x,y相关,只能由z,w确定;条件(3),视体边界面z=zNear平面和z=zFar平面上点的经过变换后依旧在立方体边界面上;为了满足条件(1):z'不能等于z(除了z=zNear和z=zFar平面上的点)。
为了满足条件(2):
M
p
e
r
s
p
→
o
r
t
h
o
M{persp→ortho}
Mpersp→ortho第三行
(
?
?
A
B
)
(?\ ?\ A\ B)
(? ? A B) 前两个元素需要等于0。
为了满足条件(3):
A
=
n
+
f
,
B
=
−
n
f
A=n+f, B=-nf
A=n+f,B=−nf。
1.计算机图形学第六章观察-黄章进-中国科学技术大学
2.GAMES101-Lecture 4:Transformation Matrices