Unity_Shader基础篇_4_Unity Shader入门精要

第4章 学习Shader所需的数学基础
计算机图形学之所以深奥难懂,很大原因是在于它是建立在虚拟世界上的数学模型。数学渗透到图形学的方方面面,当然也包括Shader。在学习Shader的过程中,我们最常使用的就是矢量和矩阵(即数学的分支之一——线性代数)。

4.2 笛卡尔坐标系
在游戏制作中,我们使用数学绝大部分都是为了计算位置、距离和角度等变量。而这些计算大部分都是笛卡尔坐标系(Cartesian Coordinate System)下进行的。
左手坐标系和右手坐标系
因为三维笛卡尔坐标系并不都是等价的。因此,就出现了两种不同的三维坐标系:左手坐标系和右手坐标系。这是因为两个坐标系不具有相同的旋向性(handedness)
这里写图片描述
这里写图片描述
4.2.4 Unity使用的坐标系
在模型空间中使用左手坐标系,观察空间中使用的是右手坐标系。观察空间,通俗来讲就是以摄像机为原点的坐标系。在这个坐标系中,摄像机的前向是z轴的负方向,这与在模型空间和世界空间中的定义相反。也就是说,z轴坐标的减少意味着场景深度的增加。
这里写图片描述
4.3 点和失量
点(point)是n维空间(游戏中主要使用二维和三维空间)中的一个位置,它没有大小、宽度这类概念。
失量(vector,也被称为向量)的定义则复杂一些。在数学家看来,失量就是一串数字。你可能要问了,点的表达式不也是一串数字吗?没错,但失量存在的意义更多是为了和标量(scalar)区分开来。通常来讲,失量是指n维空间中一种包含了模(magnitude)方向(direction)的有向线段,我们通常讲到的速度(velocity)就是一种典型的矢量。而标量只有模没有方向,生活中的距离(distance)就是以一种标量。
具体来讲。
·矢量的模指的是这个矢量的长度。一个矢量的长度可以是任意的非负数。
·矢量的方向则描述了这个矢量在空间中的指向。
矢量的表示方法和点类似。我们可以使用v=(x,y)来表示二维矢量,用v = (x,y,z)来表示三维矢量,用v = (x,y,z,w)来表示四维矢量。
为了方便阐述,我们对不同类型的变量在书写和印刷上使用不同的样式。
·对于标量,我们使用小写字母来表示,如a,b,x,y,z,θ,α等。
·对于矢量,我们使用小写的粗体字母来表示,如a,b,u,v等。
·对于后面要学习的矩阵,我们使用大写的粗体字母来表示,如A ,B,S,M,R等。
一个矢量通常由一个箭头来表示。我们有时会讲到一个矢量的头(heag)尾(tail)。矢量的头指的是它的箭头所在的端点处,而尾指的是另一个端点处,如图4.15所示:
这里写图片描述
通常,矢量被用于表示相对于某个点的偏移(displacement),也就是说他是一个相对量。
4.3.1 点和矢量的区别
这里写图片描述
我们可以认为,任何一个点都可以表示成一个从原点出发的矢量。
4.3.2 矢量运算
矢量和标量的乘法/除法
注意,对于乘法来说,矢量和标量的位置可以互换。但对于除法,只能是矢量被标量除,而不能是标量被矢量除,这是没有意义的。
从几何意义上看,把一个矢量v和一个标量k相乘,意味着对矢量v进行一个大小为|k|的缩放。例如。如果想要把一个矢量放大两倍,就可以乘以2。当k<0时,矢量的方向也会取反。
这里写图片描述
矢量的加法/减法
需要注意的是,一个矢量不可以和一个标量相加或相减,或者是和不同维度的矢量进行运算。
从几何意义上来看,对于加法,我们可以把矢量a的头连接到矢量b的为,然后画一条从a的尾到b的头的矢量,来得到ab相加后的矢量。下图称为矢量加法的三角形定则(triangle rule)
这里写图片描述
在图形学中矢量通常用于描述位置偏移(简称位移)。因此,我们可以利用矢量的加法和减法来计算一点相对于另一点的位移。
矢量的模
三维矢量的模的计算公式如下:
这里写图片描述
从图4.20可以看出,对于二维矢量,其实就是使用了勾股定理,矢量的两个分量的绝对值对应了三角形两个直角边的长度,而斜边的长度就是矢量的模。
这里写图片描述
单位矢量
在很多情况下,我们只关心矢量的方向而不是模。此时我们就需要计算单位矢量(unit vector)
单位矢量指的是那些模为1的矢量。单位矢量也被称为被归一化的矢量(normalized vector)。对任何给定的非零矢量,把它转换成单位矢量的过程就被称为归一化(normalization)
为了对矢量进行归一化,我们可以用矢量的模除以该矢量来得到。
这里写图片描述
零矢量(即矢量的每个分量值都为0,如v = (0,0,0))是不可以被归一化的。
矢量的点积
矢量之间也可以进行乘法,但是和标量之间的乘法有很大不同。矢量的乘法有两种最常用的种类:点积(dot product,也被称为内积,inner product)叉积(cross product,也被称为外积,outer product)
点积的名称来源于这个运算的符号:a·b。中间的这个圆点符号是不可以省略的。点积的公式有两种形式,我们先来看第一种。两个三维矢量的点积是把两个矢量对应分量相乘后再取和,最后的结果是一个标量。
公式一:这里写图片描述
矢量的点积满足交换律,即a·b = b·a
点积的几何意义很重要,因为点积几乎应用到了图形学的各个方面。其中一个几何意义就是投影(projection)
这里写图片描述
我们可以使用点积单位矢量a(三角形的斜边也是对象的前方)·长度不限的矢量b。来得到ba方向上的有符号的投影。
这里写图片描述
也就是说,点积的符号可以让我们知道两个矢量的方向关系。
那么,如果a不是一个单位矢量那么两个矢量的点积a·b等同于ba方向上的投影值,再乘以a的长度。
点积具有一些很重要的性质,在Shader的计算中,我们会经常利用这些性质来帮助计算。
性质一:点积可结合标量乘法。
上面的“结合”是说,点积的操作数之一可以是另一个运算的结果,即矢量和标量相乘的结果。也就是说,对点积中其中一个矢量进行缩放的结果,相当于对最后的点积结果进行缩放。
性质二:点积可结合矢量加法和减法,和性质一类似。
性质三:一个矢量和本身进行点积的结果,是该矢量的模的平方
很多情况下,我们只是想要比较两个矢量的长度大小,因此可以直接使用点积的结果。毕竟,开平方的运算需要消耗一定性能。
点积的另一种表达方式。这种方法是从三角代数的角度出发的,这种表示方法更加具有几何意义,因为它可以明确地强调出两个矢量之间的角度。
公式二:a·b = **|a||b|**cosθ
这里写图片描述
这也就是说,两个单位矢量的点积等于它们之间夹角的余弦值。再应用性质一就可以得到公式二了:这里写图片描述
也就是说,两个矢量的点积可以表示为两个矢量的模相乘,再乘以它们之间夹角的余弦值。这时的角度会影响投影值的符号。
利用这个公式我们还可以求得两个向量之间的夹角(0~180):这里写图片描述
其中,arcos是反余弦操作。
矢量的叉积
叉积(cross product),也被称为外积(outer product)。与点积不同的是,矢量叉积的结果仍是一个矢量,而非标量。
和点积类似,叉积的名称来源于它的符号:a×b。同样,这个叉号也是不可省略的。两个矢量的叉积可以用如下公式计算:这里写图片描述
需要注意的是,叉积不满足交换律,即a×b != b×a。实际上,叉积是满足反交换律的,即a×b = -(b×a)。而且叉积也不满足结合律,即(a×b)×c != a×(b×c)
从叉积的几何意义出发,我们可以更加深入地理解它的用处。对两个矢量进行叉积的结果会得到一个同时垂直于这两个矢量的新矢量。
我们先来看它的模。a×b的长度等于ab的模的乘积再乘以它们之间夹角的正弦值。公式如下:这里写图片描述
上述公式和点积的计算公式很类似,不同的是,这里使用的是正弦值。这和平行四边形的面积计算公式是一样的。
平行四边形的面积可以使用|b|h来得到,即底乘以高。而h又可以使用|a|和夹角θ来得到,即这里写图片描述
如果ab平行,我们可以认为构建出来的平行四边形面积为0,那么a×b = 0。这里得到的是零向量,而不是标量。
我们选择的方向和使同的坐标系又有联系。
这里写图片描述
使用何种坐标系不会对计算结果产生任何影响,它影响的只是数字在三维空间中的视觉化表现而已。
这里写图片描述
叉积最常见的一个应用就是计算垂直于一个平面、三角形的矢量。另外,还可以用于判断三角面片的朝向。
应用流程,进对象放置于xy(0)平面上,叉积结果为(0,0,?)。如果该值为负,则由左手法则判断可得到旋向性为顺时针方向,反之为逆时针方向。

