找回密码
 立即注册
查看: 292|回复: 0

Shader笔记——3D数学基础

[复制链接]
发表于 2022-5-6 17:48 | 显示全部楼层 |阅读模式
1.0 坐标与坐标系

1.1 坐标及坐标系的概念


在3D世界中,为了确定不同顶点所在的位置,需要使用坐标表示,二坐标的数值是基于一个固定的参照点进行定位的,这个点就是坐标原点。

通常情况下,原点的坐标一般都是(0,0)。

如果把所有的坐标汇集在一起管理,那就构成了一个坐标系。一个完整的坐标系会包含原点,方向和坐标。
1.2 3D中的坐标系


3D中涉及各种坐标系,从维度进行区分,所有坐标系可以分为平面直角坐标系和空间直角坐标系。

    平面直角坐标系,是在一个平面上定位的坐标系,坐标系由互相垂直的横,纵坐标轴组成。平面直角坐标系中的坐标通常表示为(x,y),模型UV,屏幕空间都是二维坐标系。如图:


    平面直角坐标系


    空间直角坐标系在平面直角坐标系的基础上添加了一个维度——深度,空间直角坐标系又互相垂直的三个坐标轴组成。空间直角坐标系中的坐标通常表示为(x,y,z),模型空间,世界空间,裁剪空间等都是空间直角坐标系。如图:


    空间直角坐标系

1.3 左右手坐标系


在空间坐标系中,根据坐标方向的不同又可以分为左手坐标系和右手坐标系。
    左手坐标系:伸出左手,让大拇指和食指摆成“L”型,然后将中指指向大拇指和食指所在的平面。右手坐标系:伸出右手,让大拇指和食指摆成“L”型,然后将中指指向大拇指和食指所在的平面。

若将大拇指设定为x轴,食指设定为y轴,中指设定为z轴,左右手坐标系如图:


左右手坐标系
俩种不同的坐标系没有优劣之分,可以根据不同的领域或者使用场景选择适合的坐标系。如Unity,Unreal,3D Max是左手坐标系,而Maya是右手坐标系。
2.0 向量


在数学中,坐标属于标量,只表示大小,不表示方向。
而同时表示长度和方向信息的,称之为向量(Vector),或者叫“矢量”。顶点的法线向量,切线向量等都是向量。
2.1 向量的表示方法

    向量可以使用粗体小写字母表示,比如a,b.

  • 在几何中,向量可以在空间直角坐标系中通过带有箭头的线段形象地表示出来。
    向量从起点开始绘制,指向向量的终点。线段的长度就是向量的长度,而箭头所指的方向就是向量的方向。如图:


    空间坐标系中的向量

    在代数中,向量可以通过数对的方式表示,如(x,y,z),分别表示向量的x分量,y分量和z分量。
2.2 向量的计算方法


假设二维向量a的起点A,终点为B,使用B的坐标减去A的坐标,即可计算出个向量a
二维向量a的计算公式如下:


二维向量计算公式

若将公式推广到三维空间,假设三维向量a的起点A,终点B,则三维向量a的计算公式如下:


三维向量计算公式
因为向量本身不包含位置信息,因此可以将向量移动到坐标系的任何位置,最终的到的向量与之前的向量完全相等。因此可以将所有向量的起点都设定成坐标原点,而终点的坐标就是向量本身。如图:


平移向量
2.3 相反向量


如果俩个向量的长度相等但方向相反,则这俩个向量互为相反向量。

零向量的相反向量是它本身。

从几何的角度来讲,将一个向量的起点作为终点,而原本的终点作为起点,最终得到的向量就是原向量的相反向量。

假设向量a的起点A,终点B,a的相反向量b,表示如下:


相反向量

因此,向量a的相反向量为-a,即乘以-1。

2.4 向量的模


向量包含长度和方向,向量的长度被称为向量的模。如向量a的模表示为|a|。

如图通过勾股定理,求得


直角坐标系计算向量的模长

二维向量a的模长计算公式为:


二维向量模长计算公式

向量的模一定是非负数,而零向量的模为0。

如图通过俩次勾股定理,求得


空间坐标系向量的模长

三维向量a模的计算公式为:

三维向量模长计算公式

2.5 标准化向量


“单位向量”是指模长为1的向量。
在很多情况下向量的方向比向量的长度更值得关注,如灯光的照射方向,摄像机的查看方向等。为了计算方便,可将这种向量转变为单位向量,这个转变的过程称为向量的标准化(Normalize)。

从代数的角度来讲,一个非零向量除以自身的长度,既可以将自身长度缩放为1。零向量的长度为0,在数学中0作为被除数没有意义。
因此非零向量a的标准化向量为:


非零向量**a**的标准化

单位向量与原向量相比,只是长度发生了改变,方向保持不变。
2.6 向量运算

2.6.1 向量的加法运算


从几何的角度来讲,向量的加法运算满足三角形法则。


向量的加法运算几何表示

向量的加法运算可以推广到多个数量相加,最终结果是从第一个向量的起点指向最后一个向量的终点,长度为起点与终点之间的距离。

从代数的角度来讲,向量的加法就是将相同的分量进行相加。


向量的加法运算代数表示

2.6.2 向量的减法运算


向量的减法运算可以理解为一向量与另一向量的相反向量做加法运算,同样满足三角形法则。
向量ab的减法运算转变为与相反向量的加法运算:


向量的减法运算


向量的减法运算几何表示

相同起点的俩个向量相减,得到的向量为第二个向量的终点指向第一个向量的终点,长度为俩终点之间的距离。

从代数的角度来讲,向量的减法运算就是将相同的分量相减。计算公式如下:


向量的减法运算代数表示

2.6.3 标量与向量相乘


将向量乘以一个标量,可产生向量缩放的效果。如图:

向量的缩放

假设向量a=(x,y,z),向量缩放k倍公式为:


向量的缩放

2.6.4 向量的点积运算


向量ab的点积写作a.b
在代数中,点积又叫做内积,俩个向量点积的结果就是对应所有分量相乘之后的和。点积的结果是数值。
点积计算公式为:


点积计算公式代数表示

在几何中,俩个向量点积的结果就是一个向量在另外一个向量上的投影长度与这个向量长度的积。
点积的计算公式为:


点积计算公式几何表示


向量投影
点积运算的几何意义用来判断俩个向量的相似程度,俩个向量越相似,点积的结果越大,当俩个向量的方向方向完全一致时,点积的结果是最大的。因此可以根据点积结果的正负号大致判断这俩个向量的方向是否一致。
当向量之间的夹角小于90°,点积结果为正,等于90°,点积结果为0,夹角大于90°,点积结果为负。


余弦函数曲线
2.6.5 向量的叉积计算


向量的叉积又称为外积,叉积的结果是向量。向量ab的叉积写作a × b
叉积的计算公式为:


叉积计算公式代数表示

在几何中,叉积得到的向量与ab所在平面垂直,长度等于向量ab组成的平行四边形的面积,该向量被称为法向量。如图:


叉积计算公式代数表示
法向量方向:使用右手定则,首先伸出右手,并竖起大拇指,并将其余的四个手指握紧。如图:


通过右手定则确定向量方向

以最小角度旋转向量a,使其与向量b的方向一致,四个手指朝向如上图,大拇指所指的方向就是法向量的方向。
法向量的长度:也就是平行四边形的面积,因此法向量的模长计算公式为:

法向量的模长计算公式
假设将叉乘的俩个向量颠倒顺序,ba叉乘所得向量的方向将会朝下。


交换向量顺序轴的右手定则

2.7 向量的运算法则


常用的向量运算法则如下所示:


向量运算法则

3.0 矩阵


向量可以使用横向排列的数组表示,假设纵向上继续排列相同维度的数组,最后组成的数组就是——矩阵(Matrix)。
3.1 矩阵的表示方法


向量的维度表示表示该向量所包含数的个数,同样的,矩阵的维度表示了该矩阵所包含的行和列的数量。通常使用r(raw的首字母缩写)表示行数,使用c(column的首字母缩写)表示列数,而矩阵本身则使用黑斜体大写字母表示,如M
一个3×3的矩阵M以及所对应的所有分量可以如下表示:


3×3的矩阵

3.2 方阵和单位矩阵


行数和列数相等的矩阵称为方阵。
方阵中行号和列号相等的分量称为对角元素,其他分量称为非对角元素。非对角元素全为0的矩阵称为对角矩阵。


对角矩阵

在对角矩阵中,对角元素全为1的矩阵叫作单位矩阵。


单位矩阵

任何矩阵乘以单位矩阵,最终得到的结果与原矩阵相同。单位矩阵对于矩阵的作用就像1对于标量的作用一样。
3.3转置矩阵


假设将一个r×c的矩阵M沿着对角线翻转,得到的新矩阵称为矩阵M的转置矩阵(Transpose Matrix)。


转置矩阵

转置矩阵的重要法则:将一个矩阵转置之后再进行转置,得到的矩阵与原矩阵相同,公式如下:


转置矩阵法则
将一个矩阵转置偶次后,得到的矩阵与原矩阵相同。
所有对角矩阵的转置矩阵都是原矩阵,单位矩阵也属于对角矩阵,因此单位矩阵也符合该法则。
3.4 矩阵运算

3.4.1 标量与矩阵的相乘


跟向量类似,矩阵也可以与标量相乘,中间不需要写运算符号,相乘之后的结果与原矩阵维数相同,然后将每个分量乘上这个标量。公式如下:


标量与矩阵的相乘

3.4.2 矩阵之间的乘法


当第一个矩阵的列数等于第二个矩阵的行数,这俩个矩阵才可以相乘,得到矩阵的行数等于第一个矩阵的行数,列数等于第二个矩阵的列数。


矩阵之间的乘法


矩阵乘法计算公式

3.4.3 矩阵与向量相乘


在Shader中,向量也可以与矩阵相乘,相乘的时候可以把向量看作行数为1或列数为1的矩阵。

向量(x,y,z)可以横向写成1×3的矩阵,被称为行向量:


行向量

也可以写成3×1的矩阵,被称为列向量:


列向量

向量与矩阵相乘的几何意义是实现向量的空间变换。
与矩阵相乘的时候是采用行向量还是列向量得到的结果是完全不同的,并且向量左乘矩阵还是右乘矩阵得到的结果也是截然不同。
<1> 行向量左乘矩阵:


行向量左乘矩阵

<2> 行向量右乘矩阵,没有意义:


行向量右乘矩阵

<3> 列向量左乘矩阵,没有意义:

列向量左乘矩阵

<4> 列向量右乘矩阵:

列向量右乘矩阵

结论:只有行向量左乘和列向量右乘,结果才有意义,并且俩种情况所得到的结果完全不同。
行向量左乘矩阵,所得结果依然是行向量;
列向量右乘矩阵,所得结果依然是列向量。
3.5 矩阵的运算法则


矩阵的运算法则

4.0 矩阵变换


在3D中,所有的变换都是通过矩阵完成的,包括常用的平移,旋转,缩放,除此之外,还有坐标空间之间的变换也是通过矩阵完成的。
4.1矩阵变换向量的原理


假设向量v = (x,y,z),可以表示为


然后将每个向量写成数值与单位向量相乘的形式:

观察以上列向量可知,每个单位向量其实表示的就是x,y,z轴的正方向。
假设+x,+y,+z轴的单位向量分别为p,q,r,于是上述公式可以简写为:

上述公式可以理解为:用向量pqr将向量v进行了变换,向量pqr被称为基向量。
将这3个基向量打包成一个基向量集合,以一个3×3的矩阵进行表示:

将任意向量(x,y,z)左乘以上述矩阵,计算如下:

上述的计算结果其实就是向量的加法运算,将相加的三个向量分离开:

可以发现:上面使用向量与矩阵相乘得到的结果与向量v变换之后的结果相同。
因此可以这样理解:矩阵对向量的变换等价于向量乘以矩阵。
假设aM=b,则可以说矩阵M把向量a变换为向量b

