数学基础
矩阵变换
线性变换(Linear Transform)
- 可以保留矢量加和标量乘的变换,即f(x)+f(y)=f(x+y),kf(x)=f(kx),可以用3×3矩阵表示
- 线性变换包括缩放、旋转、错切、镜像、正交投影等变换
- 平移变换满足标量乘法,但不满足标量加法,不是线性变换,不能用3×3矩阵表示
仿射变换(Affine Transform)
- 合并线性变换和平移变换的变换
- 仿射变换可以用4×4矩阵表示,把三维矢量扩展到四维空间,就是齐次坐标空间(Homogeneous Space)
齐次坐标(Homogeneous Coordinate)
- 三维矢量转换为四维坐标即齐次坐标(四维齐次坐标)
- 对于一个点,从三维坐标转换为齐次坐标是把w分量设为1,对于方向向量,把w分量设为0
- 当用一个4×4矩阵对一个点进行变换时,线性变换和平移变换都会作用于该点,但对一个方向矢量进行变换时,平移变换会被忽略
基础变换矩阵
- 表示纯平移、纯旋转和纯缩放的变换矩阵叫做基础变换矩阵
- 可以把一个基础变换矩阵分解为4个部分:
[M3×301×3t3×11]
-
M3×3用于表示旋转和缩放,t3×1用于表示平移
平移矩阵
- 对点进行平移变换
⎣⎢⎢⎡100001000010txtytz1⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡x+txy+tyz+tz1⎦⎥⎥⎤
- 对方向矢量进行平移变换
⎣⎢⎢⎡100001000010txtytz1⎦⎥⎥⎤⎣⎢⎢⎡xyz0⎦⎥⎥⎤=⎣⎢⎢⎡xyz0⎦⎥⎥⎤
- 平移矩阵的逆矩阵就是反向平移得到的矩阵
⎣⎢⎢⎡100001000010−tx−ty−tz1⎦⎥⎥⎤
- 平移矩阵非正交矩阵
缩放矩阵
⎣⎢⎢⎡kx0000ky0000kz00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡kxxkyykzz1⎦⎥⎥⎤
- 如果kx=ky=kz,这样的缩放称为统一缩放,否则称为非统一缩放
- 缩放矩阵的逆矩阵是使用原缩放系数的倒数来对点或方向矢量进行缩放
⎣⎢⎢⎡kx10000ky10000kz100001⎦⎥⎥⎤
- 缩放矩阵一般不是正交矩阵
旋转矩阵
- 绕x轴旋转θ度
⎣⎢⎢⎡10000cosθsinθ00−sinθcosθ00001⎦⎥⎥⎤
- 绕y轴旋转θ度
⎣⎢⎢⎡cosθ0−sinθ00100sinθ0cosθ00001⎦⎥⎥⎤
- 绕z轴旋转θ度
⎣⎢⎢⎡cosθsinθ00−sinθcosθ0000100001⎦⎥⎥⎤
- 旋转矩阵是正交矩阵
复合变换
- 一般先缩放,再旋转,最后平移
- 给定一个旋转顺序(如zyx)以及它们对应的旋转角度(θx,θy,θz),有两种坐标系可以选择,把它们的旋转顺序颠倒一下,得到的结果就一样
- 绕坐标系E下的z轴旋转θz,绕坐标系E下的y轴旋转θy,绕坐标系E下的x轴旋转θx,即进行一次旋转时不一起旋转当前坐标系
- 绕绕坐标系E下的z轴旋转θz,在坐标系E下再绕z轴旋转θz后的新坐标系E′下的y轴旋转θy,在坐标系E′下再绕y轴旋转θy后的新坐标系E′′下的x轴旋转θx,即在旋转时,把坐标系一起转动
- 给出(θx,θy,θz)这样的旋转角度时,需定义一个旋转顺序,在Unity中,这个旋转顺序是zxy(第一种情况),即复合旋转变换矩阵为
MrotatθZMrotatθXMrotatθY=⎣⎢⎢⎡cosθsinθ00−sinθcosθ0000100001⎦⎥⎥⎤⎣⎢⎢⎡10000cosθsinθ00−sinθcosθ00001⎦⎥⎥⎤⎣⎢⎢⎡cosθ0−sinθ00100sinθ0cosθ00001⎦⎥⎥⎤
坐标空间
坐标空间的变换
- 定义一个坐标空间,必须指明其原点位置和3个坐标轴的方向,这些数值实际上是相对于另一个坐标空间的,因此,坐标空间会形成一个层次结构——每个坐标空间都是另一个坐标空间的子空间,每个空间都有一个父坐标空间,对坐标空间的变换实际上就是在父空间和子空间之间对点和矢量进行变换
- 假设有父坐标空间P和子坐标空间C,已知子坐标空间C的3个坐标轴在父坐标空间P下的表示xc、yc、zc,以及其原点位置Oc
- 把子坐标空间下表示的点或矢量Ac转换到父坐标空间下的表示Ap,可以使用从子坐标空间变换到父坐标空间的变换矩阵Mc→p,Ap=Mc→pAc
- 把父坐标空间下表示的点或矢量Bp转换到子坐标空间下的表示Bc,可以使用Mc→p的逆矩阵Mp→c,Bc=Mp→cBp
Mc→p=⎣⎢⎢⎡∣xc∣0∣yc∣0∣zc∣0∣Oc∣1⎦⎥⎥⎤
- 对方向矢量的坐标空间变换,坐标空间的原点变换可以忽略,变换矩阵可以用3×3矩阵
Mc→p=⎣⎡∣xc∣∣yc∣∣zc∣⎦⎤
- 若Mc→p为正交矩阵
Mp→c=Mc→pT=⎣⎡−−−xcyczc−−−⎦⎤
- 从变换矩阵也可以获取子坐标空间的原点和坐标轴方向
- 在渲染流水线中,一个顶点经过多个坐标空间的变换最终被画在屏幕上,一个顶点最开始是在模型空间中定义的,最后变换到屏幕空间中,得到真正的屏幕像素坐标
模型空间(Model Space)
- 模型空间又称对象空间(Object Space)或局部空间(Local Space),是每个模型独立的坐标空间,随着模型移动和旋转
世界空间(World Space)
- 世界空间是我们所关心的最大、最外层的坐标空间,可以用于描述绝对位置
- 顶点变换的第一步,就是将顶点坐标从模型空间变换到世界空间中,这个变换称为模型变换(Model Transform)
观察空间(View Space)
- 观察空间又称摄像机空间(Camera Space),摄影机位于原点
- Unity中模型空间和世界空间使用左手坐标系,观察空间使用右手坐标系
- 顶点变换的第二步,就是将顶点坐标从世界空间变换到观察空间中,这个变换称为观察变换(View Transform)
裁剪空间(Clip Space)
- 顶点变换的第三步,从观察空间转换到裁剪空间,变换矩阵叫做裁剪矩阵(Clip Matrix),又称投影矩阵(Projection Matrix)
- 裁剪空间的目标是能够方便地对渲染图元进行裁剪:完全位于这块空间内部的图元将会被保留,完全位于这块空间外部的图元将会被剔除,而与这块空间边界相交的图元就会被裁剪,这块空间由视锥体来决定
- 视锥体(View Frustum)是摄像机可以看到的空间,由六个平面包围而成,这些平面也称为裁剪平面(Clip Planes),包括近裁剪平面(Near Clip Plane)、远裁剪平面(Far Clip Plane)和侧面的4个裁剪平面
- 投影有两种类型:正交投影(Orthographic Projection)和透视投影(Perspective Projection),在透视投影中,平行线不会保持平行,离摄像机越近网格越大,离摄像机越远网格越小,模拟了人眼看世界的方式,视锥体是金字塔形。在正交投影中,平行线保持平行,完全保留了物体的距离和角度,视锥体是长方体
- 透视投影:
-
Field of View(FOV): 视锥体竖直方向的张开角度
-
Near: 近裁剪平面与摄像机的距离
-
Far: 远裁剪平面与摄像机的距离
-
Aspect: 摄像机的横纵比
Mfrustum=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡Aspectcot2FOV0000cot2FOV0000−Far−NearFar+Near−100−Far−Near2⋅Near⋅Far0⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
Pclip=MfrustumPview
=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡Aspectcot2FOV0000cot2FOV0000−Far−NearFar+Near−100−Far−Near2⋅Near⋅Far0⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡xAspectcot2FOVycot2FOV−zFar−NearFar+Near−Far−Near2⋅Near⋅Far−z⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
- 视锥体内的顶点变换后的坐标满足:−w≤x,y,z≤w
- 正交投影:
-
Size: 视锥体竖直方向上高度的一半
Mfrustum=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡Aspect⋅Size10000Size10000−Far−Near2000−Far−NearFar+Near1⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤
Pclip=MfrustumPview
=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡Aspect⋅Size10000Size10000−Far−Near2000−Far−NearFar+Near1⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡Aspect⋅SizexSizey−Far−Near2z−Far−NearNear+Far1⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤
屏幕空间(Screen Space)
- 完成裁剪工作后,把顶点从裁剪空间投影到屏幕空间中,来生成对应的2D坐标
- 标准齐次除法(Homogenous Division)又称透视除法(Perspective Division),即用齐次坐标系的w分量去除以x、y、z分量,得到归一化的设备坐标(Normalized Device Coordinates,NDC)
- 把NDC坐标映射到窗口的对应像素坐标(Unity中屏幕空间原点为左下角)
screenx=2⋅clipwclipx⋅pixelWidth+2pixelWidth
screeny=2⋅clipwclipy⋅pixelHeight+2pixelHeight
法线变换
- 变换一个模型时,不仅需要变换顶点,还需要变换顶点法线,以便后续计算光照
- 变换法线时使用同一个变换矩阵,可能无法确保维持法线的垂直性
- 根据同一个顶点的切线和法线满足垂直条件可求得变换矩阵为(MA→B−1)T
- 如果变换矩阵是正交矩阵,(MA→B−1)T=MA→B,如果只包括旋转变换,那么这个变换矩阵就是正交矩阵。如果只包含旋转和统一缩放,而不包含非统一缩放,(MA→B−1)T=k1MA→B。如果包含非统一变换,则需要求解逆矩阵。
Unity Shader的内置变量
变换矩阵
摄像机和屏幕参数
参考: 《Unity Shader入门精要》
个人博客传送门: 十七小栈
相关文章: