【GAMES101】课堂笔记4--变换(模型、视图、投影)

前言

本文为GAMES101现代计算机图形学入门 的学习笔记系列。

我们的系列笔记将分为两部分:

  1. 课堂笔记
  2. 作业

原课程为2020年2月闫令琪所教授的 GAMES101 现代计算机图形学入门

课程主页:https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html
(幻灯片和课程录像均在此处)

课程共计22节。作业共计8次。

针对人群:计算机图形学入门新手

教材
Steve Marschner and Peter Shirley的"Fundamentals of Computer Graphics"
第三版或更新版本。目前无官方中文版。
民间翻译:https://www.stubbornhuang.com/1812/

笔记目录


正文

2022-6-5

本节课内容:

  • 3D变换(续)
  • 视图变换
  • 投影变换
    – 正交投影
    – 透视投影

3D变换(续)

绕xyz轴旋转(欧拉角)

绕x y z轴旋转
在这里插入图片描述
可见几乎与2D旋转一致。只是绕哪个轴第几行就为1。例如绕x轴则第一行为[1 0 0]
这是因为绕x轴旋转的时候,要保证x坐标不变

注意绕Y轴,负号位置在左下角。

这样将绕坐标轴旋转复合起来,就可以得到任何的旋转。
在这里插入图片描述

复合起来的三个角度,叫做欧拉角。它可以应用于飞机的转角上,例如
在这里插入图片描述
三个角度在航空领域也叫roll pitch yaw

绕任意轴旋转(Rodrigues’ Law)

在这里插入图片描述
其中轴是n=(nx ny nz) 转角是alpha

这里默认轴过原点

如果轴不过原点,就先把轴平移到原点,再旋转,再平移回去

其中那个矩阵N恰好就是向量n的dual matrix(叉乘的时候将前面的向量写成的那个矩阵)

视图变换(相机变换)

拍照有两步:

  1. 把物体摆好位置(模型变换)
  2. 相机找好视角(视图变换)

所以视图变换就是摆放相机

相机标准位置的规定

如何摆放相机?需要定义三个参数:

  1. 位置 position: e ⃗ \vec e e
  2. 看向哪 look-at: g ^ \hat g g^ (gaze)
  3. 头顶在哪 up direction: t ^ \hat t t^ (top)

up direction总与look-at相垂直
在这里插入图片描述

我们可以约定一个相机的标准位置,规定:

  1. 在原点
  2. 沿着-z轴方向看
  3. 头顶沿着y轴方向

将相机变换到标准位置

如果相机不处于标准位置,我们通常将其先变换到标准位置:

例如目前是
在这里插入图片描述
希望变换后是
在这里插入图片描述
需要经过如下步骤:

  1. 平移到原点
  2. 旋转g到-z方向
  3. 旋转t到y方向
  4. 旋转 g ^ × t ^ \hat g \times \hat t g^×t^ 到x方向

将其写为变换矩阵

  1. 先平移
    在这里插入图片描述
  2. 再旋转

如何将任意方向的g旋转到-z=(0, 0, -1)方向呢?
直接写是不好找到旋转矩阵的,但是我们可以找到其逆变换:从(0,0,-1)旋转到任意方向g,然后再对矩阵取逆就可以了。

同理,对t的旋转和对 g ^ × t ^ \hat g \times \hat t g^×t^ 的旋转都是如此。我们可以直接写到一起,得到旋转矩阵的逆矩阵:
在这里插入图片描述
可见该矩阵的第一列恰好就是将 x轴旋转到 g ^ × t ^ \hat g \times \hat t g^×t^方向,
第二列恰好就是将y轴旋转到t方向
第三列恰好就是将z轴旋转到-g方向(相当于将-z轴旋转到g方向)

再对它取逆即可(由于旋转矩阵是正交阵,取逆恰好就是取转置)
在这里插入图片描述

模型视图变换

由于模型变换是对物体进行变换
而视图变换虽然是对相机进行变换,但是也是施加到物体上的
所以两者可以合起来,称为模型视图变换(ModelView)

投影变换

投影分两种:正交投影和透视投影

如图所示
在这里插入图片描述

正交投影

  1. 将相机放到标准位置(位于原点,y轴为上,看向-z)
  2. 丢掉z坐标
  3. 把x 和y坐标都缩放到[-1, 1]区间

更简单的做法(实际做法):

  1. 将物体中心平移到原点
  2. 所有坐标缩放到[-1, 1] (称为标准立方体cuboid or canonical cube)

