Shader 入门精要笔记(8)
矩阵的几何意义:
矩阵的变换:在三维渲染中,矩阵是可视化的,结果就是变换,在游戏世界中这些变换包括:旋转,平移,缩放。那么变换是什么呢?它指的是我们把数据,点,方向矢量,颜色,通过某种方式进行转换的过程,我们常常使用的是线性变换,线性变换指的是那些可以保留矢量加 和 标量乘的变换。数学公式 f(x) + f(y) = f(x+y) kf(x) = f(kx) 缩放也是一种线性变换,f(x) = 2x 可以表示一个大小为2 的同一缩放,即经过变换后矢量x 的模将被放大2倍,旋转也是一种线性变换,我们如果要对一个三维的矢量进行变换,只用3 X 3的矩阵就可以表示所有的线性变换。线性变换除此之外还有 错切 ,镜像,正交投影。除了线性变换还要考虑平移变换,如果 f(x) = x + (2,3,4) 这个变换就不是一个线性变换,它不满足标量乘法也不满足矢量加法,如果令x = (2,2, 2) 那么:f(x) + f(x) = (8,10,12) f(x+x) = (6,7,8),这两个运算得到的结果是不一样的,所以我们不能用3 X 3 的矩阵来表示一个平移变换,所以我们延伸出了仿射变换,它就是合并线性变换和平移变换 的变换类型,仿射变换可以用一个4 X 4 的矩阵来表示,我们需要把矢量空间拓展到四维空间下,这就是齐次坐标。而齐次坐标的维度可能超过4维,但是我们通常最高只涉及到4维向量,它只是为了方便计算而使用的一种表示方式而已,如果想让一个三维矢量转换为齐次坐标(4维的),对于一个点需要把W分量设为1,对于方向矢量来说需要把W矢量设为0,这样设置后会导致转换后的4X4矩阵对一个点进行变换时,平移,缩放,旋转都会对这个点起作用,但是用于变换一个方向矢量,平移是对其不起作用的.
分解基础变换矩阵:
我们把表示纯平移,纯缩放和纯旋转的变换矩阵叫做基础变换矩阵,其具有一些共同特点,我们可以把一个基础变换矩阵分解成4个组成部分:[ M3x3 T3x1] 左上角的M3x3 用于表示旋转和缩放,T3x1 表示平移,01x3 表示是零矩阵01x3 =(0,0,0),右下角表示标量1
01x3 1
平移矩阵:
我们使用矩阵乘法来表示对一个点进行平移变换:
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 0 0
通过结果很容易看出这个矩阵的平移效果,点的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
通过计算可以发现,平移矢量不会对方向矢量产生任何影响,因为矢量没有位置属性,它可以在空间的任意位置,只要方向和大小不发生改变,因此平移对方向矢量的位置改变没有影响。
[ M3x3 T3x1]
01x3 1
当给定一个平移操作时:T3x1对应了平移矢量,,左上角的 M3x3对应单位矩阵I3
平移矢量的逆矩阵就是反向平移得到的矩阵,即:
1 0 0 -Tx
[ 0 1 0 -Ty ]
0 0 1 -Tz
0 0 0 1
平移矩阵并不是一个正交矩阵
缩放矩阵:
我们可以对一个模型沿空间的x 轴y 轴z轴 进行缩放,同样可以使用矩阵乘法来表示一个缩放变换
Kx 0 0 0 x Kx X
[ 0 Ky 0 0] [ y ] = [ Ky Y ]
0 0 Kz 0 z Kz Z
0 0 0 1 1 1
对方向矢量可以使用同样的矩阵进行缩放
Kx 0 0 0 x Kx X
[ 0 Ky 0 0] [ y ] = [ Ky Y ]
0 0 Kz 0 z Kz Z
0 0 0 1 0 0
如果缩放系数 Kx = Ky = Kz,我们把这样的缩放称为统一缩放,否则称为非统一缩放,统一缩放是把模型整体进行放大缩小,非统一缩放通常是把模型拉伸或者挤压,注意:统一缩放不会改变角度和比例信息,非统一缩放会改变与模型相关的角度和比例,如果对法线进行变换时,如果存在非统一缩放,直接使用用于变换顶点的变换矩阵的话,便会得到错误的结果。
缩放矩阵的逆矩阵是使用原缩放系数的倒数来对点或者方向矢量进行缩放,即:
1/ Kx 0 0 0
[ 0 1/ Ky 0 0]
0 0 1/Kz 0
0 0 0 1
缩放矩阵一般不是正交矩阵
上面的矩阵只适用沿坐标轴方向进行缩放,若想使其在任意方向进行缩放则需要使用一个复合变换,主要思想是:先将坐标轴变换成标准坐标轴,然后进行沿坐标轴的缩放,再使用逆变换得到原来的缩放轴朝向即可。
旋转矩阵
旋转是变换矩阵较为复杂的一种,旋转操作需要指定一个旋转轴,旋转轴不一定是空间中的坐标轴,在这只讨论x轴,y轴,z轴进行旋转
如果绕x轴进行旋转使用下面的矩阵
1 0 0 0
Rx(θ) = [ 0 cosθ -sinθ 0]
0 sinθ cosθ 0
0 0 0 1
绕y轴的矩阵
cosθ 0 sinθ 0
Ry(θ) = [ 0 1 0 0]
-sinθ 0 cosθ 0
0 0 0 1
绕z轴的矩阵
cosθ -sinθ 0 0
Ry(θ) = [sinθ cosθ 0 0]
0 0 1 0
0 0 0 1
旋转矩阵的逆矩阵是旋转相反角度得到的变换矩阵。旋转矩阵是正交矩阵,而且多个旋转矩阵之间的串联同样是正交的
复合变换
我们可以平移,旋转,缩放组合起来,形成一个复杂的变换过程,例如可以对一个模型先进行大小为(2,2,2)的缩放,再绕y轴旋转30度,最后z 轴平移4个单位,复合矩阵通过矩阵串联来实现
我们通常约定复合变换的顺序是先进行缩放再旋转最后进行平移,由于矩阵的乘法不满足交换律,因此变换顺序尤为重要,如果我们希望原来的坐标不发生改变那就不能一开始就进行平移变换,旋转时使用的坐标系也尤为重要,Unity 关于旋转API的文档有说明,其是zxy的旋转顺序,两种旋转坐标不同,一种可能进行一次旋转时不一起旋转当前坐标系,另一种在旋转时,把坐标系一起转动,因此其结果也大不相同。

浙公网安备 33010602011771号