GAMES101 Lecture 03 & Lecture 04 Transform

Lecture 03 & Lecture 04 Transform

为什么要变换

  • Modeling
  • Viewing

2D变换

  • Scale

    缩放

    缩放矩阵

    \[\begin{bmatrix} x'\\ y' \end{bmatrix} = \begin{bmatrix} s_x & 0\\ 0 & s_y \end{bmatrix} \begin{bmatrix} x\\ y \end{bmatrix} \]

    \(s_x\)\(s_y\)为缩放系数

    \(s_x=-1,s_y = 1\),则会关于y轴对称(Reflection)

  • Shear

    切变

垂直坐标不变,水平坐标向右平移了\(ay\)

\[\begin{bmatrix} x'\\ y'\ \end{bmatrix} = \begin{bmatrix} 1 & a\\ 0 & 1 \end{bmatrix} \begin{bmatrix} x\\ y \end{bmatrix} \]

上图的切变矩阵

  • Rotate

    旋转

    (默认绕原点逆时针旋转)

    旋转矩阵的推导

\[R_\theta = \begin{bmatrix} \cos\theta & -\sin\theta\\ \sin\theta & \cos\theta \end{bmatrix} \]

绕原点逆时针旋转\(\theta\)角度的旋转矩阵

若要旋转\(-\theta\)角度,则\(R_{-\theta} = \begin{bmatrix}\cos\theta & \sin\theta\\-\sin\theta&\cos\theta\end{bmatrix}=R_{\theta}^{T}=R_{\theta}^{-1}(从定义来看)\\(若一个矩阵的逆等于它的转置,则称其为正交矩阵)\)

  • Linear Transforms 线性变换

    \[x' = ax + by\\ y' = cx + dy\\ \begin{bmatrix} x'\\ y' \end{bmatrix} = \begin{bmatrix} a & b\\ c & d \end{bmatrix} \begin{bmatrix} x\\ y \end{bmatrix}\\ 我们需要用一个相同维度的矩阵乘于向量 x' = Mx \]

齐次坐标

  • Translation 平移变换

\[\begin{bmatrix} x'\\ y' \end{bmatrix} = \begin{bmatrix} a & b\\ c & d \end{bmatrix} \begin{bmatrix} x\\ y \end{bmatrix} + \begin{bmatrix} t_x\\ t_y \end{bmatrix}\\ \]

可见平移操作不是线性变换(是仿射变换),为了不让平移操作成为特殊情况,所以引入齐次坐标

  • 加入第三个维度

    • 2D point \(=(x,y,1)^T\)
    • 2D vector \(=(x,y,0)^T\)

    \[\begin{pmatrix} x'\\ y'\\ w' \end{pmatrix} = \begin{pmatrix} 1 & 0 & t_x\\ 0 & 1 & t_y\\ 0 & 0 & 1 \end{pmatrix} \cdot \begin{pmatrix} x\\ y\\ 1 \end{pmatrix} = \begin{pmatrix} x+t_x\\ y+t_y\\ 1 \end{pmatrix} \]

    于是可以将平移变换变为线性变换

    • 关于点与向量第三维度差别的理解

      • 向量具有平移不变性,所以向量第三维度为0是为了维护平移不变性

      • \[向量+向量=向量\\ 点-点=向量\\ 点+向量=点(一个点在一向量方向上移动)\\ 点+点=??(无意义)\\ 在齐次坐标中,我们定义点+点=这两点的中点\\ \begin{pmatrix} x\\ y\\ w \end{pmatrix} = \begin{pmatrix} x/w\\ y/w\\ 1 \end{pmatrix} \]

  • 齐次坐标变换矩阵

    \[\begin{pmatrix} x'\\ y'\\ 1 \end{pmatrix} = \begin{pmatrix} a & b & t_x\\ c & d & t_y\\ 0 & 0 & 1 \end{pmatrix} \cdot \begin{pmatrix} x\\ y\\ 1 \end{pmatrix} \]

    该矩阵有几个特点

    • 左上角\(abcd\)为线性变换系数
    • 右上角\(t_x,t_y\)为平移系数
    • 在表示二维情况下仿射变换时最后一行为\(001(为001的情况如投影变换)\)
  • 逆变换

    将A变换到B后,再将B变换回A称为逆变换,在数学上,逆变换表现为乘于原变换矩阵的逆矩阵

组合变换

组合变换需按照RST顺序(Rotate Scale Translate),否则会发生畸变

在数学上,表现为矩阵相乘的顺序不同意义不同

  • 在OpenGL中,向量为列向量,按一下顺序相乘

    \[T\cdot S\cdot R \begin{pmatrix} x\\ y\\ 1 \end{pmatrix}\\ 若为某个点x连续应用矩阵A_1、A_2、A_3、...\\ A_N(...A_2(A_1(x)))=A_n...A_2\cdot A_1\cdot \begin{pmatrix} x\\ y\\ 1 \end{pmatrix}\\ (矩阵的结合律) \]

  • 在DirectX中,向量为行向量 ,按以下顺序相乘

    \[{\begin{pmatrix} x\\ y\\ 1 \end{pmatrix} R\cdot S\cdot T}\\ 若为某个点x连续应用矩阵A_1、A_2、A_3、...\\ (((x)A_1)A_2...)A_N= \begin{pmatrix} x\\ y\\ 1 \end{pmatrix}A_1\cdot A_2 ... A_n \\ (矩阵的结合律) \]

以任意一点c为中心变换

  1. 先将所有点都移动\(-c\)(向量)
  2. 再进行旋转
  3. 最后将所有点移动\(c\)(向量)

3D变换

类比2D变换

  • 3D point \(=(x,y,z,1)^T\)

  • 3D vector \(=(x,y,z,0)^T\)

  • \((x,y,z,w) = (x/w,y/w,z/w,1) \ (w!=0)\)

  • \(4\times4\)矩阵表示仿射变换

    \[\begin{pmatrix} x'\\ y'\\ z'\\ 1 \end{pmatrix} = \begin{pmatrix} a & b & c & t_x\\ d & e & f & t_y\\ g & h & i & t_z\\ 0 & 0 & 0 & 1 \end{pmatrix} \cdot \begin{pmatrix} x\\ y\\ z\\ 1 \end{pmatrix} \]

    • 左上角\(3\times3\) 矩阵为线性变换矩阵
    • 右侧\(3\times1\)矩阵为平移矩阵
    • 最下面一行为\(0001\)(仿射变换时)
  • \(x、y、z\)轴旋转

    \[R_x(\alpha)= \begin{pmatrix} 1 & 0 & 0 & 0\\ 0 & \cos\alpha & -\sin\alpha & 0\\ 0 & \sin\alpha & \cos\alpha & 0\\ 0 & 0 & 0 & 1 \end{pmatrix}\\\\ R_y(\alpha)= \begin{pmatrix} \cos\alpha & 0 & \sin\alpha & 0\\ 0 & 1 & 0 & 0\\ -\sin\alpha & 0 & \cos\alpha & 0\\ 0 & 0 & 0 & 1 \end{pmatrix}\\ 在右手坐标系中,z\times x得到y\\ 所以绕y轴旋转的矩阵与另外两个不太一样\\ 左手系同样也有不同的轴\\\\ R_z(\alpha)= \begin{pmatrix} \cos\alpha & -\sin\alpha & 0 & 0\\ \sin\alpha & \cos\alpha & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{pmatrix} \]

    于是可以将复杂的旋转分解成绕\(x、y、z\)轴的旋转(也被称为欧拉角)

    \(R_{xyz}(\alpha,\beta,\gamma)=R_x(\alpha)R_y(\beta)R_z(\gamma)\)

    可以以飞机的翻滚、俯仰、偏航来理解

    旋转矩阵并不适合插值,可以用四元数

    \[Rodrigues' Rotation Formula(罗德里格斯旋转公式)\\ 表示空间中任一向量I,沿任一旋转轴旋转角度\alpha后,得到的结果 R(n,\alpha) = \cos(\alpha)I + (1-\cos(\alpha))nn^T + \sin(\alpha) \begin{pmatrix} 0 & -n_z & n_y\\ n_z & 0 & -n_x\\ -n_y & n_x & 0 \end{pmatrix}\\ n为过原点轴,公式中矩阵为一个向量的伴随矩阵\\ (若我们要绕一个非过原点轴旋转,可以视为先将该轴平移到原点,旋转,再平移回去) \]

View Transfomation

View(视图)/Camera transfomation

  • Model transfomation

    将顶点坐标从模型空间变换到世界空间

  • View transfomation

    将顶点坐标从世界空间变换到相机空间

定义相机处于原点,上方向为\(y\)轴, 看向\(z\)轴负向(OpenGL等右手系,DirectX为左手系,看向\(z\) 轴正向)

相当于以相机为中心建立了一个坐标系(相机空间)

通过\(M_{view}\)矩阵变换相机\(M_{view}=R_{view}T_{view}\)(右手系从右往左乘)

  • \(\vec e\)平移到原点(世界空间原点)

    \(T_{view}= \begin{bmatrix} 1 & 0 & 0 & -x_e\\ 1 & 0 & 0 & -ye\\ 1 & 0 & 0 & -z_e\\ 0 & 0 & 0 & 1 \end{bmatrix}\)

  • \(g\)旋转至\(-Z\)

    \(t\)旋转至\(Y\)

    \((g\times t)\)旋转至\(X\)

    (不好写)

  • 反过来旋转

将$X$旋转至$(g\times t)$

将$Y$旋转至$t$

将$Z$旋转至$-g$

$R_{view}^{-1}=\begin{bmatrix}x_{\widehat g \times \widehat t} & x_t & x_{-g} & 0\\y_{\widehat g \times \widehat t} & y_t & y_{-g} & 0\\z_{\widehat g \times \widehat t} & z_t & z_{-g} & 0\\0 & 0 & 0 & 1\end{bmatrix}$

$R_{view}=\begin{bmatrix}x_{\widehat g \times \widehat t} & y_{\widehat g \times \widehat t} & z_{\widehat g \times \widehat t} & 0\\x_t & y_t & z_t & 0\\x_{-g} & y_{-g} & z_{-g} & 0\\0 & 0 & 0 & 1\end{bmatrix}$

求得逆变换,再求逆得到我们要的旋转矩阵,

而旋转矩阵又是正交矩阵,所以对其转置则为其逆矩阵

配合前面求的\(T_{view}\)则可求得\(M_{view}\),完成视图变换

  • Projection transfomation

    将顶点坐标从相机空间变换到裁剪空间

Projection(投影) transfomation

Orthographic(正交) projection

并不正式的做法(方便理解)
  • 将相机置于原点,看向\(-Z\)轴,上方向为\(Y\)

  • 去掉\(Z\)坐标

  • 将结果矩形框平移和缩放至\([-1,1]^2\)

    为什么是\([-1,1]\)

    这是一个约定俗成的做法,方便后续的计算

正式的做法

  • 定义一个立方体,将这个立方体映射到canonical(正则、规范、标准) cube\([-1,1]^3\)

    • 这里深度范围视api而定

    • 这里的立方体长宽高依据我们要渲染的范围自己决定

  • 先进行平移,再进行缩放

    \[M_{ortho} = \begin{bmatrix} 2\over{r-l} & 0 & 0 & 0\\ 0 & 2\over{t-b} & 0 & 0\\ 0 & 0 & 2\over{n-f} & 0\\ 0 & 0 & 0 & 0 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & -{{r+l}\over2}\\ 0 & 1 & 0 & -{{t+b}\over2}\\ 0 & 0 & 1 & -{{n+f}\over2}\\ 0 & 0 & 0 & 1 \end{bmatrix} \]

  • 这里保留了深度坐标,方便用于计算遮挡

*精度上会有问题

Perspective(透视) projection

在欧氏几何中定义平行线永不相交,但在透视投影的情况下,相当于一个平面投影到另外一个平面下,这种情况就不是永不相交了

  • 定义一个视锥体(近平面、远平面)

  • 将视锥体“挤压”成长方体

    • 规定近平面永远不变,近平面上的任何点不变
    • 规定远平面上任何点的深度不变

  • 从侧面看,可以根据相似三角形算出\(y'=\frac{n}{z}y\)

  • 同理\(x'=\frac{n}{z}x\)

  • \[在齐次坐标中\\ \begin{pmatrix} x\\ y\\ z\\ 1 \end{pmatrix} => \begin{pmatrix} nx/z\\ ny/z\\ unknow\\ 1 \end{pmatrix} == \begin{pmatrix} nx\\ ny\\ still unknow\\ z \end{pmatrix}\\ 因此\\ M_{persp->ortho}^{4\times4} \begin{pmatrix} x\\ y\\ z\\ 1 \end{pmatrix} = \begin{pmatrix} nx\\ ny\\ still unknow\\ z \end{pmatrix}\\ 求解得\\ M_{persp->ortho}^{4\times4}= \begin{pmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ ? & ? & ? & ?\\ 0 & 0 & 1 & 0 \end{pmatrix}\\\\ 利用近平面上任何点不变\\ \begin{pmatrix} x\\ y\\ n\\ 1 \end{pmatrix} => \begin{pmatrix} x\\ y\\ n\\ 1 \end{pmatrix} == \begin{pmatrix} nx\\ ny\\ n^2\\ n \end{pmatrix}\\ 要使得不含x、y,则左矩阵前两个数字为0\\ \begin{pmatrix} 0 & 0 & A & B \end{pmatrix} \begin{pmatrix} x\\ y\\ n\\ 1 \end{pmatrix} =n^2\\ An+b=n^2\\ 远平面深度不变,但中心点(0,0,f,1)特殊,变换后仍不变\\ 利用远平面中心点 \begin{pmatrix} 0\\ 0\\ f\\ 1 \end{pmatrix} => \begin{pmatrix} 0\\ 0\\ f\\ 1 \end{pmatrix} == \begin{pmatrix} 0\\ 0\\ f^2\\ f \end{pmatrix} Af+B=f^2\\ 联立\\ \left\{ \begin{aligned} &An+b=n^2\\ &Af+B=f^2\\ \end{aligned} \right. \\得\\ \left\{ \begin{aligned} A&= n+f\\ B&= -nf\\ \end{aligned} \right. \]

透视矩阵

\[M_{persp->ortho}^{4\times4}= \begin{pmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & n+f & -nf\\ 0 & 0 & 1 & 0 \end{pmatrix}\\ \]

  • 对于在近平面和远平面之间的点,经过挤压变换,它们的深度被推向的远平面

    \[M_{persp->ortho}^{4\times4} \begin{pmatrix} x\\ y\\ z\\ 1 \end{pmatrix} = \begin{pmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & n+f & -nf\\ 0 & 0 & 1 & 0 \end{pmatrix} \begin{pmatrix} x\\ y\\ z\\ 1 \end{pmatrix}\\ = \begin{pmatrix} nx\\ ny\\ z(n+f)-nf\\ z \end{pmatrix}\\ = \begin{pmatrix} x/z\\ y/z\\ (n+f)-nf/z\\ 1 \end{pmatrix}\\ 即z'={(n+f)-nf\over z}\\ 则z-z'={(n+f)-nf-z^2\over z}\\ 令f(z)={(n+f)-nf-z^2}\\ 当z=n或z=f时,f(z)=0\\ 则f(z)函数图像为开口朝下的抛物线 \]

    (此处\(z\) 轴方向是右手系的原因)

    \(于是z\in(f,n),z-z'>0,即z'-z<0\\变换后的点深度小于原深度,更靠近远平面\)

    这个结论也可以用常识来理解,所有点都向着远平面压缩(离摄像机近的部分少,远的部分多),造成近大远小的现象

定义视锥体
  • FOV(field of view)垂直可视角度

  • 长宽比(aspect ratio)

    \(Aspect \ ratio = width/height\)

\(\tan{fov{Y}\over2}=\frac{t}{\lvert n\rvert}\\aspect=\frac{r}{t}\)

通过\(FOV、长宽比、近平面离摄像机距离\lvert n\rvert\)就可以计算出远近、左右、上下

posted @ 2024-03-24 11:46  Telluluu  阅读(18)  评论(0编辑  收藏  举报