4.2 旋转矩阵

4.2.1 平面坐标系中的旋转矩阵


假设平面坐标系的俩个坐标向量分别为p = (1,0),q=(0,1),绕原点逆时针旋转角度之后如图:


将平面坐标系逆时针旋转

假设在平面坐标系中逆时针旋转表示正方向(通常情况下都是这样),计算出旋转轴的基向量,将基向量构建矩阵,于是实现旋转角度的矩阵为:

4.2.2 左右手坐标系的旋转方向


左右手坐标系中的旋转方向完全不同,俩种坐标系中的旋转方向的判断方法:先伸出与坐标系对应的那只手,握住旋转轴并且保持大拇指的朝向与旋转轴的正方向一致,其余四指的朝向即为旋转的正方向。如图,弧线箭头所示的方向即为右手坐标系的旋转正方向。


右手坐标系旋转正方向

左右俩种坐标系对应的旋转方向归纳如下:


右手坐标系旋转方向


左手坐标系旋转方向

4.2.3 空间坐标系绕x轴的旋转矩阵


这里只讲解绕坐标轴旋转的情况。
将空间坐标系绕x轴旋转,空间坐标系中的旋转方向如图:


将空间坐标系绕x轴旋转

x轴上的所有坐标都不会发生改变,从x轴正方向朝负方向观察坐标系,y轴和z轴的旋转情况完全跟平面坐标系的旋转情况一样,如图:


x方向的平面坐标系


最终绕x轴旋转角度的变换矩阵为:


4.2.4 空间坐标系绕y轴的旋转矩阵


空间坐标系绕y轴的旋转方向如图:


将空间坐标系绕y轴的旋转

从y轴正方向朝负方向观察坐标系,x轴和z轴的旋转情况如图:


y方向的平面坐标系



4.2.5 空间坐标系绕z轴的旋转矩阵


空间坐标系绕z轴的旋转方向如图:


将空间坐标系统绕z轴旋转

从z轴正方向朝负方向观察坐标系,x轴和y轴的旋转情况如图:


z方向的平面坐标系



4.3 缩放矩阵




缩放矩阵

4.4 平移矩阵


为什么要使用矩阵来表示平移,而不使用简单的坐标相加运算呢?
这是因为通过矩阵可以将常用的平移,旋转,缩放这三种变换合并成一个变换矩阵,乘以这一个变换矩阵即可完成平移,旋转,缩放这三种变换。


image.png

既然将变换矩阵扩展成了齐次矩阵,顶点坐标自然也需要增加一维才可以与矩阵相乘。于是顶点坐标最后增加一个分量w,将其扩展成齐次坐标。这里会产生 一个分歧,扩展出来的w分量是按照平移矩阵的对角元素那样补上1,还是按照第四列元素那样补上0呢?
下面对这两种情况分别进行尝试。
先计算w分量等于1的情况,将顶点坐标写成矩阵的形式,左乘平移矩阵,计
算过程如下:


由此可知,相乘之后得到的结果与最开始使用加法运算得到的结果一样。
因此,将w分量填充为1可以得到平移变换后正确的顶点坐标,并且变换之后的w分量依然为1。

那么将w分量填充为0结果会怎样呢?计算过程如下:


由此可知,相乘之后的结果与原顶点的坐标一样,并且w分量依然为0。因
此,将w分量填充为0无法起到平移变换的作用。
以上是通过运算推导出的结论,下面从理论角度进行解释:顶点是有位置信
息的,而向量是没有位置信息的,因此顶点可以进行平移操作,而向量无论怎么平移,得到的结果都是与原向量相同。
因此,当w分量为0的时,它表示一个向量,而当w分量为1时,它表示一个坐标。
5.0 矩阵深入讲解

5.1 矩阵的行列式


在任意方阵中都存在一个标量,这个标量就是该方阵的行列式。方阵M的行列式可以写为|M|,注意,只有方阵才会存在行列式,非方阵是没有行列式的。

