1、矢量和矩阵是学习Shader过程中最常使用的数学,即线性代数
2、左右手坐标系的不同导致,如果使用相同的数学运算,得到的视觉效果是不一样的,因此需要进行一些转换
在模型空间中,Unity使用的是左手坐标系,右、上、前分别对应了x,y,z轴
在观察空间中,Unity使用的是右手坐标系,即以摄像机为原点的坐标系
3、点乘的几何意义很重要,其中一个几何意义就是投影
点乘的符号可以让我们知道两个矢量的方向关系
可通过矢量和自身点积求得模的平方,进而比较两个矢量的长度大小
另一个重要的矢量运算是叉积,也称外积
(ax,ay,az)x(bx,by,bz)=(aybz-azby,azbx-axbz,axby-aybx)
叉积满足反交换律,即:axb=-(bxa)
叉积的几何意义是同时垂直于两个矢量的新向量,常用于计算垂直于一个平面、三角形的矢量,判断三角形的朝向。
4、矩阵
矩阵乘法不满足交换律
矩阵乘法满足结合律
逆矩阵:不是所有的矩阵都有逆矩阵,前提是该矩阵必须是一个方阵
可逆的=非奇异的
不可逆的=奇异的
判断:行列式不为0
部分性质:
转置矩阵的逆矩阵是逆矩阵的转置
矩阵串接相乘后的逆矩阵等于反向串接各个矩阵的逆矩阵
几何意义:矩阵可以表示一个变换,逆矩阵可以表示还原这个变换
正交矩阵:一个矩阵的 转置矩阵=逆矩阵
判断:矩阵的每一行,即c1,c2,c3是单位矢量,这样,自身点积为才能是1
矩阵的每一行,即c1,c2,c3之间相互垂直,这样,相互之间点积才能是0
行列矩阵:矢量转换成矩阵进行矩阵相乘时,选择转换成行矩阵还是列矩阵是非常重要的。
Unity中,常规做法是把矢量放在矩阵的右侧,即把矢量转换成列矩阵来进行计算
5、图形学中常见变换矩阵的名称和它们的特性
变换名称 | 是线性变换吗 | 是仿射变换吗 | 是可逆矩阵吗 | 是正交矩阵吗 |
平移矩阵 | 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 |
仿射变换:合并线性变换和平移变换的变换类型
6、齐次坐标
使用一个4x4的矩阵来表示平移、旋转和缩放
平移矩阵:
缩放矩阵:
旋转矩阵:
复合矩阵:
7、坐标空间变换
对坐标的空间变换实际上就是在父空间和子空间之间对点和矢量进行变换
8、渲染流水线中顶点的空间变换过程
模型空间(对象空间) 左手坐标系 模型变换
世界空间 左手坐标系 观察变换
观察空间(以摄像机为原点) 右手坐标系 投影变换
裁剪空间(裁剪图元,并为投影做准备 ) 左手坐标系 屏幕映射
屏幕空间(xy坐标对应屏幕上的2D像素坐标)左手坐标系
9、Unity内置的变换矩阵(float4X4)
变量名 | 描述 |
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的逆转置矩阵,用于将法线从模型空间变换到观察空间 |
_Object2World | 模型矩阵,用于将顶点/方向矢量从模型空间变换到世界空间 |
_World2Object | _Object2World逆矩阵,用于将顶点/方向矢量从世界空间变换到模型空间 |
10、Unity内置的摄像机和屏幕参数
变量名 | 类型 | 描述 |
_WorldSpaceCameraPos | float3 | 摄像机在世界空间中的位置 |
_ProjectionParams | float4 | x=1.0,y=Near,z=Far,W=1.0+1.0/Far,其中Near和Far分别是近裁剪平面和远裁剪平面和摄像机的距离 |
_ScreenParams | float4 | x=width,y=height,z=1.0+1.0/width,W=1.0+1.0/height,其中width和height分别是该摄像机的渲染目标的像素宽度和高度 |
_ZBufferParams | float4 | x=1-Far/Near,y=Far/Near,z=x/Far,W=y/Far,该变量用于线性化Z缓存中的深度值 |
unity_OrthoParams | float4 | x=width,y=heigth,z=无定义,W=1.0(正交摄像机)/0.0(透视摄像机),其中width和height是正交投影摄像机的宽度和高度 |
unity_CameraProjection | float4x4 | 该摄像机的投影矩阵 |
unity_CameraInvProjection | float4x4 | 该摄像机的投影矩阵的逆矩阵 |
unity_CameraWorldClipPlanes[6] | float4 | 该摄像机的6个裁剪平面在世界空间下的等式,按左、右、下、上、近、原裁剪平面 |
11、小结
对应线性变换,使用3x3的矩阵足够表示所有变换
如果存在平移变换,我们就需要使用4x4矩阵