1. MVP 变换简介
- Model Transformation (placing objects)
世界坐标系下有很多 Object ,用一个变化矩阵把它们的顶点坐标从Local坐标系(相对坐标)转换到世界Global坐标系(绝对坐标),这就是 模型变换 。
- View Transformation (placing camera)
我们看到的画面由 camera 捕捉, camera 参数决定了我们在屏幕上看到的东西,这一步可以将世界坐标系转换到摄像机坐标系,这就是 视图变换 。
- Projection Transformation
模型 / 视图变换之后,做一个投影变换,将三维空间中的物体投影到二维空间中。
2. 视图/相机变换(View/Camera Transformation)
定义一个相机
- 位置(Position): e ⃗ \vec{e} e
- 朝向(Look-at/gaze direction): g ^ \hat{g} g^
- 上方向(Up direction): t ^ \hat{t} t^
关键 :
- 若相机和所有的对象均一起发生移动,投影出来的 Photo 不会发生变化。
因此,我们总将 Camera 固定在一个 标准位置 :
- 原点,Up direction 沿着 y y y 轴方向,Look-at direction 沿着 − z -z −z 轴;
- Camera 固定,让其他的对象跟随一起运动。
2.1 视图/相机变换
将相机从一个任意位置变换到标准位置
- 使用矩阵
M
v
i
e
w
M_{view}
Mview
- 将其固定在原点,Up direction 沿着
y
y
y 轴方向,Look-at direction 沿着
−
z
-z
−z 轴。
- 将其固定在原点,Up direction 沿着
y
y
y 轴方向,Look-at direction 沿着
−
z
-z
−z 轴。
- 矩阵
M
v
i
e
w
M_{view}
Mview 的数学性质:
- 变换 e e e 到原点;
- 旋转 g g g 到 − z -z −z 轴;
- 旋转 ( g × t ) (g \times t) (g×t) 到 x x x 轴。
构造矩阵 M v i e w M_{view} Mview :
- M v i e w = R v i e w T v i e w M_{view} = R_{view}T_{view} Mview=RviewTview
- 将
e
e
e 变换到原点的位移变换:
T v i e w = [ 1 0 0 − x e 0 1 0 − y e 0 0 1 − z e 0 0 0 1 ] T_{view} = \begin{bmatrix} 1 & 0 & 0 & -x_e \\ 0 & 1 & 0 & -y_e \\ 0 & 0 & 1 & -z_e \\ 0 & 0 & 0 & 1 \end{bmatrix} Tview=⎣⎢⎢⎡100001000010−xe−ye−ze1⎦⎥⎥⎤ - 旋转矩阵
g
↦
−
Z
g \mapsto -Z
g↦−Z ,
t
↦
Y
t \mapsto Y
t↦Y ,
(
g
×
t
)
↦
X
(g \times t) \mapsto X
(g×t)↦X
不妨先求逆变换矩阵 X ↦ ( g × t ) X \mapsto (g \times t) X↦(g×t) , Y ↦ t Y \mapsto t Y↦t , Z ↦ − g Z \mapsto -g Z↦−g
R v i e w − 1 = [ x g ^ × t ^ x t x − g 0 y g ^ × t ^ y t y − g 0 z g ^ × t ^ z t z − g 0 0 0 0 1 ] R v i e w = [ x g ^ × t ^ y g ^ × t ^ z g ^ × t ^ 0 x t y t z t 0 x − g y − g z − g 0 0 0 0 1 ] \begin{aligned} &R_{view}^{-1} = \begin{bmatrix} x_{\hat{g}\times\hat{t}} & x_t & x_{-g} & 0 \\ y_{\hat{g}\times\hat{t}} & y_t & y_{-g} & 0 \\ z_{\hat{g}\times\hat{t}} & z_t & z_{-g} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \\[8ex] &R_{view} = \begin{bmatrix} x_{\hat{g}\times\hat{t}} & y_{\hat{g}\times\hat{t}} & z_{\hat{g}\times\hat{t}} & 0 \\ x_t & y_t & z_t & 0 \\ x_{-g} & y_{-g} & z_{-g} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \end{aligned} Rview−1=⎣⎢⎢⎡xg^×t^yg^×t^zg^×t^0xtytzt0x−gy−gz−g00001⎦⎥⎥⎤Rview=⎣⎢⎢⎡xg^×t^xtx−g0yg^×t^yty−g0zg^×t^ztz−g00001⎦⎥⎥⎤
NOTE :
- 视图变换 变换的是 Camera ,其他的 Object 相对于 Camera 在进行移动;
- 若先进行了 模型变换 ,在后面进行 视图变换 时,会在移动 Camera 的同时,需要将 Object 也跟着 Camera 一同移动,以此保持 Photo 不变;
- 可见不管是 视图变换 还是 模型变换 ,最终本质上还是作用在 Object 上面,因此人们往往习惯将二者统称为 模型/视图变换(Model/View Transformation) 。
3. 投影变换(Projection transformation)
计算机图形学中的投影:
- 3D 到 2D
- 正交投影(Orthographic projection)
- 透视投影(Perspective projection):会存在 “近大远小” 的现象
- 正交投影(Orthographic projection):Camera 在一个 “点” 进行观察
- 透视投影(Perspective projection):Camera 在 “无限远” 处进行观察
3.1 正交投影(Orthographic projection)
方法一 :
- Camera 放置在原点,朝向 − z -z −z 轴,上方向为 y y y 轴;
- 消除掉 z z z 轴上的信息;
- 将生成的矩形平移缩放至小矩形 [ − 1 , 1 ] 2 [-1,1]^2 [−1,1]2 上。
方法二 :
- 先通过 6 个参数描述一个立方体(AABB);
- 将其映射到正则立方体(“Canonical” Cube):
[ l , r ] × [ b , t ] × [ f , n ] ↦ [ − 1 , 1 ] 3 [l,r]\times[b,t]\times[\bold{f},\bold{n}] \mapsto [-1,1]^3 [l,r]×[b,t]×[f,n]↦[−1,1]3
NOTE :
- 先将中心平移到原点,之后再将轴缩放到 [ − 1 , 1 ] 3 [-1,1]^3 [−1,1]3
- 因为 Camera 是沿着 − z -z −z 轴的方向(右手坐标系),因此远的地方 z z z 值较小,近的地方 z z z 值较大
构造矩阵 M o r t h o M_{ortho} Mortho :
-
先将中心点平移至原点:
T o r t h o = [ 1 0 0 − r + l 2 0 1 0 − t + b 2 0 0 1 − n + f 2 0 0 0 1 ] T_{ortho} = \begin{bmatrix} 1 & 0 & 0 & -\frac{r+l}{2} \\[1.5ex] 0 & 1 & 0 & -\frac{t+b}{2} \\[1.5ex] 0 & 0 & 1 & -\frac{n+f}{2} \\[1.5ex] 0 & 0 & 0 & 1 \end{bmatrix} Tortho=⎣⎢⎢⎢⎢⎢⎡100001000010−2r+l−2t+b−2n+f1⎦⎥⎥⎥⎥⎥⎤ -
将 length/width/height 缩放至 2
R o r t h o = [ 2 r − l 0 0 0 0 2 t − b 0 0 0 0 2 n − f 0 0 0 0 1 ] R_{ortho} = \begin{bmatrix} \frac{2}{r-l} & 0 & 0 & 0 \\[1.5ex] 0 & \frac{2}{t-b} & 0 & 0 \\[1.5ex] 0 & 0 & \frac{2}{n-f} & 0 \\[1.5ex] 0 & 0 & 0 & 1 \end{bmatrix} Rortho=⎣⎢⎢⎢⎢⎢⎡r−l20000t−b20000n−f200001⎦⎥⎥⎥⎥⎥⎤ -
可得最后的正交投影矩阵为:
M o r t h o = R o r t h o ⋅ T o r t h o = [ 2 r − l 0 0 0 0 2 t − b 0 0 0 0 2 n − f 0 0 0 0 1 ] [ 1 0 0 − r + l 2 0 1 0 − t + b 2 0 0 1 − n + f 2 0 0 0 1 ] M_{ortho} = R_{ortho} \cdot T_{ortho} = \begin{bmatrix} \frac{2}{r-l} & 0 & 0 & 0 \\[1.5ex] 0 & \frac{2}{t-b} & 0 & 0 \\[1.5ex] 0 & 0 & \frac{2}{n-f} & 0 \\[1.5ex] 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & -\frac{r+l}{2} \\[1.5ex] 0 & 1 & 0 & -\frac{t+b}{2} \\[1.5ex] 0 & 0 & 1 & -\frac{n+f}{2} \\[1.5ex] 0 & 0 & 0 & 1 \end{bmatrix} Mortho=Rortho⋅Tortho=⎣⎢⎢⎢⎢⎢⎡r−l20000t−b20000n−f200001⎦⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎡100001000010−2r+l−2t+b−2n+f1⎦⎥⎥⎥⎥⎥⎤
3.2 透视投影(Perspective projection)
- 近大远小
- 平行线不再平行;会收敛到一个点
- 齐次坐标表示的点 ( x , y , z , 1 ) (x,y,z,1) (x,y,z,1) 和 ( k x , k y , k z , k ) (kx,ky,kz,k) (kx,ky,kz,k) 均表示三维空间中的点 ( x , y , z ) (x,y,z) (x,y,z) ,其中 k ≠ 0 k \neq 0 k=0 ;
- 显然当 k = z k = z k=z 时,可以用 ( x z , y z , z 2 , z ) (xz,yz,z^2,z) (xz,yz,z2,z) 表示点 ( x , y , z ) (x,y,z) (x,y,z) ,其中 z ≠ 0 z \neq 0 z=0 ;
- eg. : ( 1 , 0 , 0 , 1 ) (1,0,0,1) (1,0,0,1) 和 ( 2 , 0 , 0 , 2 ) (2,0,0,2) (2,0,0,2) 都表示点 ( 1 , 0 , 0 ) (1,0,0) (1,0,0)
3.2.1 透视投影的过程
- 先将 Frustum 挤压成一个 Cuboid :(
n
→
n
n \to n
n→n ,
f
→
f
f \to f
f→f ,
M
p
e
r
s
p
→
o
r
t
h
o
M_{persp \to ortho}
Mpersp→ortho ):
- 挤压过程中 “*面(near plane)”( z = n z = n z=n ) 不会发生变化;
- 挤压过程中 “远平面(far plane)”( z = f z = f z=f ) 仅在 x O y xOy xOy 平面上变化, z z z 轴上的值不发生变化,特别地,中心点不会发生变化。
- 再做正交投影(使用 M o r t h o M_{ortho} Mortho )
3.2.2 构造变换矩阵
STEP - 01:先找到在 xoy 平面上的变换关系
-
找起始点 ( x , y , z ) (x,y,z) (x,y,z) 和变换后的点 ( x ′ , y ′ , z ′ ) (x',y',z') (x′,y′,z′) 。
-
可以找到各个分量的对应关系: x ′ = n z x x' = \cfrac{n}{z}x x′=znx , y ′ = n z y y' = \cfrac{n}{z}y y′=zny
-
暂时可以获得以下关系:
( x y z 1 ) ↦ M p e r s p → o r t h o ( 4 × 4 ) ( n x / z n y / z u n k n o w n 1 ) → m u l t . b y z ( n x n y u n k n o w n z ) \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} \xmapsto{M_{persp \to ortho}^{(4 \times 4)}} \begin{pmatrix} nx/z \\ ny/z \\ unknown \\ 1 \end{pmatrix} \xrightarrow{mult. \space by \space z} \begin{pmatrix} nx \\ ny \\ unknown \\ z \end{pmatrix} ⎝⎜⎜⎛xyz1⎠⎟⎟⎞Mpersp→ortho(4×4) ⎝⎜⎜⎛nx/zny/zunknown1⎠⎟⎟⎞mult. by z ⎝⎜⎜⎛nxnyunknownz⎠⎟⎟⎞ -
可以先构造 M p e r s p → o r t h o M_{persp \to ortho} Mpersp→ortho 的一部分:
M p e r s p → o r t h o = ( n 0 0 0 0 n 0 0 ? ? ? ? 0 0 1 0 ) M_{persp \to ortho} = \begin{pmatrix} n & 0 & 0 & 0 \\[1.5ex] 0 & n & 0 & 0 \\[1.5ex] ? & ? & ? & ? \\[1.5ex] 0 & 0 & 1 & 0 \end{pmatrix} Mpersp→ortho=⎝⎜⎜⎜⎜⎜⎛n0?00n?000?100?0⎠⎟⎟⎟⎟⎟⎞
STEP - 02:再找在 z 轴方向上的变换关系
矩阵 M p e r s p → o r t h o M_{persp \to ortho} Mpersp→ortho 中的第三排控制 z ↦ z ′ z \mapsto z' z↦z′ :
- “*面(near plane)”(
z
=
n
z = n
z=n )上的任意点不会发生变化:
( x y n 1 ) ↦ M p e r s p → o r t h o ( 4 × 4 ) ( x y n 1 ) → m u l t . b y n ( n x n y n 2 n ) \begin{pmatrix} x \\ y \\ n \\ 1 \end{pmatrix} \xmapsto{M_{persp \to ortho}^{(4 \times 4)}} \begin{pmatrix} x \\ y \\ n \\ 1 \end{pmatrix} \xrightarrow{mult. \space by \space n} \begin{pmatrix} nx \\[1.25ex] ny \\[1.25ex] n^2 \\[1.25ex] n \end{pmatrix} ⎝⎜⎜⎛xyn1⎠⎟⎟⎞Mpersp→ortho(4×4) ⎝⎜⎜⎛xyn1⎠⎟⎟⎞mult. by n ⎝⎜⎜⎜⎜⎛nxnyn2n⎠⎟⎟⎟⎟⎞
设矩阵的第三行为 ( 0 0 A B ) \begin{pmatrix} 0 & 0 & A & B\end{pmatrix} (00AB) ,则有:
( 0 0 A B ) ( x y n 1 ) = n 2 \begin{pmatrix} 0 & 0 & A & B \end{pmatrix} \begin{pmatrix} x \\ y \\ n \\ 1 \end{pmatrix} = n^2 (00AB)⎝⎜⎜⎛xyn1⎠⎟⎟⎞=n2
可得表达式: A n + B = n 2 An + B = n^2 An+B=n2
- “远平面(far plane)”(
z
=
f
z = f
z=f )上的点的
z
z
z 分量不会发生变化,不过这里我们只观察中心点
(
0
,
0
,
f
)
(0,0,f)
(0,0,f) ,在经过挤压变换之后没有发生任何变化:
( 0 0 f 1 ) ↦ M p e r s p → o r t h o ( 4 × 4 ) ( 0 0 f 1 ) → m u l t . b y n ( 0 0 f 2 f ) \begin{pmatrix} 0 \\ 0 \\ f \\ 1 \end{pmatrix} \xmapsto{M_{persp \to ortho}^{(4 \times 4)}} \begin{pmatrix} 0 \\ 0 \\ f \\ 1 \end{pmatrix} \xrightarrow{mult. \space by \space n} \begin{pmatrix} 0 \\ 0 \\ f^2 \\ f \end{pmatrix} ⎝⎜⎜⎛00f1⎠⎟⎟⎞Mpersp→ortho(4×4) ⎝⎜⎜⎛00f1⎠⎟⎟⎞mult. by n ⎝⎜⎜⎛00f2f⎠⎟⎟⎞
可得表达式: A f + B = f 2 Af + B = f^2 Af+B=f2
- 可以解得矩阵第三行中待定的系数
A
A
A 和
B
B
B :
{ A n + B = n 2 A f + B = f 2 ⇒ { A = n + f B = − n f \begin{cases} An + B = n^2 \\ Af + B = f^2 \end{cases} \Rightarrow \begin{cases} A = n + f \\ B = -nf \end{cases} {An+B=n2Af+B=f2⇒{A=n+fB=−nf
SETP - 03 :构造透视投影矩阵
此时已经得到了 挤压矩阵
M
p
e
r
s
p
→
o
r
t
h
o
M_{persp \to ortho}
Mpersp→ortho :
M
p
e
r
s
p
→
o
r
t
h
o
=
(
n
0
0
0
0
n
0
0
0
0
n
+
f
−
n
f
0
0
1
0
)
M_{persp \to ortho} = \begin{pmatrix} n & 0 & 0 & 0 \\[1.5ex] 0 & n & 0 & 0 \\[1.5ex] 0 & 0 & n + f & -nf \\[1.5ex] 0 & 0 & 1 & 0 \end{pmatrix}
Mpersp→ortho=⎝⎜⎜⎜⎜⎜⎛n0000n0000n+f100−nf0⎠⎟⎟⎟⎟⎟⎞
因此可得 透视投影矩阵 为:
M
p
e
r
s
p
=
M
o
r
t
h
o
⋅
M
p
e
r
s
p
→
o
r
t
h
o
=
[
2
r
−
l
0
0
0
0
2
t
−
b
0
0
0
0
2
n
−
f
0
0
0
0
1
]
[
1
0
0
−
r
+
l
2
0
1
0
−
t
+
b
2
0
0
1
−
n
+
f
2
0
0
0
1
]
[
n
0
0
0
0
n
0
0
0
0
n
+
f
−
n
f
0
0
1
0
]
\begin{aligned} &M_{persp} = M_{ortho} \cdot M_{persp \to ortho} = \\[3ex] &\begin{bmatrix} \frac{2}{r-l} & 0 & 0 & 0 \\[1.5ex] 0 & \frac{2}{t-b} & 0 & 0 \\[1.5ex] 0 & 0 & \frac{2}{n-f} & 0 \\[1.5ex] 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & -\frac{r+l}{2} \\[1.5ex] 0 & 1 & 0 & -\frac{t+b}{2} \\[1.5ex] 0 & 0 & 1 & -\frac{n+f}{2} \\[1.5ex] 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} n & 0 & 0 & 0 \\[1.5ex] 0 & n & 0 & 0 \\[1.5ex] 0 & 0 & n + f & -nf \\[1.5ex] 0 & 0 & 1 & 0 \end{bmatrix} \end{aligned}
Mpersp=Mortho⋅Mpersp→ortho=⎣⎢⎢⎢⎢⎢⎡r−l20000t−b20000n−f200001⎦⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎡100001000010−2r+l−2t+b−2n+f1⎦⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎡n0000n0000n+f100−nf0⎦⎥⎥⎥⎥⎥⎤