Unity Shader涉及得数学知识

矩阵

矩阵可以理解为一个行(row)X列(column)得数组,比如3行4列,2行3列等。如下图所示。之前我们可以用一个数组来表示一个矢量,在这里矩阵也可以看成一个数组,这里将矩阵和矢量用数组联系起来得用途就是为了让矢量参与矩阵运算,最终达到空间变换的目的,比如在顶点着色器中我们需要把顶点坐标从模型空间变换到齐次才见坐标系中。不同空间的坐标系就可以理解为不同的坐标空间,矢量在这些不同的空间中转换就是通过与矩阵运算做到的。
在这里插入图片描述

矩阵的运算

1.标量和矩阵得乘法
矩阵和标量相乘,就是矩阵中每个元素与标量相乘,结果还是得到一个相同维度的矩阵。如下图所示:
在这里插入图片描述
2.矩阵和矩阵得乘法
矩阵间得惩罚需要满足一定的条件才能相乘,就是第一个矩阵的列数要和第二个矩阵得行数相同,否则不能相乘。例如矩阵A得维度是3X4,矩阵B得维度是4X6,则AB得维度就等于3*6,其中,在这个新的3X6矩阵中,每一个元素都对应等于A矩阵得第i行和B矩阵得第j列得矢量进行矢量点成得结果。如下图所示:。在Shader得计算中,更多的是使用4X4矩阵来运算的。
在这里插入图片描述
3.特殊矩阵
(1)方块矩阵:是指行数和列数相同的矩阵,例如3X3,5X5等。有些相关矩阵的运算和特殊性质,是只有方块矩阵才有。在方块矩阵中,那些行号和列号相同的元素被称为对角元素,这些元素可以形象的看成是位于正方形得对角线上。如果在一个方块矩阵中除了对角元素外其余元素都为0,则这个方块矩阵就成为对角矩阵。如下图所示:
在这里插入图片描述
当对角矩阵中得对角元素都为1时,就成为了单位矩阵,在矩阵惩罚中,任何矩阵和单位矩阵相乘结果还是原来的矩阵。
(2)转置矩阵:实际上是对矩阵得一种转置运算,原矩阵中得每个元素得行列数相互调换形成一个新的矩阵。也就是原矩阵的第i行变成了第i列,第j列变成了第j行
。对于矩阵M,他的转置可以表示成MT,如果所示:
在这里插入图片描述
转置矩阵有两个常用得性质
1)矩阵转置得转置等于原矩阵。
2)矩阵串接得转置等于反向串接各个矩阵得转置,用公式表示为(AB)T=BTAT

(3)逆矩阵:并不是所有的矩阵或者方阵都有逆矩阵,但成为你矩阵的前提是矩阵必须是一个方阵。比如给定一个矩阵M,它的逆矩阵用M表示,=-1。逆矩阵有一个性质是M和M^ 相乘,结果将会是一个单位矩阵。如果有一个矩阵有对应的逆矩阵,则说这个矩阵是可逆得。反之则不可逆。
逆矩阵有几个性质:
1)逆矩阵得逆矩阵是原矩阵本身。
2)单位矩阵的逆矩阵是他本身。
3)转置矩阵的逆矩阵是逆矩阵的转置。
4)矩阵串接相乘后得逆矩阵等于反向串接各个矩阵的逆矩阵。
矩阵是用来转换矢量得,将一个矢量从一个空间变换到另一个空间。而逆矩阵的作用就是还原这个变换。
(4)正交矩阵:如果一个矩阵和他的转置矩阵相乘,结果是一个单位矩阵得话,则称这个矩阵是正交矩阵。结合上面的逆矩阵可以得出,一个正交矩阵,他的转置矩阵和逆矩阵是一样得。引入正交矩阵得概念是为了方便计算。另外一点需要知道的是,之前我们将矢量表示为行矩阵和列矩阵,单独这么表示是没有什么区别得。然而如果和矩阵相乘则就会有区别。在Unity中,都是将矢量用列矩阵得形式参与矩阵运算的。

矩阵的几何意义

矩阵的一个主要用途就是变换,像在游戏当中的旋转,缩放,平移等这些线性变换(可以保留适量加和标量相乘的变换,例如乘以2的缩放,结果是此矢量的模放大两倍。平移变换不是线性变换。)线性变换通常使用3X3的矩阵完成,但为了能正确表示平移变换就需要把矢量拓展到四维空间下,这就引出了齐次坐标空间。为此我们需要把三维矢量转换为四维矢量,也就是齐次坐标。对于一个点,从三维坐标转换成齐次坐标是把其w分量设为1,对于矢量来说,需要把w分量设为0.此时,当用一个4X4矩阵对一个点进行变换时,平移,缩放,旋转都会作用于该点的各个分量。当对一个矢量进行变换时,平移的效果就会被忽略。从之前矢量的性质来理解,矢量本身是没有位置属性的,也就是说矢量可以放在空间的任何位置。平移矩阵,如下图所示:
在这里插入图片描述
在这里插入图片描述

旋转矩阵

在这里插入图片描述
在这里插入图片描述
如果缩放系数Kx=Ky=Kz,则就是统一缩放,反之就是非统一缩放,可以理解为在Unity中缩放一个Cube,统一缩放就是整体放大缩小,非统一缩放就是单个轴向上的放大和缩小。一般非统一缩放会改变与模型相关的角度和比例,统一缩放就不会。如在对法线进行变换时,如果存在非统一的缩放,就会得到错误的结果。
上面的缩放只适用于沿着坐标轴方向进行缩放,如果在任意方向上进行缩放的话就要用到复合变换,例如其中一种是先将缩放轴变成标准坐标轴,沿着这个坐标轴缩放完之后再使用逆变换得到原来的缩放轴朝向。

复合变换

可以将其理解为将多种变换组合起来,比如平移,旋转,缩放组合起来从而形成一个新的变换过程。之前我们说过矢量表示为矩阵后可以有行矩阵和列矩阵,和相应的变换矩阵参与运算后会有不同的结果,在Unity中是使用列矩阵,因此在复合运算中,要依照先缩放,再旋转,最后平移的顺序进行运算,否则得到的结果就不是我们想要的正确结果

坐标空间

我们之前说过顶点着色器有一个基本的功能就是将模型的顶点坐标从模型空间转换到齐次裁剪空间坐标中,也就是三维转思维,这么做是为了保证矢量与矩阵的运算正确性。再次为何要引入坐标空间,可以试想一下假设你现在在房子里,有一个人过来问你你的饮水机在哪儿,你也许会说在门旁边,也可以说在冰箱旁边。你会发现你在定位饮水机的时候是分别以门以及冰箱作为参照来说的,可以直接理解为以门或冰箱为原点的坐标空间来定位饮水机。这就体现了坐标空间的重要性,没有它你无法定位一个物体。

坐标空间的转换

对于坐标之间的转换可以这样理解,一个坐标空间由远点和三个坐标轴组成,也就是说只要指定了一个原点以及三个坐标轴方向就能定义一个坐标空间。对于上面的假设,你跟别人说饮水机在门旁边或者在冰箱旁边,你是以门或者冰箱来定义了饮水机的位置,那么你有是怎么定义门和冰箱的位置呢?你可能会说厨房门或者厨房冰箱,这时你又以门或者冰箱来定义了饮水机的位置。坐标空间的定义实际上是相对的。一个坐标空间都是参照其他坐标空间来定义,可以理解为每个坐标空间都有一个父坐标空间。这其中比较重要的,也就是如何获得坐标空间变换的矩阵,再平常UnityShader编写应用中虽然涉及不到深层次的计算,淡化时间理解背后的原理对实际应用帮助是非常大的。

在渲染流水线中,一个点要经过多个坐标空间的转换最终才能显示在屏幕上,模型上的多个顶点经过此操作才能将整个模型显示在屏幕上。所经的坐标空间依次为模型空间->世家空间->摄像机空间->裁剪空间->标准屏幕空间->窗口空间

模型空间

模型空间,或者称本地坐标,每个模型都有自己的独立的坐标空间,比如你自己现在房间中走动,你是以自己的坐标轴来前后左右移动,但突然,旁边邻居发生了剧烈的瓦斯爆炸,一连串的连锁反应你所住的楼房因爆炸发生了倒塌,楼房向右边倾倒,此时你的朝向是向着楼房的左边,这时在房间的你也是跟着楼房向右边倾倒,而不是以你自己的坐标空间发生位移,最终随着楼房的倒塌你也跟着一起GameOver。这只是一个比喻,在游戏模型制作中,模型空间的原点和坐标轴通常是由美术人员在建模软件中确定好的。在Unity脚本中世界坐标转本地坐标的方法:transform.worldToLocalMatrix.在Unity着色器中是左乘_World2Object矩阵。

