【GAMES101学习笔记】04 - 视图变换

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^

【GAMES101学习笔记】04 - 视图变换

关键

  • 若相机和所有的对象均一起发生移动,投影出来的 Photo 不会发生变化。

【GAMES101学习笔记】04 - 视图变换

因此,我们总将 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 轴。
       
  • 矩阵 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 轴。

【GAMES101学习笔记】04 - 视图变换

构造矩阵 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​=Rview​Tview​
  • 将 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​=⎣⎢⎢⎡​1000​0100​0010​−xe​−ye​−ze​1​⎦⎥⎥⎤​
  • 旋转矩阵 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^​0​xt​yt​zt​0​x−g​y−g​z−g​0​0001​⎦⎥⎥⎤​Rview​=⎣⎢⎢⎡​xg^​×t^​xt​x−g​0​yg^​×t^​yt​y−g​0​zg^​×t^​zt​z−g​0​0001​⎦⎥⎥⎤​​

NOTE

  • 视图变换 变换的是 Camera ,其他的 Object 相对于 Camera 在进行移动;
  • 若先进行了 模型变换 ,在后面进行 视图变换 时,会在移动 Camera 的同时,需要将 Object 也跟着 Camera 一同移动,以此保持 Photo 不变;
  • 可见不管是 视图变换 还是 模型变换 ,最终本质上还是作用在 Object 上面,因此人们往往习惯将二者统称为 模型/视图变换(Model/View Transformation)

3. 投影变换(Projection transformation)

计算机图形学中的投影:

【GAMES101学习笔记】04 - 视图变换

  • 3D 到 2D
  • 正交投影(Orthographic projection)
  • 透视投影(Perspective projection):会存在 “近大远小” 的现象

【GAMES101学习笔记】04 - 视图变换

  • 正交投影(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 上。

【GAMES101学习笔记】04 - 视图变换

方法二

  • 先通过 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

【GAMES101学习笔记】04 - 视图变换

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​=⎣⎢⎢⎢⎢⎢⎡​1000​0100​0010​−2r+l​−2t+b​−2n+f​1​⎦⎥⎥⎥⎥⎥⎤​

  • 将 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−l2​000​0t−b2​00​00n−f2​0​0001​⎦⎥⎥⎥⎥⎥⎤​

  • 可得最后的正交投影矩阵为:
    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−l2​000​0t−b2​00​00n−f2​0​0001​⎦⎥⎥⎥⎥⎥⎤​⎣⎢⎢⎢⎢⎢⎡​1000​0100​0010​−2r+l​−2t+b​−2n+f​1​⎦⎥⎥⎥⎥⎥⎤​

3.2 透视投影(Perspective projection)

  • 近大远小
  • 平行线不再平行;会收敛到一个点

【GAMES101学习笔记】04 - 视图变换

  • 齐次坐标表示的点 ( 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 透视投影的过程

【GAMES101学习笔记】04 - 视图变换

  • 先将 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 平面上的变换关系

【GAMES101学习笔记】04 - 视图变换

  • 找起始点 ( 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′=zn​x , y ′ = n z y y' = \cfrac{n}{z}y y′=zn​y

  • 暂时可以获得以下关系:
    ( 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?0​0n?0​00?1​00?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} (0​0​A​B​) ,则有:
    ( 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 (0​0​A​B​)⎝⎜⎜⎛​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​=⎝⎜⎜⎜⎜⎜⎛​n000​0n00​00n+f1​00−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−l2​000​0t−b2​00​00n−f2​0​0001​⎦⎥⎥⎥⎥⎥⎤​⎣⎢⎢⎢⎢⎢⎡​1000​0100​0010​−2r+l​−2t+b​−2n+f​1​⎦⎥⎥⎥⎥⎥⎤​⎣⎢⎢⎢⎢⎢⎡​n000​0n00​00n+f1​00−nf0​⎦⎥⎥⎥⎥⎥⎤​​

上一篇:【GAMES101现代计算机图形学入门笔记】Lec03 变换


下一篇:MySQL学习笔记_10_MySQL高级操作(下)