4.4 矩阵
矩阵,英文名是matrix。
4.4.1 矩阵的定义
从它的外观上来看,就是一个长方形的网格,每个格子里放了一个数字。既然是网格结构,就意味着矩阵有行(row)列(column)之分。以3×3的矩阵为例,它可以写成:
这里写图片描述
m(ij)表明了这个元素在矩阵M的第i行、j列。
4.4.2 和矢量联系起来
我们可以用矩阵来表示矢量。实际上,矢量可以看成是n×1的列矩阵(column matrix)或1×n的行矩阵(row matrix),其中n对应了矢量的维度。例如,矢量v = (3,8,6)可以写成行矩阵[3 8 6 ]或列矩阵这里写图片描述
4.4.3 矩阵运算
矩阵和标量的乘法
这里写图片描述
矩阵和矩阵的乘法
一个r×n的矩阵A和一个n×c的矩阵B相乘,他们的结果AB将会是一个r×c大小的矩阵。第一个矩阵的列数必须和第二个矩阵的行数相同,他们相乘得到的矩阵的行数是第一个矩阵的行数,而列数是第二个矩阵的列数。例如,A的维度是1×3,B的维度是3×4,那么AB的维度就是1×4。
矩阵AB相乘得到矩阵C,那么,C中的每一个元素C(ij)等于A的第i行所对应的矢量和B的第j列所对应的矢量进行矢量点乘的结果,即:
这里写图片描述
看起来很复杂,我们用一个简单的方式来解释:对于每个元素C(ij),我们找到A中的第i行和B中的第j列,然后把他们的对应元素相乘后再加起来,这个和就是C(ij)。
一种更直观的方式如图4.30所示。假设A的大小是4×2,B的大小是2×4,那么如果计算C的元素C(23)的话为:C(23) = a(21)b(13) + a(22)b(23)
这里写图片描述
矩阵乘法满足一些性质。
性质一:并不满足交换律。也就是说,通常情况下:AB!= BA
性质二:满足结合律。也就是说,(AB)C = A(BC)

