《Unity Shader入门精要》读书笔记03
第 4 章 数学基础
笛卡尔坐标系(Cartesian Coordinate System)
二维笛卡尔坐标系;三维笛卡尔坐标系
基矢量(basis vector):坐标系的坐标轴
标准正交基(orthonormal basis):相互垂直,长度为 1
正交基(orthogonal basis):相互垂直
旋向性(handedness):相同旋向性的坐标轴可通过旋转重合
左手坐标系(left-handed coordinate space):
左手(拇指,食指,中指)->(+x, +y, +z)
左手法则(left-hand rule)- 左手“点赞”右手坐标系(right-handed coordinate space):
右手(拇指,食指,中指)->(+x, +y, +z)
右手法则(right-hand rule)- 右手“点赞”Unity 在模型/世界空间中使用左手坐标系,而在观察空间中使用右手坐标系。
练习题:1.右手坐标系 2.(1,0 ,0) (1,0 ,0) 3. -10 10
点和矢量
- 点(point):一个位置
- 矢量/向量(vector):n维空间中一种包含了模(magnitude)和方向(direction)的有向线段;是相对量,无论放在哪里都一样。
- 对于标量,我们使用小写字母来表示,如α,b,x,y,z,θ,α等;
- 对于矢量,我们使用小写的粗体字母来表示,如a,b,u,v 等;
- 对于后面要学习的矩阵,我们使用大写的粗体字母来表示,如 A,B,S,M,R 等。
矢量运算
- 矢量和标量乘除
- 矢量加减——三角形定则(triangle rule)
- 矢量的模
- 单位矢量(unit vector)/ 被归一化的矢量(normalized vector) ——归一化(normalization)
- 矢量的点积/内积(dot product / inner product)——投影(projection)
- 矢量的叉积/外积(cross product / outer product)——计算垂直于一个平面、三角形的矢量;判断三角面皮的朝向
练习题:
1.(1)错 (2)对 (3)错
2.(1) (2)(12.5, 10, 25) (3)(1.5, 2)
(4)(5/13, 12/13) (5)() (6)(10,9) (7)(-6, 1, 2)
3.
4.(1)75(2)13 (3)13(4)(-9, -13, 17) (5)(9,13,-7)
5.(1)12 (2)20. 784
6.(1)若>0,说明玩家在NPC前方;反之在后方
(2)上述公式中乘积小于零,同时根据画图可知玩家在NPC后方,(1)方法正确。
(3)计算,,然后将与比较。也可以比较和。
(4)计算距离,将d固定的距离比较。
7.计算,若结果的z分量>0,根据左手法则,是逆时针排列。
矩阵(matrix)
数学家的Excel(
上面是三行三列的的矩阵。行(row),列(column)。
矢量可以看成是 的列矩阵(column matrix)或 的行矩阵(row matrix),其中n对应了矢量的维度。
矩阵运算
1.矩阵和标量的乘法:矩阵的每个元素和该标量相乘。
2.矩阵和矩阵的乘法:第一个矩阵的列数必须和第二个矩阵的行数相同,
- 矩阵乘法不满足交换律
- 矩阵乘法满足结合律
特殊的矩阵
1.方块矩阵(square matrix)->对角矩阵(diagonal matrix)
2.单位矩阵(identity matrix),用表示。相当于标量中的数字 1 。
3.转置矩阵(transposed matrix),实际是对原矩阵的一种运算
- 性质一:矩阵转置的转置等于原矩阵。
- 性质二:矩阵串接的转置,等于反向串接各个矩阵的转置,
4.逆矩阵(inverse matrix)
不是所有的矩阵都有逆矩阵,首先,该矩阵是一个方阵。
给定一个方阵,它的逆矩阵用来表示。那么
如果一个矩阵有对应的逆矩阵,我们就说这个矩阵是 可逆的(invertible) 或者说是 非奇异的(nonsingular);相反的,如果一个矩阵没有对应的逆矩阵,我们就说它是 不可逆的(noninvertible) 或者说是 奇异的(singular)。
- 判断方法:如果一个矩阵的 行列式(determinant) 不为0,那么它就是可逆的。
- 性质一:逆矩阵的逆矩阵是原矩阵本身。
- 性质二:单位矩阵的逆矩阵是它本身。
- 性质三:转置矩阵的逆矩阵是逆矩阵的转置。
- 性质四:矩阵串接相乘后的逆矩阵等于反向串接各个矩阵的逆矩阵。
5.正交矩阵(orthogonal matrix)
一个方阵和它的转置矩阵的乘积是单位矩阵,即
等价于
这个式子可以用于逆矩阵的求解。因为正交矩阵的逆矩阵就是它的转置矩阵。
- 一个正交矩阵的行和列之间分别构成了一组标准正交基。
在Unity中,常规做法是把矢量放在矩阵的右侧,即把矢量转换成列矩阵来进行运算。我们的矩阵乘法通常都是右乘,例如:
从右到左,即先对 使用A进行变换,再使用B进行变换,最后使用C进行变换。
练习题
1.(1)(2)乘积不存在
(3)
2.(1)不是(2)是(3)是
3.(1)一样(2)不一样(3)一样
为了得到相同的结果,需要矩阵是对称矩阵(symmetric matrix,矩阵和转置矩阵相同);或者进行行矩阵乘法时,对矩阵进行转置。
矩阵和变换
变换(transform) 指的是我们把一些数据,如点、方向矢量甚至是颜色等,通过某种方式进行转换的过程。
线性变换(linear transform),指的是那些可以保留矢量加和标量乘的变换。公式如下
线性变换包括旋转(rotation)和缩放(scale),错切(shear)、镜像(mirroring,也被称为 reflection)、正交投影(orthographic projection)等。
仿射变换(affine transform),是合并线性变换和平移变换的变换类型。仿射变换可以使用一个4x4的矩阵来表示,为此,我们需要把矢量扩展到四维空间下,这就是齐次坐标空间(homogeneous space)。
| 变换名称 | 是线性变换吗 | 是仿射变换吗 | 是可逆矩阵吗 | 是正交矩阵吗 |
|---|---|---|---|---|
| 平移矩阵 | N | Y | Y | N |
| 绕坐标轴旋转的旋转矩阵 | Y | Y | Y | Y |
| 绕任意轴旋转的旋转矩阵 | Y | Y | Y | Y |
| 按坐标轴缩放的缩放矩阵 | Y | Y | Y | N |
| 错切矩阵 | Y | Y | Y | N |
| 镜像矩阵 | Y | Y | Y | Y |
| 正交投影矩阵 | Y | Y | N | N |
| 透视投影矩阵 | N | N | N | N |
齐次坐标(homogeneous coordinate)
对于一个点,从三维坐标转换成齐次坐标是把其 w 分量设为1,而对于方向矢量来说,需要把其 w 分量设为0。
分解基础变换矩阵
其中,表示旋转和缩放,表示平移。
- 平移矩阵
- 缩放矩阵——统一缩放(uniform scale),非统一缩放(nonuniform scale)
- 旋转矩阵
复合变换
- 我们约定变换的顺序是先缩放,再旋转,最后平移。
- 当我们直接给出(,, )这样的旋转角度时,需要定义一个旋转顺序。在Unity中,这个旋转顺序是zxy,组合旋转变换矩阵是:
一些读者会有疑问:上面的公式书写顺序是不是反了?不是说列矩阵要从右往左读吗?这样一来顺序不就颠倒了吗?实际上,有一个非常重要的东西我们没有说明白,那就是旋转时使用的坐标系。给定一个旋转顺序(例如这里的zxy),以及它们对应的旋转角度(0,0,0),有两种坐标系可以选择。
Unity 文档中说的是世界坐标系下的旋转;而使用矩阵变换时是在局部坐标系中旋转的
说得明白点,在第一种情况下按zxy顺序旋转和在第二种情况下按yxz顺序旋转是一样的。
坐标空间
坐标空间的变换
顶点的坐标空间变换过程:
- 模型空间(model space)/对象空间(object space)/局部空间(local space)
- —模型变换(model transform)
- 世界空间(world space)
- —观察变换(view transform)
- 观察空间(view space)/摄像机空间(camera space)
- —投影矩阵变换
- 裁剪空间(clip space)
- —齐次除法(hemogeneous division)/透视除法(perspective division)
- 屏幕空间(screen space)
模型空间是在建模软件里确定好的
观察空间(view space)/摄像机空间(camera space)
Unity中观察空间的坐标轴选择是:+x轴指向右方,+y轴指向上方,而+z轴指向的是摄像机的后方。Unity在模型空间和世界空间中选用的都是左手坐标系,而在观察空间中使用的是右手坐标系。这是符合OpenGL传统的,在这样的观察空间中,摄像机的正前方指向的是-z轴方向。
裁剪空间(clip space)
裁剪矩阵(clip matrix)/投影矩阵(projection matrix),正交投影(orthographic projection),透视投影(perspective projection),视锥体(view frustum),裁剪平面(clip planes),近剪裁平面(near clip plane),远剪裁平面(far clip plane)投影矩阵有两个目的:
- 首先是为投影做准备。这是个迷惑点,虽然投影矩阵的名称包含了投影二字,但是它并没有进行真正的投影工作,而是在为投影做准备。真正的投影发生在后面的齐次除法
(homogeneous division)过程中。而经过投影矩阵的变换后,顶点的 w 分量将会具有特殊的意义。
读者:投影到底是什么意思呢?
我们:可以理解成是一个空间的降维,例如从四维空间投影到三维空间中。而投影矩阵实际上并不会真的进行这个步骤,它会为真正的投影做准备工作。真正的投影会在屏幕映射时发生,通过齐次除法来得到二维坐标。具体会在4.6.8节中讲到。- 其次是对x、y、z分量进行缩放。我们上面讲过直接使用视锥体的6个裁剪平面来进行裁剪会比较麻烦。而经过投影矩阵的缩放后,我们可以直接使用w分量作为一个范围值,如果x、y、z分量都位于这个范围内,就说明该顶点位于裁剪空间内。
在裁剪空间之前,虽然我们使用了齐次坐标来表示点和矢量,但它们的第四个分量都是固定的:点的w分量是1,方向矢量的w分量是0。经过投影矩阵的变换后,我们就会赋予齐次坐标的第4个坐标更加丰富的含义。
- 首先是为投影做准备。这是个迷惑点,虽然投影矩阵的名称包含了投影二字,但是它并没有进行真正的投影工作,而是在为投影做准备。真正的投影发生在后面的齐次除法
屏幕空间
归一化的设备坐标(Normalized Device Coordinates,NDC)按照OpenGL的传统,这个立方体的 x、y、z 分量的范围都是[-1,1]。但在 DirectX 这样的 API 中,z分量的范围会是[0,1]。而 Unity 选择了 OpenGL 的齐次裁剪空间。
在Unity中,从裁剪空间到屏幕空间的转换是由底层完成。我们的顶点着色器只需要把顶点转换到裁剪空间。
法线变换
- 法线(normal)/法矢量(normal vector)
- 切线(tangent)/切矢量(tangent vector)——与纹理空间对齐,与法线方向垂直
要使用原变换矩阵的 逆 转置矩阵 来变换法线。
- 如果变换矩阵是正交矩阵,那么我们可以使用用于变换顶点的变换矩阵来直接变换法线。如果变换只包括旋转变换,那么这个变换矩阵就是正交矩阵。
- 而如果变换只包含旋转和统一缩放,而不包含非统一缩放,我们利用统一缩放系数 k 来得到变换矩阵的逆转置矩阵。
- 如果变换中包含了非统一变换,那么我们就必须要求解逆矩阵来得到变换法线的矩阵。
Unity Shader 的内置变量
以下是 Unity 2022.3 的内置变量
变换矩阵
| Name | Value |
|---|---|
| UNITY_MATRIX_MVP | 当前的模型-观察-投影矩阵,用于将顶点/方向矢量从模型空间变换到裁剪空间 |
| UNITY_MATRIX_MV | 当前的模型-观察矩阵,用于将顶点/方向矢量从模型空间变换到观察空间 |
| UNITY_MATRIX_V | 当前的观察矩阵,用于将顶点/方向矢量从世界空间变换到观察空间 |
| UNITY_MATRIX_P | 当前的投影矩阵,用于将顶点/方向矢量从观察空间变换到裁剪空间 |
| UNITY_MATRIX_VP | 当前的观察-投影矩阵,用于将顶点/方向矢量从世界空间变换到裁剪空间 |
| UNITY_MATRIX_T_MV | UNITY_MATRIX_MV的转置矩阵 |
| UNITY_MATRIX_IT_MV | UNITY_MATRIX_MV的逆转置矩阵,用于将法线从模型空间变换到观察空间,也可用于得到UNITY_MATRIX_MV的逆矩阵 |
| unity_ObjectToWorld | 当前的模型矩阵,用于将顶点/方向矢量从模型空间变换到世界空间 |
| unity_WorldToObject | ObjectToWorld的逆矩阵,用于将顶点/方向矢量从世界空间变换到模型空间 |
摄像机与屏幕参数
| Name | Type | Value | |
|---|---|---|---|
| _WorldSpaceCameraPos | float3 | 摄像机在世界空间中的位置。 | |
| _ProjectionParams | float4 | x 为 1.0(如果当前使用翻转的投影矩阵进行渲染,则为 -1.0), y 为摄像机的近平面,z 为摄像机的远平面, w 为 1/远平面。 | |
| _ScreenParams | float4 | x 是相机目标纹理的宽度(以像素为单位)。y 是相机目标纹理的高度(以像素为单位), z 是 1.0 + 1.0/宽度, w 是 1.0 + 1.0/高度。 | |
| _ZBufferParams | float4 | 用于线性化 Z 缓冲区值。 | |
x | 如果 UNITY_REVERSED_Z 设置为 1,则为 1-far/near ,或 -1+far/near | ||
y | far/near ,或者如果 UNITY_REVERSED_Z 设置为 1,则为 1 有关 | ||
z | x/far | ||
w | y/far | ||
| unity_OrthoParams | float4 | x 是正交相机的宽度, y 是正交相机的高度, z 未使用, w 在相机为正交相机时为 1.0,在透视相机时为 0.0。 | |
| unity_CameraProjection | float4x4 | 摄像机的投影矩阵。 | |
| unity_CameraInvProjection | float4x4 | 摄像机投影矩阵的逆矩阵。 | |
| unity_CameraWorldClipPlanes[6] | float4 | 摄像机视锥体平面世界空间方程,按此顺序:左、右、下、上、近、远。 | |
| 除此之外还有 Time、Lighting……这项和引擎相关,需要时再查文档即可。 |
答疑解惑
- ,还是?:在对顶点的变换中,我们通常使用 的变换矩阵。而在对方向矢量的变换中,我们通常使用 的矩阵就足够了。
- 获取屏幕坐标的方法:ComputeScreenPos/VPOS/WPOS
- 标题: 《Unity Shader入门精要》读书笔记03
- 作者: 铁名_IronName
- 创建于 : 2026-01-13 09:57:36
- 更新于 : 2026-01-16 18:04:54
- 链接: https://blog.ironname.top/2026/01/13/《Unity-Shader入门精要》读书笔记03/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。