NOTES: x轴代表的是左右 y轴代表的是上下 z轴代表的是远近

所以按照坐标值来说 左<右,这样我们就能分清左右 下<上,这样我们就能分清上下 远<近,这样我们就能分清远近

值得一提的是,远近和我们直观上的区分是相反的。我们直观上以为越远距离越大,z坐标越大。实际上因为我们是沿着-z轴看去的,所以越远z坐标越小。

另外值得一提的是,OpenGL中则恰好相反,它规定看向z轴,于是越远z坐标越大,但是这样违背了右手系的规定。

于是我们按照这种做法,将一个x坐标范围[l, r] (left to right), y坐标范围[b, t] (bottom to top) ,z坐标范围[f, n] (far to near)的长方体正交投影到一个标准立方体

在这里插入图片描述

矩阵解释:从右向左乘。
右边的矩阵是平移矩阵:先找到中点,因此除以2,再平移。
左边的矩阵是缩放矩阵:因为缩放到[-1, 1], 因此缩放系数分子为2,分母就是原长度。

透视投影

在透视投影满足了近大远小的效果。原本的平行线投影后不一定平行。

我们要在一块固定大小的二维的屏幕上显示3D的物体,要呈现出近大远小的效果,于是就需要将透视投影转换为正交投影。然后再做正交投影,就得到了在2D固定大小屏幕上的显示。

关键是如何将透视投影转换为正交投影?

透视投影转换为正交投影

在这里插入图片描述
如图,就是要将左边的棱台挤压成右边的标准立方体。关键在于如何找到变换矩阵

我们还是用待定系数法。

我们观察发现变换前后满足以下条件:

  1. 近平面和远平面上的z坐标不变
  2. 近平面n不做任何变换,即n平面上的任何点坐标不变
  3. 远平面的点虽然变换了,但其中心点坐标变换后与变换前完全一样

这里特别要注意第一条:只有远平面和近平面上的z坐标是不变的,其他平面是不满足这个条件的。

下面我们用这三个条件来待定系数。我们假设变换矩阵为M

于是变换写成
M ( x y z 1 ) = ( x ′ y ′ z ′ 1 ) M\begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix}= \begin{pmatrix} x^\prime \\ y^\prime \\ z^\prime \\ 1 \end{pmatrix} Mxyz1=xyz1

我们的目标就是根据待定系数法算出M

下面开始推导

取任意一条棱,例如最上边那条棱。可以构建出一个相似三角形

在这里插入图片描述
利用相似三角形,得到变换前后的坐标关系满足

y ′ = n z y y'=\frac{n}{z} y y=zny

同理得到 x ′ = n z x x'=\frac{n}{z} x x=znx

将x’和y’带入进去,于是这个变换暂时可以写成

M ( x y z 1 ) = ( n x / z n y / z u n k o w n 1 ) M\begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix}= \begin{pmatrix} nx/z \\ ny/z \\ unkown \\ 1 \end{pmatrix} Mxyz1=nx/zny/zunkown1
由于根据规定(见上节课),点的坐标值可以随意乘以一个系数,所以我们不妨同时乘以z,写成 M ( x y z 1 ) = ( n x n y u n k o w n z ) M\begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix}= \begin{pmatrix} nx \\ ny \\ unkown \\ z \end{pmatrix} Mxyz1=nxnyunkownz

M是一个4x4的矩阵,也就是我们要带求解的

我们观察到:

根据矩阵向量乘法,结果的每一个数都是矩阵的每一行乘以右侧向量。因此我们可以一行一行地待定求解矩阵 也就是把矩阵分解为 M = ( r ⃗ 1 r ⃗ 2 r ⃗ 3 r ⃗ 4 ) M=\begin{pmatrix} \vec r_1 \\ \vec r_2 \\ \vec r_3 \\ \vec r_4 \end{pmatrix} M=r 1r 2r 3r 4

因此第一行乘以(x y z 1) 得到 nx 第二行乘以(x y z 1) 得到 ny 第四行乘以(x y z 1) 得到 z

写成方程就是 r ⃗ 1 ⋅ ( x y z 1 ) = n x \vec r_1 \cdot \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} =nx r 1xyz1=nx

于是很容易就能求出来, r ⃗ 1 = ( n 0 0 0 ) \vec r_1= \begin{pmatrix} n & 0 & 0 &0 \end{pmatrix} r 1=(n000)

同理, r ⃗ 2 = ( 0 n 0 0 ) \vec r_2=\begin{pmatrix} 0 & n & 0 &0 \end{pmatrix} r 2=(0n00)

r ⃗ 4 = ( 0 0 1 0 ) \vec r_4 =\begin{pmatrix} 0 & 0 & 1 &0 \end{pmatrix} r 4=(0010)

所以矩阵M就是 ( n 0 0 0 0 n 0 0 ? ? ? ? 0 0 1 0 ) \begin{pmatrix} n & 0 & 0 & 0\\ 0 & n & 0 &0 \\ ? & ? & ? &? \\ 0 & 0 & 1 &0 \end{pmatrix} n0?00n?000?100?0

于是我们就只剩下第三行没有确定了。

如何确定第三行呢?

我们利用如下条件:

  1. 近平面上所有点的坐标不变
  2. 远平面上中心点的坐标不变

我们先说近平面。

假设近平面任意一点坐标为 ( x y n 1 ) \begin{pmatrix} x \\ y \\ n \\ 1 \end{pmatrix} xyn1
这是假设了在该平面上的坐标为x y, 且z轴位于n(near)平面上,也就是远近距离为n。

该点经过M的变换以后坐标不变,也就是

M ( x y n 1 ) = ( x y n 1 ) M\begin{pmatrix} x \\ y \\ n \\ 1 \end{pmatrix}= \begin{pmatrix} x \\ y \\ n \\ 1 \end{pmatrix} Mxyn1=xyn1

但是这样做,M不就是单位阵了嘛?显然这样是没有意义的。但是利用同时乘以一个系数表示同一点的性质,我们可以把坐标同时乘以n。于是就写成 M ( x y n 1 ) = ( n x n y n 2 n ) M\begin{pmatrix} x \\ y \\ n \\ 1 \end{pmatrix}= \begin{pmatrix} nx \\ ny \\ n^2 \\ n \end{pmatrix} Mxyn1=nxnyn2n

我们再次待定系数。这里就不写过程了。我们直接观察发现,第三行乘以n得到n^2。而这意味着:第三行把x和y给筛掉了。所以我们可以把第一个数和第二个数写为0。第三个数和第四个数仍然待定,记为A和B。

在这里插入图片描述

于是我们只剩下第三行最后两个数没有确定了。

同时,我们还能用上面的式子写出一个方程 A n + B = n 2 An+B=n^2 An+B=n2

然后再利用远平面中心点的那个条件。 远平面的中心点可以写为 ( 0 0 f 1 ) \begin{pmatrix} 0 \\ 0 \\ f \\ 1 \end{pmatrix} 00f1 其中由于是中心点,所以x y坐标都是0。由于远近距离是f,所以第三个坐标是f

它经过变换以后,也是不变的。 M ( 0 0 f 1 ) = ( 0 0 f 1 ) M\begin{pmatrix} 0 \\ 0 \\ f \\ 1 \end{pmatrix}= \begin{pmatrix} 0 \\ 0 \\ f \\ 1 \end{pmatrix} M00f1=00f1

故技重施,将右端所有坐标同时乘以f M ( 0 0 f 1 ) = ( 0 0 f 2 f ) M\begin{pmatrix} 0 \\ 0 \\ f \\ 1 \end{pmatrix}= \begin{pmatrix} 0 \\ 0 \\ f^2 \\ f \end{pmatrix} M00f1=00f2f

于是我们就能写出第三行的另一个方程 ( 0 0 A B ) ( 0 0 f 1 ) = f 2 \begin{pmatrix} 0 & 0 & A & B \end{pmatrix}\begin{pmatrix} 0 \\ 0 \\ f \\ 1 \end{pmatrix}= f^2 \\ (00AB)00f1=f2

也就是

联立两个式子 A n + B = n 2 A f + B = f 2 An+B=n^2\\ Af+B=f^2 An+B=n2Af+B=f2 就能够解出A和B。

A = n + f B = − n f A=n+f\\ B=-nf A=n+fB=nf

于是我们就解出来了整个M矩阵:

M = ( n 0 0 0 0 n 0 0 0 0 n + f − n f 0 0 1 0 ) M=\begin{pmatrix} n & 0 & 0 & 0\\ 0 & n & 0 &0 \\ 0 & 0 & n+f &-nf \\ 0 & 0 & 1 &0 \end{pmatrix} M=n0000n0000n+f100nf0

推导到此结束。

接下来,只要再施加正交投影,就得到了3D到2D固定屏幕上的变换。本节课完。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值