4.4.4 特殊的矩阵
方块矩阵(square matrix)。简称方阵。在三维渲染里,最常使用的就是3×3和4×4的方阵。
方阵之所以值得单独拿出来讲,是因为矩阵的一些运算和性质是只有方阵才具有的。例如,对角元素(diagonal elements)。方阵的对角元素指的是行号和列号相等的元素,例如m(11)、m(22)、m(33)等。如果把方阵看成一个正方形的话,这些元素排列在正方形的对角线上,这也是他们名字的由来。如果一个矩阵除了对角元素外的所有元素都为0,那么这个矩阵就叫做对角矩阵(diagonal matrix)
单位矩阵
一个特殊的对角矩阵是单位矩阵(identity matrix),用I(n)来表示。一个3×3的单位矩阵如下:
这里写图片描述
任何矩阵和它相乘的结果还是原来的矩阵。也就是说:MI = IM = M
转置矩阵
转置矩阵(transposed matrix)实际是对原矩阵的一种运算,即转置运算。给定一个r×c的矩阵M,它的转置可以表示成这里写图片描述,这是一个c×r的矩阵。转置矩阵的计算非常简单,我们只需要把原矩阵翻转一下即可。也就是说,原矩阵的第i行变成了第i列,而第j列变成了第j行。数学公式是:
这里写图片描述
例如:
这里写图片描述
对于行矩阵和列矩阵来说,我们可以使用转置操作来转换行列矩阵。
转置矩阵也有一些常用的性质。
性质一:矩阵转置的转置等于原矩阵。
这里写图片描述
性质二:矩阵串接的转置,等于反向串接各个矩阵的转置。
这里写图片描述
逆矩阵
逆矩阵(inverse matrix)大概是本书讲到的关于矩阵最复杂的一种操作了。不是所有的矩阵都有逆矩阵,第一个前提就是,该矩阵必须是一个方阵。
给定一个方阵M,它的逆矩阵用M(-1)来表示。逆矩阵最重要的性质就是,如果我们把M*和**M(-1),那么他们的结果将会是一个单位矩阵。也就是说:
这里写图片描述
前面说了,并非所有的方阵都有对应的逆矩阵。一个明显的例子就是一个所有元素都为0的矩阵。如果一个矩阵有对应的逆矩阵,我们就说这个矩阵是可逆的(invertible)或者说是非奇异的(nonsingular);相反的,如果一个矩阵没有对应的逆矩阵,我们就说他是不可逆的(noninvertible)或者说是奇异的(singular)
简单来说,如果一个矩阵的行列式(determinant)不为0,那么他就是可逆的。
对于二阶行列式:
|a b|
|c d|=ad-bc
对于三阶行列式:
| a b c |
| x1 x2 x3 |
| y1 y2 y3 |
结果可以写为:a*(x2*y3-x3*y2)-b*(x1*y3-x3*y1)+c*(x1*y2-x2*y1)
即:a*x2*y3-a*x3*y2-b*x1*y3+b*x3*y1+c*x1*y2-c*x2*y1
详细可以参见三阶行列式
以此类推,对于任意阶行列式,都可以改写为第一行某一元素与从第二行起的某一个n-1阶行列式的积,以此不断递推,直到分为某项与二阶行列式的积,然后再自此回溯最终可得解。
逆矩阵的实现:
例如求3阶可逆矩阵A的逆矩阵,首先做这样的一个矩阵
a11 a12 a13 1 0 0
a21 a22 a23 0 1 0
a31 a32 a33 0 0 1 (也就是 [原矩阵:单位矩阵] )
通过若干次初等行变换(“某行乘以一个数后加到另一行”、“某两行互换位置”、“某行乘以某一个数”,这三种以行做运算的方法),将上面的矩阵变为 1 0 0 b11 b12 b13
0 1 0 b21 b22 b23
0 0 1 b31 b32 b33 (也就是想办法把原来的A矩阵变成单位矩阵,变成这样的形式 [单位矩阵:B矩阵] )
这样B矩阵就是A矩阵的逆矩阵了。
以此类推到N阶可逆矩阵求逆矩阵。

