【GAMES101】Lecture03,04 Transformation 精要
本文图片来源于GAMES101课件。
注:本课程中所有变换都是建立在右手系的基础上的。
MVP变换,即模型-视图-投影变换,形象来说,就是将三维世界的物体用相机“拍摄”下来,得到的相片即变换结果。
Model Transformation
模型变换即对物体做平移、旋转、缩放等变换,从而将其放置在世界坐标系中。
Translate vs. Rotate / Scale / Shear / Reflect
旋转/缩放/剪切/反射变换为线性变换,由其可加性和数乘性质可知,原点永远不动,故平移需要用更高维度的变换矩阵表示。为了达到像线性变换一样用一个矩阵表示平移变换的目的,引入齐次坐标(homogeneous coordinates)的概念。
3D点表示: ( x , y , z , 1 ) (x,y,z,1) (x,y,z,1),对于 a ≠ 0 a\ne0 a=0,它与 ( a x , a y , a z , a ) (ax,ay,az,a) (ax,ay,az,a)都表示点 ( x , y , z ) (x,y,z) (x,y,z)。
这里的点+点表示两点的中点。
3D向量表示: ( x , y , z , 0 ) (x,y,z,0) (x,y,z,0)
Affine Translation
仿射变换依次包含两个步骤:先线性变换后平移
3D Transformation
R x ( α ) = [ 1 0 0 0 0 cos α − sin α 0 0 sin α cos α 0 0 0 0 1 ] R y ( α ) = [ cos α 0 sin α 0 0 1 0 0 − sin α 0 cos α 0 0 0 0 1 ] R z ( α ) = [ cos α − sin α 0 0 sin α cos α 0 0 0 0 1 0 0 0 0 1 ] R_{x}(\alpha) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\alpha& -\sin\alpha & 0 \\ 0 & \sin\alpha & \cos\alpha & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix} R_{y}(\alpha) = \begin{bmatrix} \cos\alpha & 0 & \sin\alpha & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\alpha & 0 & \cos\alpha & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix} R_{z}(\alpha) = \begin{bmatrix} \cos\alpha& -\sin\alpha & 0 & 0\\ \sin\alpha & \cos\alpha & 0 & 0\\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} Rx(α)=⎣ ⎡10000cosαsinα00−sinαcosα00001⎦ ⎤Ry(α)=⎣ ⎡cosα0−sinα00100sinα0cosα00001⎦ ⎤Rz(α)=⎣ ⎡cosαsinα00−sinαcosα0000100001⎦ ⎤
这里只提一下绕轴旋转变换,尤其是绕y轴的旋转,与绕x、z轴的稍微不同。原因是右手系的旋转顺序: z : ( x y ) y : ( z x ) x : ( y z ) z:(xy) \quad y:(zx) \quad x:(yz) z:(xy)y:(zx)x:(yz)。
Rodrigues’ Rotation Formula 推导简述
绕给定单位轴
n
\bold{n}
n旋转
α
\alpha
α角度时的变换矩阵如下:
R
(
n
,
α
)
=
cos
(
α
)
I
+
(
1
−
cos
(
α
)
)
n
n
T
+
sin
(
α
)
[
0
−
n
z
n
y
n
z
0
−
n
x
−
n
y
n
x
0
]
R(\bold{n},\alpha)=\cos(\alpha)I + (1-\cos(\alpha))\bold{n}\bold{n}^T+\sin(\alpha)\begin{bmatrix} 0 & -n_z & n_y \\ n_z & 0 & -n_x \\ -n_y & n_x & 0 \\ \end{bmatrix}
R(n,α)=cos(α)I+(1−cos(α))nnT+sin(α)⎣
⎡0nz−ny−nz0nxny−nx0⎦
⎤
注:
-
单位轴意味着 n = n ^ \bold{n}=\hat{\bold{n}} n=n^,式中最后一项的矩阵即三维叉乘矩阵;
-
该公式默认轴的起始点在坐标原点,如果要绕某一特定位置的轴做旋转,那么变换矩阵的形式应为 T − 1 R ( n , α ) T T^{-1}R(\bold{n},\alpha)T T−1R(n,α)T,其中 T T T为平移矩阵,作用是将对象按照“将旋转轴的起点移动到原点上”的相同效果进行平移。
这里仅给出推导的大致流程以及关键步骤的解读:
-
任给定一个不平行于 n \bold{n} n的向量 v \bold{v} v,将其分解为平行于 n \bold{n} n的 v ∥ \bold{v}_{\parallel} v∥和垂直于 n \bold{n} n的 v ⊥ \bold{v}_{\perp} v⊥。其中 v ∥ \bold{v}_{\parallel} v∥借助点乘得到,即 v ∥ = ( n ^ ⋅ v ) n ^ \bold{v}_{\parallel}=(\hat{\bold{n}}\cdot\bold{v})\hat{\bold{n}} v∥=(n^⋅v)n^,而点乘 n ^ ⋅ v \hat{\bold{n}}\cdot\bold{v} n^⋅v的等价形式为 n ^ T v \hat{\bold{n}}^T\bold{v} n^Tv,故有 v ∥ = ( n ^ ⋅ v ) n ^ = n ^ ( n ^ ⋅ v ) = n ^ n ^ T v \bold{v}_{\parallel}=(\hat{\bold{n}}\cdot\bold{v})\hat{\bold{n}}=\hat{\bold{n}}(\hat{\bold{n}}\cdot\bold{v})=\hat{\bold{n}}\hat{\bold{n}}^T\bold{v} v∥=(n^⋅v)n^=n^(n^⋅v)=n^n^Tv;由此通过向量减法得 v ⊥ = v − v ∥ = ( I − n ^ n ^ T ) v \bold{v}_{\perp}=\bold{v}-\bold{v}_{\parallel}=(I-\hat{\bold{n}}\hat{\bold{n}}^T)\bold{v} v⊥=v−v∥=(I−n^n^T)v (分配律);
-
旋转只对 v ⊥ \bold{v}_{\perp} v⊥造成实质影响,相当于仅对 v ⊥ \bold{v}_{\perp} v⊥执行绕 n \bold{n} n的 α \alpha α角度的旋转,其旋转平面由 v ^ ⊥ \hat{\bold{v}}_{\perp} v^⊥与 n ^ × v ^ ⊥ \hat{\bold{n}}\times\hat{\bold{v}}_{\perp} n^×v^⊥确定,以它们为基向量来表示旋转后的 v ⊥ \bold{v}_{\perp} v⊥,记为 v ⊥ r o t \bold{v}_{\perp}^{rot} v⊥rot;
-
不难得到 v ⊥ r o t \bold{v}_{\perp}^{rot} v⊥rot于新的基向量组 { v ^ ⊥ , n ^ × v ^ ⊥ } \{\hat{\bold{v}}_{\perp},\hat{\bold{n}}\times\hat{\bold{v}}_{\perp}\} {v^⊥,n^×v^⊥}下的坐标 ( ∥ v ⊥ ∥ cos α , ∥ v ⊥ ∥ sin α ) (\Vert\bold{v}_{\perp}\Vert\cos\alpha,\Vert\bold{v}_{\perp}\Vert\sin\alpha) (∥v⊥∥cosα,∥v⊥∥sinα);
-
变换后的向量 v ′ = v ⊥ r o t + v ∥ \bold{v'}=\bold{v}_{\perp}^{rot} + \bold{v}_{\parallel} v′=v⊥rot+v∥,代入各部分的推导结果即可得到 v ′ = R ( n , α ) v \bold{v'}=R(\bold{n},\alpha)\bold{v} v′=R(n,α)v。
Viewing Transformation
View/Camera Transformation
视图变换,即将相机的位置、前向和上方向确定好后,将画面中的所有对象随着相机一起变换(保持相对静止,因而最终拍摄结果不变),使得相机位于坐标原点,上方朝y轴正向,前向朝z轴负向。
注:不仅相机要做视图变换,在画面中的所有对象也得做相同的视图变换,因而计算开销取决于有关的对象数目。
视图变换的过程:① 将相机平移至坐标原点;② 将三个轴向 g ^ \hat g g^、 t ^ \hat t t^、 g ^ × t ^ \hat g \times \hat t g^×t^依次对准 − z \bold{-z} −z、 y \bold{y} y、 x \bold{x} x。
矩阵形式:
M
v
i
e
w
=
R
v
i
e
w
T
v
i
e
w
M_{view}=R_{view}T_{view}
Mview=RviewTview
其中
R
v
i
e
w
R_{view}
Rview为旋转变换,正向过程不好表示,逆向过程比较直观。对于可逆的线性变换来说,其矩阵为正交矩阵,因而有
R
v
i
e
w
−
1
=
R
v
i
e
w
T
R_{view}^{-1} = R_{view}^T
Rview−1=RviewT
该逆矩阵将 x y z xyz xyz轴向依次旋转为 g ^ × t ^ \hat g \times \hat t g^×t^、 t ^ \hat t t^、 − g ^ -\hat g −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_{view}^{-1} = \begin{bmatrix} x_{\hat g \times \hat t} & x_{\hat t} & x_{-\hat g} & 0 \\ y_{\hat g \times \hat t} & y_{\hat t}& y_{-\hat g} & 0 \\ z_{\hat g \times \hat t} & z_{\hat t} & z_{-\hat g} & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix} Rview−1=⎣ ⎡xg^×t^yg^×t^zg^×t^0xt^yt^zt^0x−g^y−g^z−g^00001⎦ ⎤
因而有:
M v i e w = ( R v i e w T ) T T 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 ] [ 1 0 0 − x e 0 1 0 − y e 0 0 1 − z e 0 0 0 1 ] \begin{align} M_{view}&=(R_{view}^T)^TT_{view} \nonumber\\ &=\begin{bmatrix} x_{\hat g \times \hat t} & y_{\hat g \times \hat t} & z_{\hat g \times \hat t} & 0 \\ x_{\hat t} & y_{\hat t}& z_{\hat t} & 0 \\ x_{-\hat g}& y_{-\hat g} & z_{-\hat g} & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}\begin{bmatrix} 1 & 0 & 0 & -x_e \\ 0 & 1& 0 & -y_e \\ 0 & 0 & 1 & -z_e \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}\nonumber \end{align} Mview=(RviewT)TTview=⎣ ⎡xg^×t^xt^x−g^0yg^×t^yt^y−g^0zg^×t^zt^z−g^00001⎦ ⎤⎣ ⎡100001000010−xe−ye−ze1⎦ ⎤
注:相机朝向向量 g ^ × t ^ \hat g \times \hat t g^×t^、 t ^ \hat t t^、 g ^ \hat g g^以及相机位置 e \bold{e} e的坐标均为世界坐标,即 x g ^ × t ^ x_{\hat g \times \hat t} xg^×t^, x t ^ x_{\hat t} xt^, x − g ^ x_{-\hat g} x−g^, x e x_e xe等都是世界坐标系下的分量值。
Projection
1. Orthogonal Projection
过程:先把长方体(可以视作物体的包围体)随着其中心平移到原点,然后缩放至
[
−
1
,
1
]
3
[-1,1]^3
[−1,1]3的立方体中。
变换对应的矩阵形式:
M 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 ] s c a l e [ 1 0 0 − l + r 2 0 1 0 − b + t 2 0 0 1 − f + n 2 0 0 0 1 ] t r a n s l a t e M_{ortho}= \begin{bmatrix} \frac{2}{r-l} & 0 & 0 & 0 \\ 0 & \frac{2}{t-b} & 0 & 0 \\ 0 & 0 & \frac{2}{n-f} & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}_{scale}\begin{bmatrix} 1 & 0 & 0 & -\frac{l+r}{2} \\ 0 & 1& 0 & -\frac{b+t}{2} \\ 0 & 0 & 1 & -\frac{f+n}{2} \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}_{translate} Mortho=⎣ ⎡r−l20000t−b20000n−f200001⎦ ⎤scale⎣ ⎡100001000010−2l+r−2b+t−2f+n1⎦ ⎤translate
2. Perspective Projection
过程:① 先将截锥(frustum)中垂直于z轴的各个平面“挤压”至以近平面为底面的长方体中;② 然后沿z轴执行正交投影。
性质:① 投影前后近平面和远平面上各点的z值不会改变;② 近平面的各点在投影前后完全不变。
上述性质告诉我们:
( x , y , n , 1 ) → ( x , y , n , 1 ) ≡ ( n x , n y , n 2 , n ) (x,y,n,1) \rightarrow (x,y,n,1)\equiv(nx,ny,n^2,n) (x,y,n,1)→(x,y,n,1)≡(nx,ny,n2,n) (性质2)
( x , y , f , 1 ) → ( x ′ , y ′ , f , 1 ) ≡ ( n x , n y , f 2 , f ) (x,y,f,1) \rightarrow (x',y',f,1)\equiv (nx,ny,f^2,f) (x,y,f,1)→(x′,y′,f,1)≡(nx,ny,f2,f) (性质1)。特别地,远平面的中心点 ( 0 , 0 , f , 1 ) → ( 0 , 0 , f 2 , f ) (0,0,f,1) \rightarrow (0, 0, f^2, f) (0,0,f,1)→(0,0,f2,f)
由此不难得出透视投影变换的矩阵形式:
M p e r s p = M o r t h o M p e r s p → o r t h o M_{persp}=M_{ortho}M_{persp\rightarrow ortho} Mpersp=MorthoMpersp→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\rightarrow ortho}=\begin{bmatrix} n & 0 & 0 & 0 \\ 0 & n& 0 & 0 \\ 0 & 0 & n+f & -nf \\ 0 & 0 & 1 & 0 \\ \end{bmatrix} Mpersp→ortho=⎣ ⎡n0000n0000n+f100−nf0⎦ ⎤
思考题
Lecture04最后遗留的问题:对于 z ∈ ( f , n ) z \in (f,n) z∈(f,n)的点 ( x , y , z , 1 ) , ( z < 0 ) (x,y,z,1),(z\lt0) (x,y,z,1),(z<0),考虑执行透视投影中的挤压步骤后 z z z值的变化如何。
解法:用变换矩阵 M p e r s p → o r t h o M_{persp\rightarrow ortho} Mpersp→ortho乘以 ( x , y , z , 1 ) T (x,y,z,1)^T (x,y,z,1)T:
M p e r s p → o r t h o ( x , y , z , 1 ) T = [ n 0 0 0 0 n 0 0 0 0 n + f − n f 0 0 1 0 ] ( x y z 1 ) = ( n x n y ( n + f ) z − n f z ) ≡ ( n x / z n y / z ( n + f ) − n f / z 1 ) \begin{align} M_{persp\rightarrow ortho}(x,y,z,1)^T&=\begin{bmatrix} n & 0 & 0 & 0 \\ 0 & n& 0 & 0 \\ 0 & 0 & n+f & -nf \\ 0 & 0 & 1 & 0 \\ \end{bmatrix}\begin{pmatrix}x \\ y \\ z \\ 1\end{pmatrix} \nonumber\\&=\begin{pmatrix}nx \\ ny \\ (n+f)z-nf \\ z\end{pmatrix}\nonumber \equiv \begin{pmatrix}nx/z \\ ny/z \\ (n+f)-nf/z \\ 1\end{pmatrix}\end{align} Mpersp→ortho(x,y,z,1)T=⎣ ⎡n0000n0000n+f100−nf0⎦ ⎤⎝ ⎛xyz1⎠ ⎞=⎝ ⎛nxny(n+f)z−nfz⎠ ⎞≡⎝ ⎛nx/zny/z(n+f)−nf/z1⎠ ⎞
即比较 z z z和 ( n + f ) − n f / z (n+f)-nf/z (n+f)−nf/z的大小,稍作变形,并令 F ( z ) = z 2 − ( n + f ) z + n f F(z)=z^2-(n+f)z+nf F(z)=z2−(n+f)z+nf,即比较函数 F ( z ) F(z) F(z)与0的大小关系,观察其函数图像,可知 F ( z ) F(z) F(z)与 z z z轴交于 ( n , 0 ) (n,0) (n,0)和 ( f , 0 ) (f,0) (f,0)两点,且开口向上,故对于 z ∈ ( f , n ) z \in (f, n) z∈(f,n)有 F ( z ) < 0 F(z)<0 F(z)<0,注意到 z < 0 z\lt0 z<0,因此 z > ( n + f ) − n f / z z>(n+f)-nf/z z>(n+f)−nf/z,这说明夹在远近平面之间的平面在挤压过程中z轴值向远平面靠近。