要会写Shader,需要掌握一些基本的空间知识,比如空间坐标,矢量,线性代数等。下面介绍一些相关知识。
常见的坐标系分为二维坐标系和三维坐标系,二维坐标系比较容易理解,它就是我们初中就已经接触过的X-Y轴坐标系,相信大家都已经有所认识,不再赘述。三维坐标系比二维坐标系多了Z轴,也多了一些特性。三维坐标系可以分为左手笛卡尔坐标系和右手笛卡尔坐标系。之所以存在2种坐标系,是因为两种坐标系无论如何旋转都无法使轴向和另一种坐标系完全相同。
左手笛卡尔坐标系:
伸出左手,拇指的指向为X轴,食指指向为Y轴,中指指向为Z轴,这样便构成了左手笛卡尔坐标系。Unity使用的是左手笛卡尔坐标系。
右手笛卡尔坐标系:
伸出右手,拇指的指向为X轴,食指指向为Y轴,中指指向为Z轴,这样便构成了右手笛卡尔坐标系。我们观察一下左右手坐标系的异同点:①伸出的手不同,②手指的顺序相同都是拇指-食指-中指。
左手法则:
目的是确定旋转方向。左手法则应用于左手笛卡尔坐标系,左手变成一个点赞的手势,拇指指向和轴方向相同,那么其他手指的指向就是旋转的正方向。
右手法则:
右手法则应用于右手笛卡尔坐标系,原理同上。
OpenGL屏幕坐标:
左下角为原点。
DirectX屏幕坐标:
左上角为原点。
既有大小又有方向的量。矢量虽然和点的结构一样,都可以用Vector3来表示,但它们的意义不同。矢量在很多时候强调它的方向性,比如法线方向。而点更多的是描述物体的位置。
1、矢量减法:c = a - b,得到的结果是b矢量的末尾指向a矢量的末尾;
2、矢量加法:c = a + b,调整b矢量的位置,将a矢量的末尾指向b矢量的头,得到从a矢量的头出发连接到b矢量的末尾的矢量;
3、矢量点积:a · b = |a||b|,它的几何意义是两个矢量之间的投影大小,也可以用于计算两个矢量之间夹角的大小;
4、矢量叉积:|a * b| =|a||b|sin ,它的几何意义是,得到垂直于a,b矢量所在平面的方向。
《线性代数》这门课程主要学习的内容就是矩阵,那么线性代数和矩阵有什么关系呢?这是因为数学家发现线性代数的很多运算可以用矩阵来表达。多个线性代数构成的函数块,提取他们的代数构成矩阵,通过矩阵运算可以简化代数运算过程(大概就是这个意思,我也没太弄懂。。。)。图形学利用矩阵的一些特性,和运算来表达图形的移动、旋转、缩放。矩阵形如:
行矩阵:矩阵分为行和列,水平方向为行,竖直方向为列,当行为1时,此矩阵为行矩阵,形如M13:
列矩阵:列数为1的矩阵成为列矩阵,形如M31:
方块矩阵:行数和列数相等的矩阵成为方块矩阵,图形学里用的最多的是3×3和4×4矩阵。
对角矩阵:除了对角线,其余元素都为0的方块矩阵,即是对角矩阵。形如:
单位矩阵:对角线元素都为1的对角矩阵是单位矩阵,记为,形如:
转置矩阵:对矩阵进行翻转,行变为列,例如第一行变为新矩阵第一列,第二行变为新矩阵第二列,例如:
转置后
逆矩阵:两个方阵相乘,结果为单位矩阵,那么第二个矩阵是第一个矩阵的逆矩阵,记为,则有 = 。如果一个矩阵具有逆矩阵,那么这个矩阵是可逆的,或者说是非奇异的,与此相反,如果一个矩阵没有逆矩阵,那么这个矩阵是不可逆的,或者说是奇异矩阵。逆矩阵的几何意义在于,对一个矩阵的变换(矩阵相乘),可以通过乘逆矩阵来还原。逆矩阵和转置矩阵包含很多特性,如下:
①逆矩阵的逆矩阵是原矩阵:
②单位矩阵的逆矩阵是它自身:
③转置矩阵的逆矩阵是逆矩阵的转置:
④矩阵相乘的逆矩阵等于反向相乘各个矩阵的逆矩阵:
正交矩阵:如果一个方阵M和它的转置矩阵的乘积是单位矩阵,这个矩阵就是正交的。公式:
正交矩阵也拥有很多特性,对图形学来说,正交矩阵经常用于通过简单地求解转置矩阵来获得逆矩阵。其他特性如下(②③是把矩阵的每一行看作向量):
①正交矩阵的逆矩阵和转置矩阵相等:
②矩阵的每一行都是单位向量:
③矩阵行与行之间都相互垂直:
矩阵乘法:矩阵乘法不满足交换律,满足结合律。从结构上看,第一个矩阵的列数必须和第二个矩阵的行数相等,公式: = 。矩阵相乘后仍然是矩阵。矩阵的相乘运算比较复杂,结果矩阵的第i行,第j列元素的值等于A矩阵的第i行元素依次乘以B矩阵第j列的元素,并求和。举个例子 = ,那么现在的第1行,第2列的元素值是多少呢?
= = = 1 * 3 + 2 * 9 = 21
齐次坐标:
为了达到一些运算目的,将坐标提高一个维度后得到新的坐标,这个坐标就称为齐次坐标。在图形学中,为了能实现平移,常常将3维的坐标空间提高为4维的坐标空间。这里特地说明一下,Unity的矩阵乘法遵循右乘的规则,即从右乘到左,而不是我们习惯的从左乘到右。
几何变换:
通过乘以变换矩阵,对一个点进行坐标变换,变换顺序为缩放,旋转,平移,这个变换矩阵一般为:
其中用于旋转和缩放,用于表示平移,表示0矩阵,1表示标量。
平移矩阵:此时是单位矩阵,的x,y,z分别表示xyz轴的移动距离。
缩放矩阵:此时是对角矩阵,是零矩阵,k1,k2,k3分别表示对xyz轴的缩放。
旋转矩阵:旋转矩阵是正交矩阵,Unity的旋转顺序是zxy,这里特地讲解一下Unity的旋转顺序。其实这里的旋转顺序zxy指的是物体相对于世界坐标系的旋转顺序,如果你以物体的局部坐标系来作为观察空间,那么此时的旋转顺序是yxz,刚好和前面的顺序想反。手动试验一下更容易理解~
x轴旋转:
y轴旋转:
z轴旋转:
//矩阵行列式: