RuaYiii
RuaYiii

个人频道:https://t.me/justAboringchannel |PM友好型 | BUPT 瞎看点什么,留下点什么。

【学点记点】MVP矩阵

(编辑过)
学习的摘要快照,唉,讲给自己听。还有一点要事先说一下,可能由于定义的坐标系不同,不同地方的公式中负责z轴的地方可以看到不同+-符号上的差异,这些都无所谓,因为只要反转z轴,就可以完成左右手坐标系的互换。

模型和世界和摄像机

或许该从坐标系讲起,对于一个物件,一个3d模型资产,它有自己的坐标系 x-y-z,或许以它的中心为坐标原点,我们用以描述模型内部相对位置的这个空间、这个场所——我们称之为 模型空间

但是一个单独物件很少作为一个场景运作,我们会在一个场景、或者是一个世界里,我们把这一个个模型塞在这个世界里,但是坐标系肯定不是之前以某个模型为中心的坐标系了,我们会重新以某个世界原点建立世界坐标系,我们又在这里描述物件们的相对位置,这个场所——我们称之为 世界空间

在多考虑一步,世界、模型这些都是他者,有别于此的是主体的视角(这点很重要,我们通过显示器看到的就是这个视角就是摄像机的视角,我们需要这样一个观察者,它有着自己的位置,朝向,还有视野范围,唉 总之 这个场所——我们称之为 观察空间

但是实际上,坐在屏幕前的我们看到的不是这些空间本身,我们透过一个平面的屏幕看到摄像机的传给我们的信息,平面的、经过裁剪过的影像,唉 总之这个、、算是空间吧——我们称之为 裁剪空间

这四个空间是 彼此之间相互转化的一个关系:模型 -> 世界 -> 观察 -> 裁剪

从一个空间到另一个空间的变化伴随着坐标的改变,实际上,这玩意我们通过矩阵运算实现这种变换,如下就是三个矩阵:

  • 模型矩阵(Model)

  • 观察矩阵(View)

  • 投影矩阵(Projection)

取其首字母,这三个玩意就是MVP矩阵,还挺好记的。

模型空间—M矩阵—世界空间

M矩阵不是一个单一的矩阵,我们描述模型空间的变换往往伴随着 三个操作 缩放旋转平移

而这三个操作依次进行的结果就是M矩阵

值得注意的是,我们的矩阵运算是左乘,所以 经过对应的缩放旋转平移 之后,我们从空间A变换到空间B:B=M*A

而且这个顺序是不能变的,因为一个物件出现世界,一般都是 在原点,此时缩放、旋转的操作需要一个中心,在不进行移动的时候这个中心在模型和世界空间是重合的,所以先进行这个操作,最后进行平移

  • 虽然是x-y-z三个维度,但是你可能发现下面的矩阵形式是四维的,这是因为平移变换不是齐次的,所以额外引入一个维度: 4*4的一个矩阵

  • 值得注意的是,中间这个旋转矩阵的形式是依据你旋转的的轴,比如上面的公式就是绕x轴旋转

世界空间—V矩阵—观察空间

  • C=V*B

其实摄像机也只是一个物件,其实可以把这个过程理解为 M矩阵过程的反向,但是摄像机一般没有缩放

  • 显然摄像机的视角立足于世界空间,由于涉及旋转中心,所以首先要将世界原点和摄像机移动重合起来,所以是先平移再旋转,但是摄像机不会缩放吧,我们可以把它理解成徒有位置和朝向的单一点,缩放不具备意义,但是再一些引擎中,摄像机的坐标系和世界坐标系不是一个方向(比如unity,所以最后处理的时候会反向z轴,如下

观察空间—P矩阵—裁剪空间【这个比较复杂】

  • 再观察空间里,我们实际还是三维中的点(虽然是4*4),但是在投影过程中,我们需要把这些三维信息映射到二维屏幕上,但实际上我们P矩阵不是这一步

  • D=P*C 得到的D仍旧是一个三维空间,他不是一个最后投影的结果,但是在为投影做准备。裁剪空间的目的是帮助判断顶点是否可见。

我们可以用这种方式理解这个裁剪空间:裁剪空间是一个111的区域,我们需要把视锥体里的内容压缩到这个区域,那除此之外的东西都是我们看不到的,以这种方式进行所谓的裁剪。

一般投影有两种:一种是正交投影、一种是透视投影

前者就是 无论远近,一样大的东西怎么看都是一样的大小

后者则是 我们人眼的 近大远小

为了理解投影,我们需要引入视锥体这一概念: 这是透视摄像机可以看到和渲染的区域的形状

就像一个被切掉了尖端的金字塔,由远近两个平行的矩形接连而成的区域,若是相同,这就成了一个长方体(此时为正交投影);若是不一样,那就是透视投影

先考虑正交投影吧,我们需要 把一个长方体变换到一个中心位于原点,坐标范围[-1,1]的立方体,因此通过移动加缩放即可完成变换,我们知道本身 视锥体 长方形的 长宽高 ,以及某个点在摄像机空间中的位置,则对于当前长方体的中心点位置就是 ((r+l)/2,(t+b)/2,(n+f)/2),则平移矩阵是

然后根据长宽高 进行缩小,由于由于我们本身就是 (r-l)/2,(t-b)/2,(n-f)/2

由于大数减小数还是正的,然后缩小就放大系数的倒数,则缩放系数是

先平移后缩放,合并一下就是:

这就是正交投影的全部, 透视投影比起这玩意更复杂点

而透视投影的视锥体近处的矩形和远处的矩形是不一样的,所以我们可以先进行一个类似挤压的操作,把远处的矩形挤压到和近处的一致,经过这一处理之后的视锥体就和正交投影一样了,直接套用正交投影的P矩阵就完事了。

那现在开始专注这个挤压操作,来个图可能比较直观吧

但对于我们举证来讲这个每个点的xyz都只是过客,对于xy的变动,用 n/z = x’ /x

这里等比关系可推理处压缩矩阵的x y 的变换参数,这也是一个类似缩放的齐次变换,

为了好看大家都乘z ,但是经过变换齐次的那个 1 会变成 z ,根据这个规则,我们的最后一行用(0 0 1 0) 就能完成这个变换

现在是这样的:

但是z轴呢?

其实z轴的缩放和位移我们是不知道的,,但挤压后的某些结果我们是知道的:

  • 一个是近平面

对于本来就是在近平面的点,也就是z为n的点,则经过挤压后其齐次坐标为,下图

对于远平面上的也是,但是n变成f, 然后讨论 x ,y 为 0的情况

则我们我们只抽出对z轴产生影响的那行,设缩放为A, 位移为B,则有

也就可以得到 A*n+B=n^2

同理 也有 A*f+B=f^2 唉 然后联立求解就可以得到: A=n+f ; B=-n*f

我的想法是:之所以要这么得到如下的矩阵,是因为本身 这个压缩就是我们制定的规则,所以需要特例点回溯性建构出这个矩阵。那么现在则结果如下

然后直接套用上一步的正交投影的矩阵,那透视投影的p矩阵就长这样子了

唉 捋一下清晰多了

CC BY-NC-ND 4.0 版权声明

第一个支持了这篇作品
加载中…

发布评论