MVP变换
Model_Matrix
模型矩阵意在将模型空间中的坐标映射到世界空间
遵循先缩放,后旋转,再平移的顺序
View_Matrix
视图矩阵意在将世界空间中的坐标映射到观察空间
0.分析
当摄像机拍摄某一个物体时,如果摄像机的位置和朝向发生了变化,则成像也会变化。
但是如果给物体施加以和摄像机相同的变换,则成像就不会发生变化。
即当相机和物体的相对位置没有发生变化的时候,成像不变。
因此,我们可以将摄像机的的位置,变换到原点,并将旋转归零。
再将相同的变换操作应用到物体上,即可得到物体的观察空间坐标。
1.先将摄像机位置归于原点
摄像机的位置
则将摄像机归于原点的变换矩阵为:
2.将摄像机的旋转归零
继续分析,以X轴方向为例。
其实我们很难将 摄像机空间中的X轴方向 变换到 世界空间中的X轴方向
但是,反过来想,我们却可以很轻易地做到
我们将X轴视为右方向,则可以有
然后我们将这个简单的操作重复到Y轴和Z轴上,即可得到旋转矩阵
又因为旋转矩阵的特殊性,即旋转矩阵的逆矩阵等于旋转矩阵的转置矩阵,因此我们便得到了我们想要的矩阵
注:方向向量都是单位向量
注:forward是负数,是约定了相机看向-z方向,forward = target - eye
3.结论
由以上步骤,我们得到最终的View_Matrix
Projection_Matrix
投影矩阵意在将观察空间中的坐标映射到裁剪空间(Clip Space)
投影分为两种类型,正交投影,和透视投影
1.正交投影
在图形学中,我们借助构建标准立方体[-1,1],来确定投影范围
确定投影空间的边界,有如下参数(参数来源自摄像机)
l : 左
r : 右
t : 上
b : 下
n : 近平面
f : 远平面

先将标准立方体位移至原点
然后在缩放至标准立方体的大小
大小是[-1,1],所以每个边界的长度是2
最后我们就得到了正交投影矩阵
2.透视投影
关于透视投影,我们可以先将透视投影的视锥体(frustom)的远平面"挤压",将远平面的大小变换成与近平面相同,再乘以我们已经知晓答案的正交投影矩阵,即可完成透视投影矩阵

根据下图的相似三角形

我们可以很轻易地得出X和Y经过变化后的结果,即
由此,我们可以先推到出部分透视->正交矩阵,即
接下来,将要推导Z的部分,通过分析 [透视->正交变换示意图]
我们可以得到如下两条结论:
1.通过透视->正交矩阵变换后,近平面上的任意点,没有发生任何变化
2.通过透视->正交矩阵变换后,远平面上的中心点,没有发生任何变化
根据1结论,我们可以得出如下推导
根据上面的推导,我们可以进一步假设透视->正交矩阵的一部分
进而得出等式1:
根据2结论,我们可以得出如下推导
根据上面的推导,我们可以进一步假设透视->正交矩阵的一部分
进而得出等式2:
至此,我们的除了两条等式,求解即可得到
最终我们得到了完成的透视->正交矩阵
3.结论
写在最后
以上推导过程,来自Games101课程
虽然过程没有任何问题
但是,在做作业01的时候,发现作业的代码,如果完全按照课程推导出的矩阵带入的话,得到的结果会颠倒,如图

通过查阅资料,和自己的一点点思考后,发现,问题出在
因为在视图变换中,我们规定相机看向了
我个人是简单地将【透视->正交矩阵】做了一点简单的修改
这样即可得到正确的结果:

也有文章指出,是因为参数中的
但是我认为,这种做法,还有包括我的做法,都是不太对的。
另有文章指出,《虎书》中推导的矩阵代入程序也是正确的。
其实到这一步还没学习到光栅化,深度测试等内容,所以,无所谓啦,之后也得再看看《虎书》的。
2025.05.07 更新
// 颠倒的解决方法
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
{
...
// 做上下翻转操作
// 看起来是对的,那就是对的
float t = -1 * tan(fov_Radian_Half) * zNear; // 上边界
...
}最后!!!
关于图形学的学习,其实很早很早就开始了,但也总是中断,都没有坚持。加上工作忙且与渲染相关的需求其实并不多,就一直搁置,希望这次可以好好学到底,加油哦~
引用图形学里一句经典的话