欢迎光临散文网 会员登陆 & 注册

Shader学习第三篇:Shader中需要数学知识

2023-03-02 22:03 作者:依稀爱恋  | 我要投稿

在Shader的学习中,我们可能需要一些数学知识,我也是学习了一段时间,之前数学的知识都忘了,重新来一遍吧,我把学习的点分享一下。

向量:

点乘:
向量A·向量B = A向量的模 * B向量的模 * cosθ
一般用来计算向量夹角cosθ,这里可以看下Lambert (兰伯特)光照模型这篇文章来感受下在Shader中的向量计算

叉乘: 计算两个向量构成平面的法向量

矩阵:

矩阵相乘必须要满足一个规则:第一个矩阵的列数要与第二个矩阵的行数相同。
而得到的结果一定为:行数为第一个矩阵的行数,列数为第二个矩阵的列数。
一个m行n列的向量A与一个n行r列的向量B相乘,得到m行r列的向量C。


例如矩阵A的维度是3×2,矩阵B的维度是2×4,那么AB的维度就是3×4。如下

另外还有一个计算技巧:
C23的值是从哪计算得来呢?可以看C23的下标,是由第一个矩阵的第2行 乘以 第二个矩阵的第3列得来

矩阵乘法的一些性质

  • 性质一:矩阵乘法不满足交换律。
    也就是说,通常情况下:AB≠BA

  • 性质二:矩阵乘法满足结合律。
    (AB)C=A(BC)
    矩阵乘法的结合律可以扩展到更多矩阵的相乘。例如,ABCD=((A(BC))D)=(AB)(CD)

向量与矩阵相乘

一个向量可以用(x,y,z)表示,现在我们让向量与矩阵相乘。
行向量与矩阵相乘:


列向量与矩阵相乘

注意:在Unity中,矩阵与向量运算,通常采用列向量右乘

特殊的矩阵

1、方块矩阵

简称方阵,是指那些行和列数目相等的矩阵。在三维渲染里,最常使用的就是3×3和4×4的方阵

2、单位矩阵

一个特殊的对角矩阵是单位矩阵(identity matrix),任何矩阵与它相乘还是原来的矩阵。

3、转置矩阵

直接举例:如下图

4、逆矩阵

不是所有的矩阵都有逆矩阵,该矩阵必须是个方阵。
逆矩阵几何意义:我们可以通过一个矩阵表示一个变换,如何把矩阵还原呢?可以使用逆矩阵来还原这个变换。
例如:

矩阵变换

线性变换:

满足下面条件的可以称之为线性变换

f(x)+f(y)=f(x+y) kf(x)=f(kx)

在 Unity 中,旋转、缩放为线性变换
对于线性变换来说,对一个三维的矢量进行变换,使用3×3的矩阵就可以表示所有的线性变换

非线性变换:

当然是不满足上面条件了,平移变换属于非线性变换
而对于非线性变换,3x3的矩阵已无法满足,既然三维空间无法满足,那么我用更高纬度的空间,4维空间来实现非线性变换。
使用4x4的矩阵来做非线性变换,我们称之为仿射变换(affine transform)。
把原来的三维矢量转换成四维矢量,这就是我们所说的齐次坐标(homogeneous coordinate)。
齐次坐标:


对于一个点w 补1,因为点会受到平移变换的影响
对应一个方向向量 w 补0,因为向量不会受平移的影响,不管怎么平移向量是不会变的。

平移矩阵变换。

下面我们来实现平移矩阵变换,来感受一下

假设现在有一个点为(1,2,4),把该点平移(2,1,3),最后的结果是(3,3,7),那么通过矩阵是怎么运算的呢?我们使用齐次坐标空间,由于此处是点的平移那么 w 处补0


如果现在改为方向向量(1,2,4),平移后方向向量是不变的,还是(1,2,4),此处w补0

缩放矩阵

旋转矩阵

沿x轴旋转


沿y轴旋转

沿z轴旋转

复合变换举例

我们把上面的平移缩放旋转来进行复合变换,说的再多,举一个例子可能更直观点。
点A(2,3,4),绕z轴旋转30度,缩放(1,2,3),平移(6,7,8),我们用矩阵来计算下


矩阵从右往乘,先旋转,再缩放,再平移。由于矩阵相乘满足结合律,我们可以把前面的三个矩阵相乘后得到一个变换矩阵,再于坐标点相乘

实际应用

在这里我们可以看Unity Shader的一个例子:
在Unity中需要一系列的矩阵变换才能被看到,我们来看看Unity的空间变换。

坐标空间

  • 模型空间:物体的原始数据存储在模型空间下,点是相对于模型空间。
    当一个模型导入到Unity中后,我们可以在顶点着色器中访问到模型的顶点信息,其中包含了每个顶点的坐标。这些坐标都是相对于模型空间中的原点(通常位于模型的重心)定义的。
    在模型空间下我们看不到物体,我们需要把物体先转换到世界空间

  • 世界空间:游戏运行时,把物体加载到场景中,会把点转换到世界空间下

  • 观察空间:摄像机空间,观察空间的原点在摄像机处,把世界空间下的点转换到摄像机的视角空间下。

  • 裁剪空间:到了观察空间,我们依然无法正常显示物体,需要进行下一步变换到裁剪空间,把摄像机外的物体裁剪掉,只有位于摄像机内的物体才会显示。

  • 屏幕空间:在完成上面的操作后,我们需要把点投影到屏幕上,而屏幕时二维空间的显示器,把点投影到屏幕空间中,计算屏幕坐标,显示器才能正常显示。

Shader中相对于的矩阵

1:模型空间 2:世界空间 3:观察空间 4:裁剪空间

  • UNITY_MATRIX_M:从模型空间,转换到世界空间

  • UNITY_MATRIX_V:从世界空间,转换到观察空间

  • UNITY_MATRIX_P:从观察空间,转换到裁剪空间

  • UNITY_MATRIX_MV:从模型空间,到观察空间

  • UNITY_MATRIX_VP:从世界空间,到裁剪空间

  • UNITY_MATRIX_MVP:从模型空间,转换到裁剪空间

直接上图,看的比较清楚

在顶点着色器中,需要对顶点进行空间变换。假如模型空间下的点A=(2,2,3),向量可以用列矩阵表示。需要把该点转为世界空间下的点,再转为视图空间(我理解的是摄像机的空间),再转为裁剪空间。
UNITY_MATRIX_M x A = 世界空间下的坐标
UNITY_MATRIX_V x 世界空间下的坐标 = 观察空间下的坐标
UNITY_MATRIX_P x 观察空间下的坐标 = 裁剪空间下的坐标

由于矩阵时满足结合律的,上面的空间变换我们可以用一个矩阵来表示UNITY_MATRIX_MVP,UNITY_MATRIX_MVP x A把该点从模型空间转为世界空间

在Unity中提供了相应的方法UnityObjectToClipPos,来进行坐标变换

一个简单的Shader代码


Shader学习第三篇:Shader中需要数学知识的评论 (共 条)

分享到微博请遵守国家法律