
什么是MVP矩阵?
MVP矩阵分别是模型(Model),观察(View),投影(Projection)三个矩阵。我们的顶点坐标起始于局部空间(Local Space),在这里它称为局部坐标(Local Coordinate),它在之后会变为世界坐标(World Coordinate),观察坐标(View Coordinate),裁剪坐标(Clip Coordinate),并最后以屏幕坐标(Screen Coordinate)的形式结束

M矩阵 模型空间 → 世界空间的转换矩阵
模型空间是以自身中心为原点的空间坐标系
世界空间是以世界中心为原点的空间坐标系
※这里提一下,在不同的建模软件或者游戏引擎中使用的坐标系是不一样的,比如OpenGL使用的的右手坐标系,DirectX实用的是左手坐标系,两种坐标系怎么区分呢?正x轴指向右面,正y轴指向上面。通过沿正x轴方向到正y轴方向握拳,大姆指的指向就是相应坐标系统的正z轴的指向。在握拳的过程中,如果是顺时针方向就是左手坐标系,如果是逆时针方向就是右手坐标系,在Unity中使用的是左手坐标系
从模型空间变换到世界空间是怎么变换的呢?
变换是左乘法则,即

在绝大多数情况下,我们约定变换的顺序就是先缩放,再旋转,再平移
为什么?可能会有小伙伴有疑问了,为什么我们要先缩放,再旋转,再平移?
※对于视频中为什么不能交换变换顺序的解释(矩阵乘法是不满足乘法交换律的)
一个三维场景中的各个模型一般需要各自建模,再通过坐标变换放到一个统一的世界空间的指定位置上,这个过程再3D图形学称作 “世界变换”,实际变换有三种,平移、旋转和缩放(实际上还有不常用的的扭曲和镜像,他们不是仿射变换),这三种变换按各种顺序执行,结果是不同的。可是实际的应用中一 般按照 缩放 → 旋转 → 平移的顺序进行。这样做的原因是可以获得最符合常理的变换结果
比方说,通过世界变换希望获得的结果可能是:
将一个放在原点的物体(比如说可乐罐)移动到(30,50),让它自身倾斜 45° ,再放大 2 倍
而不希望的结果是:
和本地坐标轴成角度的缩放(会导致扭曲,像踩扁的可乐罐)
绕自己几何中西以外位置的原点的旋转(地球公转式)和缩放
而颠倒了上述变换顺序就会得到这样不自然的结果。
具体地说:
当缩放在旋转之后进行时,会发生现象一。
当缩放和旋转在平移之后进行时会发生现象二。
这时因为:
在物体刚刚放入世界坐标系的时候使用的是本地坐标,也就是本地和全局坐标系的原点和坐标轴都是重合的(当然两者分别使用了 左右手坐标系除外,那是BUG),此时所有物体都“把世界坐标系当做 自己的本地坐标系”
而经过坐标变换后:
缩放变换不改变坐标轴的走向,也不改变原点的位置,所以两个坐标系仍然重合
旋转变换改变坐标轴的走向,但不改变原点的位置,所以两个坐标系坐标轴不再处于相同走向
平移变换不改变坐标轴走向,但改变原点位置,两个坐标系原点不再重合
所以我们需要先进行缩放,再旋转,在平移,如上节所说的那样,完全可以将缩放矩阵,旋转矩阵,平移矩阵进行矩阵乘法计算,获得最后的复合变换矩阵,

,这样计算也不会影响最终结果的
顶点坐标从模型坐标变换到世界坐标

V矩阵 世界空间 → 视觉空间的转换矩阵
视觉空间是以摄像机中心为原点的空间坐标系
※有一点需要注意的是,在视觉空间中使用的是右手坐标系
平移整个观察空间,摄像机原点和世界坐标原点重合,坐标轴重合,也就是将观察空间坐标系平移到世界空间坐标系,让两个空间坐标 系重合,就可以求出这个 View 变换矩阵
因为摄像机是在世界空间中是先旋转,再平移,为了让摄像机与世界坐标重合,所以我们需要逆变换
如何进行逆变换?
第一步我们要先进行平移,然后再进行旋转,最后对 Z 分量取反(因为世界空间坐标系是左手坐标系,而视觉空间的坐标系是右手坐标系,所以我们需要对Z分量进行取反),使用公式表达是

P矩阵 视觉空间 → 裁剪空间
1.不是真的投影,为投影做准备
2.目的:判断顶点是否在可见范围内,若在可见范围内即渲染出来,若不在范围内则将该顶点剔除掉,就如第一节所说的,对于裁剪的图形,在裁剪的位置生成新的顶点来代替

3.P矩阵:对 x,y,z分量进行缩放,用 w 分量做范围值。如果x,y,z都在 w 范围内,那么该点在裁剪空间内
计算好之后为后面的投影做准备
透视投影
什么是透视投影?符合我们人眼视觉的投影,即近大远小

正交投影
什么是正交投影?被投影的的物体没有远近之分,即正交视图

世界空间的应用
不规则平面的Tilling:以世界坐标当作 uv 进行采样

观察空间的应用
根据摄像机距离显隐变换的云朵

对于视频中shaderLab代码的介绍,在我这里就暂时不多说了,我是学过一些 shaderlab 语法(虽然目前还挺菜吧),这一块内容介绍出来就很多了,为此只需要知道一些应用场景就行,对于 shaderlab 语法等后面 May佬 的课程更新之后,我再对视频中的一些语法进行一些补充的解释
光栅化阶段的补充
教程中的小视频已经非常形象了,我也没什么好补充的,不太清楚的,多看几遍
模型空间,世界空间,观察空间的区别
模型空间
模型空间是和某个模型或者说是对象有关的。有时模型空间也被称为对象空间或局部空间。每个模型都有自己独立的坐标空间,当它移动或旋转的时候,模型空间也会跟着它移动和旋转。比如自己的游戏模型,我们移动的时候我们的模型空间也在跟着移动,我们转身时本身的前后左右方向也跟着改变。
世界空间
世界空间是一个特殊的坐标系,因为它建立了我们所关心的最大的空间。世界空间可以被用于描述绝对位置(这里指的是世界坐标系中的位置),通常我们把世界空间的原点放置在游戏空间的中心。
在 unity 中,除了观察空间(摄像机空间),所有的空间坐标系都是使用的左手坐标系。很多的效果都是要在世界空间中完成的,比如说我们想要让一个物体有凹凸感觉,这就需要后面的 May佬 的课程,切线空间,UV之间的关系来说明了,现在说就有一些超纲了…简单而言我们想要让一个物体表面生成凹凸的感觉,我们可以使用两种贴图,一种法线贴图,一种高度图 进行空间转换,在世界空间中与物体的原贴图进行混合
观察空间(摄像机空间)
最大的区别在于在观察空间中我们使用的是右手坐标系,而这个是符合OpenGL的,在观察空间中我们需要把世界空间的顶点转换到观察空间,为此我们需要求的观察空间的变换矩阵,因为坐标系的不同,所以我们需要对z轴取反,并求得逆变换,
在观察空间还有一项就是需要将观察空间的顶点转换到裁剪空间(也被称为齐次裁剪空间),这个用于变换的矩阵叫做裁剪矩阵,也被称为投影矩阵,在观察空间中并不是真正的投影,而是准备投影的数据,即那些顶点需要保留,那些需要剔除,这是由投影方式决定的