在写Shader的过程中,这些矩阵通常可以通过调用第三方库(如C++数学库Eigen)来直接求得,不需要开发者手动计算。在Unity中,重要变换矩阵的逆矩阵Unity也提供了相应的变量供我们使用。Unity内置的矩(3.8)。
逆矩阵有很多非常重要的性质。
性质一:逆矩阵的逆矩阵是原矩阵本身。
性质二:单位矩阵的逆矩阵是它本身。
性质三:转置矩阵的逆矩阵是逆矩阵的转置。
性质四:矩阵串接相乘后的逆矩阵等于反向串接各个矩阵的逆矩阵。
逆矩阵是具有几何意义的。我们知道一个矩阵可以表示一个变换(4.5),而逆矩阵允许我们还原这个变化,或者说是计算这个变换的反向变换。因此,如果我们使用变换矩阵M对矢量v进行了一次变换,然后再使用它的逆矩阵M(-1)进行另一次变换,那么我们会得到原来的矢量。这个性质可以使用矩阵乘法的结合律很容易地进行证明:
这里写图片描述
正交矩阵
另一个特殊的方阵是正交矩阵(orthogonal matrix)。正交是矩阵的一种属性。如果一个方阵M和它的转置矩阵的乘积是单位矩阵的话,我们就说这个矩阵是正交的(orthogonal)。反过来也是成立的。也就是说,矩阵M是正交的等价于:
这里写图片描述
上式和我们在逆矩阵时遇到的公式很像。把两个公式结合起来,我们就可以得到一个重要的性质,即如果一个矩阵是正交的,那么他的转置矩阵和逆矩阵是一样的。也就是说,矩阵M是正交的等价于:
这里写图片描述
这个式子非常有用,因为在三维变换中我们经常会需要使用逆矩阵来求解反向的变换。而逆矩阵的求解往往计算量很大,但转置矩阵却非常容易求解:我们只需要把矩阵翻转一下就可以了。
接下来我们来观察正交矩阵的构造。我们来看一下对于3×3的正交矩阵有什么特点。根据正交矩阵的定义。我们有:
这里写图片描述
这样,我们就有了9个等式:
这里写图片描述
我们可以得到以下结论:
·矩阵的每一行,即c1、c2和c3是单位矢量,因为只有这样他们与自己的点积才能是1;
·矩阵的每一行,级c1、c2和c3之间互相垂直,因为只有这样他们之间的点积才能是0。
·上述两条结论对矩阵的每一列同样适用,因为如果M是正交矩阵的话,M(T)也会是正交矩阵。
也就是说,如果一个矩阵满足上面的条件,那么它就是一个正交矩阵。一组标准正交基(4.2.2)可以精确地满足上述条件。在4.6.2中,我们会使用坐标空间的基矢量来构建用于空间变换的矩阵。因此,如果这些基矢量是一组标准正交基的话(例如只存在旋转变换),我们就可以直接使用转置矩阵来求得该变换的逆变换。

已知,一个坐标空间需要指定一组基矢量,也就是我们理解的坐标轴。如果这些基矢量之间是相互垂直的,那么我们就把他们称为是一组正交基(orthogonal basis)。但是,他们的长度并不要求一定是1。如果他们的长度的确是1的话,我们就说他们是一组标准正交基(orthogonal basis)。因此,一个正交矩阵的行和列之间分别构成了一组标准正交基。但是,如果我们使用一组正交基来构建一个矩阵的话,这个矩阵可能就不是一个正交矩阵,因为这些基矢量的长度可能不为1,也就是说他们不是标准正交基。

4.4.5 行矩阵还是列矩阵
不同的行列方式经过运算之后对矩阵的书写次序和结果值是非常重要的。
在Unity中,常规做法是吧矢量放在矩阵的右侧,即把矢量转换成列矩阵来进行运算。因此,无特殊情况,我们都将使用列矩阵。这意味着,我们的矩阵乘法通常都是右乘,例如:
这里写图片描述
使用列向量的结果是,我们的阅读顺序是长右到左,即先对v使用A进行变换,再使用B进行变换,最后使用C进行变换。
4.5 矩阵的几何意义:变换
变换(transform),指的是我们把一些数据,如点、方向矢量甚至是颜色等,通过某种方式进行转换的过程。在计算机图形学领域,变换非常重要。尽管通过变换我们能够进行的操作是有限的。
线性变换(linear transform)指的是那些可以保留矢量加和标量乘的变换。
缩放(scale)就是一种线性变换。同样,旋转(rotation)也是一种线性变换。对于线性变换来说,如果我们要对一个三维的矢量进行变换,那么仅仅使用3×3的矩阵就可以表示所有的线性变换。
线性变化除了包括旋转和缩放外,还包括错切(shear)、镜像(mirroring,也被称为reflection)、正交投影(orthographic projection)等。
关于平移我们使用仿射变换(affine transform)。仿射变换就是合并线性变换和平移变换的变换类型。仿射变换可以使用一个4×4的矩阵来表示,为此,我们需要把矢量扩展都四维空间下,这就是齐次坐标空间(homogeneous space)
这里写图片描述
4.5.2 齐次坐标
我们知道,由于3×3矩阵不能表示平移操作,我们就把其扩展到了4×4的矩阵。为此,我们还需要把原来的三维矢量转换成四维矢量,也就是我们所说的齐次坐标(homogeneous coordinate)(事实上齐次坐标的维度可以超过四维,但本书中所说的齐次坐标将泛指四维齐次坐标)。
如何把三维矢量转换成齐次坐标,对于一个点,从三维坐标转换成齐次坐标是把其w分量设为1,而对于方向矢量来说,需要把其w分量设为0。这样的是设置会导致,当用一个4×4矩阵对一个点进行变换时,平移、旋转、缩放都会施加于该点。但是如果是用于变换一个方向矢量,平移的效果就会被忽略。
4.5.3 分解基础变换矩阵
我们把表示纯平移、纯旋转和纯缩放的变换矩阵叫做基础变换矩阵。这些矩阵具有一个共同点,我们可以把一个基础变换矩阵分解成4个组成部分:
这里写图片描述
其中,左上角的矩阵用于表示旋转和缩放,右上角用于表示平移,左下角是零矩阵,即[ 0 0 0],右下角的元素就是标量1。
4.5.4 平移矩阵
我们可以使用矩阵乘法来表示对一个点进行平移变换:
1 0 0 tx x x+tx
0 1 0 ty y = y+ty
0 0 1 tz z z+tz
0 0 0 1 1 1
从结果来看我们可以很容易看出为什么这个矩阵有平移的效果:点的x、y、z分量分别增加了一个位置偏移。在3D中的可视化效果是,把点(x,y,z)在空间中平移了(tx,ty,tz)个单位。
有趣的是,如果我们对一个方向矢量进行平移变换,结果如下:
1 0 0 tx x x
0 1 0 ty y = y
0 0 1 tz z z
0 0 0 1 0 0
可以发现,平移变换不会对方向矢量产生任何影响。
现在,我们来构建一个平移矩阵:基础变换矩阵中的t(3×1)矢量对应了平移矢量,左上角的矩阵M(3×3)为单位矩阵I(3)
平移矩阵的逆矩阵就是反向平移得到的矩阵,即
1 0 0 -tx
0 1 0 -ty
0 0 1 -tz
0 0 0 1
可以看出,平移矩阵并不是一个正交矩阵。
4.5.5 缩放矩阵
我们可以对一个模型沿空间的x轴、y轴和z轴进行缩放。同样,我们可以使用矩阵乘法来表示一个缩放变换:
kx 0 0 0 x kxx
0 ky 0 0 y = kxy
0 0 kz 0 z kxz
0 0 0 1 1 1
对方向矢量可以使用同样的矩阵进行缩放:
kx 0 0 0 x kxx
0 ky 0 0 y = kxy
0 0 kz 0 z kxz
0 0 0 1 0 0
如果缩放系数kx = ky = kz,我们把这样的缩放称为统一缩放(uniform scale),否则称为非统一缩放(nonuniform scale)。从外观上看,同一缩放是扩大整个模型,而非统一缩放会改变与模型相关的角度和比例。例如在对法线进行变换时,如果存在非统一缩放,直接使用用于变换顶点的变换矩阵的话,就会得到错误的结果。
缩放矩阵的逆矩阵是使用原缩放系数的倒数来对点或方向矢量进行缩放,即
1/kx 0 0 0
0 1/ky 0 0
0 0 1/kz 0
0 0 0 1
缩放矩阵一般不是正交矩阵。
上面的矩阵只适用于沿坐标轴方向进行缩放。如果我们希望在任意方向上进行缩放,就需要使用一个复合转换。其中一种方法的主要思想就是,先将缩放轴变换成标准坐标轴,然后进行沿坐标轴的缩放,再使用逆变换得到原来的缩放轴朝向。
4.5.6 旋转矩阵
旋转是三种常见的变换矩阵中最复杂的一种。我们知道,旋转操作需要指定一个旋转轴,这个旋转轴不一定是空间中的坐标轴,但本节所讲的旋转就是指绕着空间中的x轴、y轴或z轴进行旋转。
如果我们需要把点绕着x轴旋转θ度,可以使用下面的矩阵:
R(θ) = 1 0 0 0
0 cosθ - sinθ 0
0 sinθ cosθ 0
0 0 0 1
绕y轴的旋转也是类似的:
R(θ) = cosθ 0 sinθ 0
0 1 0 0
-sinθ 0 cosθ 0
0 0 0 1
最后,是绕z轴的旋转:
R(θ) = cosθ -sinθ 0 0
sinθ 0 cosθ 0
0 0 1 0
0 0 0 1
sinθ×sinθ+ cosθ×cosθ = 1
旋转矩阵的逆矩阵是旋转相反角度得到的变换矩阵。旋转矩阵是正交矩阵,而且多个旋转矩阵之间的串联同样是正交的。
4.5.7 复合变换
我们可以把平移、旋转和缩放组合起来,来行成一个复杂的变换过程。例如,可以对一个模型先进行大小为(2,2,2)的缩放,再绕y轴旋转30度,最后向z轴平移4个单位。复合变换可以通过矩阵的串联来实现。上面的变换过程可以使用下面的公式来计算:
P(new) = M(translation)M(rotation)M(scalθ )P(old)
由于上面我们使用的是列矩阵,因此阅读顺序是从右到左,即先进行缩放变换,再进行旋转变换,最后进行平移变换。需要注意的是,变换的结果是依赖于变换顺序的,由于矩阵乘法不满足交换律,因此矩阵的乘法顺序很重要。
这里写图片描述
在绝大多数情况下,我们约定的变换的顺序就是先缩放,再旋转,最后平移。
除了需要注意不同类型变换顺序外,我们有时还需要小心旋转的变换顺序。
这里写图片描述
旋转顺序是zxy。这里的顺序对于使用列矩阵来说是颠倒的,但是旋转时使用的坐标系有两种选择。
·绕坐标系E下的z轴旋转θ ,绕坐标系E下的y轴旋转θ,绕坐标系E下的x轴旋转θ,即进行一次旋转时不一起旋转当前坐标系。
·绕坐标系E下的z轴旋转θ,在坐标系E下再绕z轴旋转θ后的新坐标系E‘下的y轴旋转θ,在坐标系E‘下再绕y轴旋转θ后的新坐标系E‘’下的x轴旋转θ,即在旋转时,把坐标系一起转动。

猜你喜欢

转载自blog.csdn.net/qq_39710961/article/details/79964294
今日推荐