行列式的计算方法非常简单:“将主对角线、反对角线上的元素各自相乘,然后将主对角线上的元素积的和减去反对角线积的和”。

2×2矩阵的行列式:


2×2矩阵的行列式


2阶矩阵行列式对角线

3×3矩阵的行列式:


3×3矩阵的行列式


3阶矩阵行列式对角线

下文会讲解一个计算高阶矩阵行列式更简单的方法。
5.2 余子式和代数余子式


如:3×3矩阵M如下:




3阶矩阵的余子式

对于方阵M,给定行i,列j元素的代数余子式等于相应余子式的有符号行列式,计算公式如下:


余子式是一个矩阵,而代数余子式是有符号的行列式,因此是一个标量。


5.3 通过代数余子式计算行列式


从矩阵中选择任意一行或者一列,对该行或者该列的每个元素都乘以该元素对应的代数余子式,这些乘积的和就是该矩阵的行列式。

假设3×3矩阵的行列式如下:


3×3矩阵

取第一行元素进行举例计算:


可以发现,通过代数余子式计算出来的3×3矩阵的行列式与前文计算结果相同。因此可以使用该方法进行高维矩阵的行列式计算。5.4 逆矩阵


通过矩阵将向量进行变之后,如果将这个变换“撤销”呢?这就需要使用逆矩阵。

逆矩阵的计算只能用于方阵,假如一个矩阵与另一个矩阵相乘,结果为单位矩阵,则这俩个矩阵互为逆矩阵。
验证俩个矩阵是否为逆矩阵,计算公式为:


用这个公式推导一遍矩阵变换之后的撤销操作,如下:


并非所有的矩阵都有逆。
如果一个矩阵有逆矩阵,则称这个矩阵是可逆的或者非奇异矩阵;
如果一个矩阵没有逆矩阵,则称这个矩阵是不可逆的或者奇异矩阵。

奇异矩阵的行列式为0,非奇异矩阵的行列式不为0。
因此检测一个矩阵是否有逆矩阵可以通过检测其行列式是否为0。

那么如何计算一个矩阵的逆矩阵呢?
这里就需要引进一个新的专有名词——标准伴随矩阵。

矩阵M的标准伴随矩阵可以表示为“adjM”,它是M代数余子式矩阵的转置矩阵。
即:计算出矩阵M每个元素的代数余子式,然后将这些数值构建成一个新的矩阵,这个矩阵的转置矩阵就是adjM

得到标准伴随矩阵之后,除以矩阵M的行列式就可以得到矩阵M的逆矩阵,计算公式如下:

3×3矩阵M如下:


计算每个元素的代数余子式:

得到每个元素的代数余子式之后,计算矩阵M的标准伴随矩阵为:

得到标准伴随矩阵之后,除以矩阵M的行列式就可以得到矩阵M的逆矩阵。
这里直接给出矩阵M的行列式值为|M|=-24。

通过逆矩阵的定义“互为逆矩阵的俩个矩阵相乘结果为单位矩阵”来验证结果的准确性,如下:


矩阵相乘的最终结果为:

经过验证,这两个矩阵相乘得到的矩阵为单位矩阵,因此通过标准伴随矩阵计算出的逆矩阵是正确的。
5.5 正交矩阵


假如在计算逆矩阵之前知道了这个矩阵为正交矩阵,就可以直接使用转置矩阵作为逆矩阵了。

在计算一个矩阵的逆矩阵之前,先计算这个矩阵的转置矩阵,然后将原矩阵与转置矩阵相乘,如果结果为单位矩阵,则转置矩阵为逆矩阵;如果结果为非单位矩阵,则需要计算矩阵的逆矩阵。


求逆矩阵流程图
那么有没有其他更为简单的方式可以判断矩阵是否正交呢?
再来深入探索正交矩阵的判定公式:


通过矩阵的乘法运算,可以得到以下9个等式:




5.6 逆矩阵的运算法则


逆矩阵的运算法则
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-22 13:32 , Processed in 0.226862 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表