世界空间

世界空间,可理解为世界坐标系空间,可以理解为在Unity里,以游戏模型所在的场景为原始坐标系。在Unity脚本中本地坐标转世界坐标的方法:transform.localToWorldMatrix.在Unity着色器中:左乘_Object2World矩阵

摄像机空间

摄像机空间也称观察空间,物体经过摄像机观察后进入摄像机空间,这是以摄相机为原点的特性坐标空间,Unity里摄像机是以右手坐标系为主,不同于Unity里的世界坐标系以左手坐标系为主。因此,摄像机的视线时沿着世界坐标Z轴的负方向。另外需要注意的时摄像机空间跟屏幕空间是不同的,摄像机空间是三维空间,而屏幕空间是一个二维空间。本地坐标转摄像机坐标方法:UNITY_MATRIX_MV矩阵。

裁剪空间

裁剪空间的目的是能够方便的对渲染图元进行裁剪,完全在这块空间内的图元会被保留下来,在空间外的以及和空间边界相交的都会被裁剪掉,决定这块空间的就是视锥体。视锥体式摄像机映照场景形成的一种特殊区域,一般是不可见的,这块区域决定了摄像机可以看到的空间,视锥体有正交投影和透视投影两种,一般在做3D游戏为了体验真实感就用透视投影,在做类似平面不用凸显体积的2D游戏时选择正交投影,如下图所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
视锥体是用来裁剪图元的,但是直接用视锥体来裁剪的话,不同的视锥体就需要不用的处理过程,在这里,为了通用这个过程,一般用投影矩阵把顶点转换到裁剪空间中。投影矩阵本身是个迷惑行为,真正的投影实际上是使用齐次除法来得到二维坐标,之后再映射到屏幕上。尔投影矩阵只是投影前期的准备工作,主要是赋予顶点的w分量特殊意义成为一个范围,另外就是使顶点的x,y,z分量值缩放,最后分别通过判断处理过的x,y,z分量是否在w范围内,在就留下,不在就剔除掉。

屏幕空间

屏幕空间,经过投影矩阵的变换后,就需要将视锥体投影到屏幕空间中,经过这一步变换后我们得到的就是二维坐标而不是三维坐标,主要由齐次除法来完成。齐次除法就是用四维的w分量,分别除以x,y,z,w分量。在OpenGL中,把这一步得到的坐标叫做归一化的设备坐标。经过齐次除法后顶点坐标会变换到一个立方体内,按照OpenGL的传统,这个立方体的x,y,z分量范围都是[-1,1]。最后根据变换后的x,y坐标来映射输出屏幕的对应像素坐标。

窗口空间

窗口空间,代表的是设备上的一块矩形区域,坐标是以像素为单位。主要思路就是将屏幕空间的x,y平面对应到窗口上,将[-1,1]范围内的x,y坐标折算为窗口上的像素坐标。下图图示是整理了空间变换的过程以及各个坐标空间的旋向。
在这里插入图片描述

法线变换

法线变换,法线也称为法矢量,和上述的矢量不同是需要特殊处理的一种矢量,模型的顶点往往会携带额外的信息,其中就有顶点法线,在变换模型的时候不仅要变换顶点,同时也要变换顶点法线,以便后续在片元着色器中计算光照等。写到这里可能会回想起中学物理讲光的折射反射,比如法线垂直于平面,入射角等于反射角等等,此法线就是彼法线。在实际应用中,不是直接通过顶点来变换法线的,而是先通过两个顶点的插值计算出切线,之后在变换法线。这里的切线也是模型顶点携带的信息,切线通常与纹理空间对其并且与法线方向垂直。

小结

这次写完这些内容后也发现了很多知识盲区 例如法线变换等,其余内容虽然已有了解不过加深了解后更方便日后Shader的学习打好基础一点一点进步 Day Day Up 向着URP,HDRP冲鸭!
[文章内容原址(https://connect.unity.com/p/guan-yu-unity-shaderde-xue-xi-bi-ji-liu)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值