Games101学习笔记#2 - 变换(二维与三维、模型、视图、投影)

428 阅读10分钟

课程地址

课程录像:GAMES101-现代计算机图形学入门-闫令琪
课程主页:GAMES101: 现代计算机图形学入门
本节PPT:GAMES101_Lecture_03GAMES101_Lecture_04
作业地址:往期作业汇总帖

1. 摘要

  • 二维变换(旋转、缩放、错切)
  • 齐次坐标
  • 组合变换

2. 二维变换

  • 缩放:将一张图片缩放ss倍,即所有组成该图片的像素点所表示的向量缩放ss倍。
    • 数学形式:任意一点(x,y)(x,y)缩放之后为(sx,sy)(sx,sy),即(x,y)(x',y') = (sx,sy)(sx,sy)
    • 矩阵形式:[xy]=[s00s][xy]\begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}s & 0 \\0 & s\end{bmatrix} \begin{bmatrix}x\\y\end{bmatrix} ,其中[s00s]\begin{bmatrix}s & 0 \\0 & s\end{bmatrix}为缩放矩阵,表示在 xx 轴和yy 轴方向上都缩放ss倍。缩放矩阵也可以不均匀缩放,如[m00n]\begin{bmatrix}m & 0 \\0 & n\end{bmatrix}表示在 xx 轴方向上缩放mm倍,在yy 轴方向上缩放nn倍。
      注:缩放矩阵的大小由向量的维度决定,nn维向量的缩放矩阵的大小为n×nn\times n,其他变换矩阵亦同。
  • 错切:简单的讲,错切变换就是将一个矩形变成一个平行四边形。假设现在有一个正方形,将正方形的一条边向水平方向向右移动,同时对边不动,左右两条边倾斜,这个变换就是错切变换。
    • 数学形式:以上述为例,正方形在水平错切时,可以发现一个规律,所有点坐标的yy不变,只有xx在变,即错切只会影响同方向上的坐标。那么如下图所示,上边移动了aa,那么可以看到,随着yy的减小,坐标的水平平移量也越少,斜率为a1\frac{a}{1},平移量为ayay,故(x,y)(x',y') = (x+ay,y)(x+ay,y)
    • 矩阵形式:[xy]=[1a01][xy] \begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}1 & a \\ 0 & 1 \end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix}
      image.png
  • 旋转:将一个图片以原点为中心,旋转 θ\theta 角度。此处跳过了旋转矩阵的推导,可自行度娘,或点击下方的油管链接学习推导过程。
    • 数学形式:(x,y)=(cosθxsinθy,sinθx+cosθy)(x',y') = (cos\theta x-sin\theta y,sin\theta x+cos\theta y)
    • 矩阵形式:[xy]=[cosθsinθsinθcosθ][xy] \begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix}
    • 旋转矩阵推导: 油管链接(需梯子) 注:可以发现,以上几种变换用矩阵形式表示时,坐标的转换都可以只通过乘以一个矩阵来完成变换过程,那么这种变换统称为,线性变换。

3. 齐次坐标

介绍齐次坐标前,先了解一下平移变换。

  • 平移变换:顾名思义,就是移动一张图片,xx坐标和yy坐标各加上一个常量。
    • 数学形式:(x,y)=(x+m,y+n)(x',y')=(x+m,y+n)
    • 矩阵形式:[xy]=[xy]+[mn]\begin{bmatrix}x'\\y'\end{bmatrix} = \begin{bmatrix}x\\y\end{bmatrix}+\begin{bmatrix}m\\n\end{bmatrix} 可以看出,平移变换不能通过乘以一个矩阵的形式来实现,因此平移变换并不是线性变换。为了让平移矩阵可以像线性变换一样用一个矩阵来表示,而不是作为特例,接下来引入齐次坐标的概念。
  • 定义:将一个维度ww加入到坐标的表示中。那么原本一个二维坐标(x,y)(x,y),就变成了(x,y,w)(x,y,w)
    • 作用:将平移变换可以用一个矩阵表示。引入齐次坐标后,平移变换就可以表示为[xyw]=[10m01n001][xy1]=[x+my+n1]\begin{bmatrix}x'\\y'\\w'\end{bmatrix} = \begin{bmatrix}1&0&m\\0&1&n\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix} = \begin{bmatrix}x+m\\y+n\\1\end{bmatrix}。并且加入齐次坐标以后,还可以加入齐次坐标后,ww还可以区分此坐标表示的是点还是向量。
      • 二维中的点:(x,y,1)(x,y,1)
      • 二维中的向量:(x,y,0)(x,y,0) 注:结合上方的平移矩阵来看,ww为1时,结果为(x+m,y+n,1)(x+m,y+n,1);ww为0时,结果为(x,y,0)(x,y,0)。这里符合向量的性质:平移一个向量,向量不变,因为向量=方向+长度,平移向量不会影响其方向和长度,因此w=1w=1表示点,w=0w=0表示向量。此外,也符合点和向量通过加减操作转变成另一个点或向量。
  • 仿射变换:一个线性变换加上一个平移变换
    • 矩阵形式:[xy]=[abcd][xy]+[mn] \begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}a & b \\ c & d \end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix}+\begin{bmatrix}m\\n\end{bmatrix}

    • 加入坐标:[xyw]=[abmcdn001][xy1]=[x+my+n1]\begin{bmatrix}x'\\y'\\w'\end{bmatrix} = \begin{bmatrix}a&b&m\\c&d&n\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix} = \begin{bmatrix}x+m\\y+n\\1\end{bmatrix}。 可以发现,加入齐次坐标后的变换矩阵的特性:矩阵的最后一行永远是[001]\begin{bmatrix}0&0&1\end{bmatrix},代表平移的部分是除最后一行的最后一列[mn]\begin{bmatrix}m\\n\end{bmatrix},其他部分则是原来的线性变换矩阵[abcd]\begin{bmatrix}a & b \\ c & d \end{bmatrix}

  • 组合变换
    前面提到的变换都是简单的单一变换,假设我们现在需要将一个图片同时进行平移和旋转两个操作,那么这个复杂一点的变换该如何进行表示呢?

    这个变换包括两个简单变换旋转(本文中的旋转都是指绕原点旋转)和平移。通过下图,我们可以发现变换的顺序带来的影响,分别是先平移再旋转和先旋转再平移。
    通过上图,我们可以得出:
    • 一个复杂的变换可以由多个简单的变换组成。

    • 变换的顺序是很重要的,和矩阵乘法一样,顺序不同,得到的结果也不尽相同。 两中变换的矩阵形式分别是:

    • 平移再旋转:[cos(45)sin(45)0sin(45)cos(45)0001][101010001][xy1]\begin{bmatrix}cos(45^{\circ})&-sin(45^{\circ})&0\\sin(45^{\circ})&cos(45^{\circ})&0\\0&0&1\end{bmatrix}\begin{bmatrix}1&0&1\\0&1&0\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}

    • 旋转再平移:[101010001][cos(45)sin(45)0sin(45)cos(45)0001][xy1]\begin{bmatrix}1&0&1\\0&1&0\\0&0&1\end{bmatrix}\begin{bmatrix}cos(45^{\circ})&-sin(45^{\circ})&0\\sin(45^{\circ})&cos(45^{\circ})&0\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}
      根据这两个矩阵,我们可以发现变换的顺序和对应变换矩阵相乘的顺序是相反的,同时也可以发现变换矩阵一直是3×33\times 3的矩阵。根据结合律,将前面所有的变换矩阵先进行相乘可以得到一个3×33\times 3的矩阵。这也表示我们只使用一个3×33\times 3的矩阵就可以表示出一个很复杂的变换。同理,我们也可以将一个复杂的变换拆解成多个简单的变换去实现。

