分类 Shader 下的文章

在Unity里,矩阵的作用是对向量进行变换,主要的变换有三种形式,旋转、平移、缩放,以下为主要的几种矩阵的具体公式:

旋转矩阵

​ 2D坐标旋转矩阵

$$ M = \left[ \begin{matrix} \cos\theta & \sin\theta \\ -\sin\theta & \cos\theta \end{matrix} \right] $$

​ 具体计算

$$ \left[ \begin{matrix} x & y \end{matrix} \right] \times \left[ \begin{matrix} \cos\theta & \sin\theta \\ -\sin\theta & \cos\theta \end{matrix} \right] = \left[ \begin{matrix} x\times\cos\theta - y\times\sin\theta & x\sin\theta + y\times\cos\theta \end{matrix} \right] $$

​ 3D坐标旋转矩阵
​ 绕x轴旋转:

$$ \left[ \begin{matrix} 1 & 0 & 0\\ 0 & \cos\theta & \sin\theta\\ 0 & -\sin\theta & \cos\theta \end{matrix} \right] $$

   绕y轴旋转:

$$ \left[ \begin{matrix} \cos\theta & 0 & \sin\theta\\ 0 & 1 & 0\\ -\sin\theta & 0 & \cos\theta \end{matrix} \right] $$

   绕z轴旋转:

$$ \left[ \begin{matrix} \cos\theta & \sin\theta & 0 \\ -\sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{matrix} \right] $$

​ 具体计算与2D相同,具体思想:
​ 绕x旋转,x不变,用矩阵改变y,z的坐标;
​ 绕y旋转,y不变,用矩阵改变x,z的坐标;
​ 绕z旋转,z不变,用矩阵改变x,y的坐标;

平移矩阵

​ 2D平移矩阵

$$ \left[ \begin{matrix} 1 & 0 & 0\\ 0 & 1 & 0\\ d_x & d_y & 1 \end{matrix} \right] $$

​ (d_x 为 x方向增量,d_y 为 y方向增量)

​ 具体计算

$$ \left[ \begin{matrix} x & y & 1\\ \end{matrix} \right] \times \left[ \begin{matrix} 1 & 0 & 0\\ 0 & 1 & 0\\ d_x & d_y & 1 \end{matrix} \right] = \left[ \begin{matrix} x+d_x & y+d_y & 1\\ \end{matrix} \right] $$

​ 计算结果与分别在x、y坐标上增加增量一致

​ 3D平移矩阵

$$ \left[ \begin{matrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ d_x & d_y & d_z & 1\\ \end{matrix} \right] $$

​ (d_x 为 x方向增量,d_y 为 y方向增量,d_z 为 z方向增量)
​ 计算方式与2D相同,不再赘述

投影矩阵

$$ \left[ \begin{matrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & \frac{1}{d}\\ 0 & 0 & 0 & 0 \end{matrix} \right] $$

​ 计算

$$ \left[ \begin{matrix} x & y & z & 1 \end{matrix} \right] \times \left[ \begin{matrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & \frac{1}{d}\\ 0 & 0 & 0 & 0 \end{matrix} \right] = \left[ \begin{matrix} x & y & z & \frac{z}{d} \end{matrix} \right] $$

​ d是摄像机到视椎体前平面的距离,最终的x、y需要除以第4个分量,得到最终值

缩放矩阵

$$ \left[ \begin{matrix} s_x & 0 & 0 & 0\\ 0 & s_y & 0 & 0\\ 0 & 0 & s_z & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right] $$

​ 缩放矩阵具体计算

$$ \left[ \begin{matrix} x & y & z & 1 \end{matrix} \right] \times \left[ \begin{matrix} s_x & 0 & 0 & 0\\ 0 & s_y & 0 & 0\\ 0 & 0 & s_z & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right] = \left[ \begin{matrix} xs_x & ys_y & zs_z & 1 \end{matrix} \right] $$

​ 矩阵的效果可以通过相乘进行叠加,比如把平移和旋转的矩阵相乘,得到的新矩阵,就同时具有这两个功能,也可以多个矩阵相乘

$$ \left[ \begin{matrix} \cos\theta & 0 & \sin\theta & 0\\ 0 & 1 & 0 & 0\\ -\sin\theta & 0 & \cos\theta & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right] \times \left[ \begin{matrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ d_x & d_y & d_z & 1\\ \end{matrix} \right] = \left[ \begin{matrix} \cos\theta & 0 & \sin\theta & 0\\ 0 & 1 & 0 & 0\\ -\sin\theta & 0 & \cos\theta & 0\\ d_x & d_y & d_z & 1 \end{matrix} \right] $$

  1. 余弦定理:
    对于任意三角形,任何一边的平方等于其他两边平方的和减去这两边与它们夹角的余弦的积的两倍。

ta.png

$$ c^2 = a^2 + b^2 - 2ab\cos\gamma $$

余弦定理,可以用来推导向量的点积

  1. 向量的点积(点乘)公式:

$$ a\cdot b = (a_x,a_y,a_z)\cdot(b_x,b_y,b_z) = a_xb_x + a_yb_y + a_zb_z $$

点积的几何意义为b向量在a向量方向上的投影

image-20220118144358911.png

点积的结果是一个标量,两个向量的夹角小于90度,结果为正,等于90度,结果为0,大于90度,结果为负;可以用计算结果来判断两个向量的方向的一致性;

image-20220118144852067.png

  1. 向量的叉乘公式

    $$ a \times\ b = (a_x, a_y, a_z) \times\ (b_x, b_y, b_z) = (a_yb_z - a_zb_y,a_zb_x - a_xb_z,a_xb_y - a_yb_x) $$

叉乘不满足交换律,即 a×b ≠ b×a,但满足反交换律 a×b = −(b×a),叉乘也不满足结合律,即 (a×b) ×c ≠ a×(b×c)

原公式比较复杂,不容易记,可以用行列式的方式速记,或掐头去尾的方式速记;

$$ a \times\ b = \begin{vmatrix}i & j & k\\ a_x & a_y & a_z\\ b_x & b_y & b_z \end{vmatrix} = \begin {vmatrix} a_y & a_z \\ b_y & b_z \end{vmatrix}i + \begin {vmatrix} a_x & a_z \\ b_x & b_z \end{vmatrix}j + \begin {vmatrix} a_x & a_y \\ b_x & b_y \end{vmatrix}k $$

计算顺序为 y -- z -- x;

《掐头去尾法》:把向量的行列式水平写两遍,再掐头去尾去掉首列和尾列,之后,从左到右交叉相乘即可,如下

$$ a \times\ b = \begin{vmatrix}a_x & a_y & a_z & a_x & a_y & a_z\\ b_x & b_y & b_z &b_x & b_y & b_z \end{vmatrix} = \begin{vmatrix}a_y & a_z & a_x & a_y\\ b_y & b_z &b_x & b_y \end{vmatrix} = \begin{vmatrix}a_y & a_z\\ b_y & b_z\end{vmatrix} + \begin{vmatrix}a_z & a_x\\ b_z &b_x \end{vmatrix} + \begin{vmatrix}a_x & a_y\\ b_x & b_y \end{vmatrix} $$

叉乘结果是一个向量,向量的方向与做叉乘的两个向量同时垂直,也就是a、b两个向量所在平面的法线