4. 三维变换

  • 三维空间中的齐次坐标

    • 点:(x,y,z,1)(x,y,z,1)

    • 向量:(x,y,z,0)(x,y,z,0)

    • 仿射变换:[xyz1]=[abctxdeftyghitz0001][xyz1]\begin{bmatrix}x' \\ y' \\ z' \\ 1\end{bmatrix}=\begin{bmatrix} a & b & c & t_x \\ d & e & f & t_y \\ g & h & i & t_z \\ 0 & 0 & 0 & 1 \end{bmatrix}\begin{bmatrix}x \\ y \\ z \\ 1\end{bmatrix}

    根据上方的几个式子,我们可以发现三维空间中的齐次坐标和仿射变换的矩阵形式与二维空间中的表示形式基本一致,特性是相同的。

  • 旋转变换
    三维空间的最简单的旋转就是按照三条轴进行旋转

    由上图可知,绕哪一条轴旋转时,那条轴的坐标不变,另外两条轴形成一个二维坐标系再采用旋转矩阵,但是我们会发现只有绕 yy 轴旋转时,旋转的角度其实不是 α\alpha,而是α-\alpha。这是因为xz=y\vec{x}\vec{z} = -\vec{y},而 zx\vec{z}\vec{x} 才等于 y\vec{y}。将一个变量绕yy轴顺时针旋转 α\alpha,这个α\alpha是相对于zoxzox坐标系而言的,在xozxoz坐标系中就是逆时针旋转α\alpha,而我们想要的就是xozxoz坐标系,因此这里要旋转α-\alpha

    • 欧拉角
      • 定义:将任意一个3D旋转变换分解成三个分别绕xyzxyz轴的简单旋转,这三个轴旋转变换的角度便是欧拉角。
    • 罗德里格斯旋转公式: nn是任意一条轴(需过原心),α\alpha是要旋转的角度,II是被旋转的向量
  • MVP变换

    • 定义:MVP变换可以抽象成拍照的过程:1、摆好人和物;2、调整摄像头的角度、3、按下快门。这三步分别表示:模型变换(M)、视图变换(V)和投影变换(P)。

    注: 模型变换就包括在三维空间中对物体进行线性变换和仿射变换。

  • 视图变换 View/Camera transiformation

    • 相机的定义:由位置、朝向和向上方向组成,同时假设相机和所有物体一起进行相同的运动,那么拍出来的画面一定是一样,因此为了简化操作,约定将相机固定在原心位置,同时朝向z-z轴方向,yy轴方向向上。
    • 视图矩阵

      • 作用:将任意一个相机转换为我们约定的标准相机(在原心位置,朝向z-z轴方向,yy轴方向向上)。
      • 推导思想:
        假设一个相机在点ee上,朝向 g\vec g 方向,t\vec t 方向向上,将这样一个相机变换为标准相机可以分为这几步:1.移动至原点、2.将朝向旋转至z-z方向、 3、将向上方向旋转至 yy 方向、4、g×t\vec g \times \vec t方向自然是 x\vec x 方向。
      • 矩阵形式:
        由上所述,视图变换可以分成先平移再旋转的变换,记为:Mview=RviewTviewM_{view} = R_{view}T_{view}。平移矩阵很简单,写为[001xe010ye001ze0001]\begin{bmatrix}0&0&1&-x_e\\0&1&0&-y_e\\0&0&1&-z_e\\0&0&0&1\end{bmatrix},然而旋转矩阵并不好写,这里我们可以通过逆向思维先求出从标准坐标系旋转至目标相机的旋转矩阵,即从(x,y,z)(\vec x,\vec y,\vec z)旋转至(g×t,t,g)(\vec g \times \vec t,\vec t,\vec -g)。由矩阵的逆的性质NN1=ENN^{-1}=E 可知,NN变换和N1N^{-1}变换是两个相反的变换。由此可知Rview1=[xg×txtxg0yg×tytyg0zg×tztzg00001]R_{view}^{-1} = \begin{bmatrix}x_{\vec g\times \vec t}&x_{\vec t}&x_{-\vec g}&0\\y_{\vec g\times \vec t}&y_{\vec t}&y_{-\vec g}&0\\z_{\vec g\times \vec t}&z_{\vec t}&z_{-\vec g}&0\\0&0&0&1 \end{bmatrix}Rview=[xg×tyg×tzg×t0xtytzt0xgygzg00001]R_{view} = \begin{bmatrix}x_{\vec g\times \vec t}&y_{\vec g\times \vec t}&z_{\vec g\times \vec t}&0\\x_{\vec t}&y_{\vec t}&z_{\vec t}&0\\x_{-\vec g}&y_{-\vec g}&z_{-\vec g}&0\\0&0&0&1 \end{bmatrix}

      注:此处的Rview1R_{view}^{-1}矩阵并不是之前提及的旋转矩阵,而是基变换矩阵,相机的旋转可以理解为坐标系的转换。原本坐标系的转换会改变空间内所有物体的位置表示,那么就像之前提到的,为了物体和相机的相对位置不变(位置表示),物体也需要进行一次跟相机相同的变换。另一种理解是,物体位置保持不变,我们先变换相机空间的位置,然后再将所有物体进行一次相同的变换以保持同步。 推导过程: 基变换

  • 投影变换 Projection transiformation

    • 正交投影

      • 性质:没有近大远小的现象。
      • 数学理解:假设有一个空间和一个相机(点),那么从这个相机看相这个空间,相机看到的视野范围就会是一个四棱锥,我们再取一个四棱锥上的一个面作为屏幕,将相机放在无限远同时屏幕又离四棱锥的底面足够近,那么屏幕和四棱锥底面构成的立体图形就近似与长方体,此时再将空间内的物体投影至屏幕。
      • 投影过程:1、在空间中定义一个立方体(视野范围),这个立方体有六个参数上下t,b(t,b)、左右l,r(l,r)和远近f,n(f,n),分别是这个立方体在xyzxyz三条轴上的最大最小值;2、将立方体的中心平移至原心;3、将立方体缩放成一个[1,1]3[-1,1]^3的正方体(为了方便后续操作的标准规定)。

      注:由于我们使用的是右手坐标系,这里的远近是相对与z-z轴方向的,所以在数值表示上,越远数值越小。

      • 正交矩阵:先平移再缩放。

        Mortho=[2rl00002tb00002nf00001][100r+l2010t+b2001f+n20001]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}\begin{bmatrix}1&0&0&-\frac{r+l}{2}\\0&1&0&-\frac{t+b}{2}\\0&0&1&-\frac{f+n}{2}\\0&0&0&1 \end{bmatrix}

        注:nfn-f 是因为之前提到的, 在数值上n>fn>f;缩放至 2,是因为正方体边长为 2。

    • 透视投影

      • 性质:近大远小,平行线不再平行。
      • 数学理解:和正交投影相似,不同的是相机不再是无限远了,同时屏幕和四棱锥底面构成的立体图形是一个四棱台,远处的物体投影时,会被压缩,进而导致近大远小。
      • 投影过程:1、在空间中定义一个四棱台(视野范围),这里只需要两个参数远近f,n(f,n)来标识棱台上下面的位置;2、将四棱台向中心轴方向压缩成一个立方体;3、对立方体做一次正交投影。
      • 投影矩阵:根据投影过程,可知投影矩阵是先压缩再正交投影,正交投影我们已经知道了,那么现在就需要求出压缩的矩阵。
        • 推导过程:首先我们需要先确定空间中哪些点不变哪些点会变,由于是沿中心轴方向压缩,所以中心轴上的点不变,且近平面和远平面上的点的zz不变,空间中其他的点都不知道。确定之后,我们任取空间中的一点(x,y,z)(x,y,z),将此点连接至原点与近平面相交于(x,y,z)(x',y',z'),在zyzy平面上可以发现,yy=zn=>y=nzy\frac{y}{y'}=\frac{z}{n}=>y' = \frac{n}{z}y(相似三角形),同理x=nzxx' = \frac{n}{z}x。那么我们就知道了压缩后 [xyz1]\begin{bmatrix}x\\y\\z\\1\end{bmatrix}变为[nx/zny/z?1]=[nxny?(z?=?)z]\begin{bmatrix}nx/z\\ny/z\\?\\1\end{bmatrix} = \begin{bmatrix}nx\\ny\\?(z?=?)\\z\end{bmatrix}
      • 演算过程:经过上一步的推导,我们已经知道了x,yx,y是如何变化的,假设MM4×44\times 4压缩矩阵,那么 Mpersp>ortho[xyz1]=[nxny?z]M_{persp->ortho}\begin{bmatrix}x\\y\\z\\1\end{bmatrix}=\begin{bmatrix}nx\\ny\\?\\z\end{bmatrix},根据矩阵相乘的规律可知 Mpersp>ortho=[n0000n00????0010]M_{persp->ortho}=\begin{bmatrix}n&0&0&0\\0&n&0&0\\?&?&?&?\\0&0&1&0 \end{bmatrix},接下来只需要演算出第三列的??就可以得到完整的压缩矩阵。首先找出两个始终不变的向量,分别是近平面和远平面上的向量(x,y,n)(x,y,n)(x,y,f)(x,y,f)。将(x,y,n)(x,y,n)带入[xyz1]\begin{bmatrix}x\\y\\z\\1\end{bmatrix},得[xyn1]==[nxnyn2n]\begin{bmatrix}x\\y\\n\\1\end{bmatrix}==\begin{bmatrix}nx\\ny\\n^2\\n\end{bmatrix},由此可知当z=nz=n时,?=n2?=n^2,且与x,yx,y无关,故可设矩阵第三行为(0,0,A,B)(0,0,A,B),代入可得An+B=n2An+B=n^2。同理将(x,y,f)(x,y,f)代入,可得Af+B=f2Af+B=f^2。联立方程得An+B=n2Af+B=f2}=>A=n+fB=nf\left.\begin{aligned}An+B=n^2\\Af+B=f^2\end{aligned}\right\}=>\begin{aligned}A=n+f\\B=-nf\end{aligned}。故,Mpersp>ortho=[n0000n0000n+fnf0010]M_{persp->ortho}=\begin{bmatrix}n&0&0&0\\0&n&0&0\\0&0&n+f&-nf\\0&0&1&0 \end{bmatrix}
      • 投影矩阵:先进行压缩再执行一次正交投影 Mpersp=MorthoMpersp>orthoM_{persp}=M_{ortho}M_{persp->ortho},因此Mpersp=[2rl00002tb00002nf00001][100r+l2010t+b2001f+n20001][n0000n0000n+fnf0010]M_{persp} = \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}\begin{bmatrix}1&0&0&-\frac{r+l}{2}\\0&1&0&-\frac{t+b}{2}\\0&0&1&-\frac{f+n}{2}\\0&0&0&1 \end{bmatrix}\begin{bmatrix}n&0&0&0\\0&n&0&0\\0&0&n+f&-nf\\0&0&1&0 \end{bmatrix}。 投影矩阵补充说明:由于投影矩阵应用的相机视角是一个四棱锥,因此在正交投影中的l,r,t,b,n,fl,r,t,b,n,f六个参数是定义长方体的,并不能直接拿到投影矩阵中使用。我们同样也可以用fovY,aspectratio,n,ffovY,aspect ratio,n,f四参数来表示投影矩阵中的四棱台,分别是垂直可视角度、宽高比(近平面)、近平面的距离zz、远平面的距离zz。接下来,只要将l,r,t,bl,r,t,b分别用这四个参数进行表示,就可以