MVP 变换

思考一个问题,我们怎么样拍一张照片?

找一个好地方,搭好场景摆好 Pose(模型变换 model transformation)

找一个好的角度放照相机(视图变换 view transformation)

拍照!(投影变换 projection transformation)

图形学中的这三个变换简称 MVP 变换。

 

(1)视图变换

第一,我照相机放在哪。第二,我相机往哪看,第三,相机的旋转,即相机顶部朝向的方向向量。

有一个相对运动的概念,如果相机和物体是相对静止的,那么不管怎么运动,拍出来的都是不变的。

那么进一步思考,直接将相机放在一个永远固定的原点位置上,让场景中的所有物体进行运动。相机永远朝向 -z 方向上。

这是约定俗成的一件事,因为这样做可以让操作简化。

那么如何将相机从任意一种摆放,把它移动到原点位置上去?

写成矩阵形式如下:

将向量 e 变换到原点,做一个简单的平移就能实现;

但是将向量 g 变换到 -z 不好写,将向量 t 变换到 y 不好写,( g × t ) 变换到 x 也不好写。我们从反向思考,求逆变换

由左边的矩阵得到右边的矩阵的过程用到了旋转的特性,详细见图像的几何变换

现在两个矩阵都求出来了,先做旋转再做移,Mview 这个变换就叫做视图变换。相机要通过这种变换,到一个固定或约定俗成的位置上。其它所有物体也都需要跟着做这样一个变换。

(2)投影变换

投影有正交投影(Orthographic Projection)和透视投影(Perspective Projection)。由三维投影到二维。

正交投影可以看作平行光线的投影,或者相机放在无限远,更多的用于工程制图。透视投影则有一种近大远小的效果。

透视投影四棱锥中物体放置的那块区域叫做 frustum,将区域内的物体投影到近处的面上。

(2.1)正交投影

正交投影不管空间中的长方体原先是什么长宽高比,都把它映射成标准的立方体。左右、顶底、远近。

将这样一个变换写成数学的矩阵形式:

也很直观,先做一个移,再做一个缩放。为什么是 2,因为 [-1, 1] 覆盖的范围是 2,然后除以原本覆盖的范围,比如远和近是 n - f 。

(2.2)透视投影

 

普通点转为齐次坐标点有如下的概念:

面有四个点,可以看成把他们挤到和近面同一个高度上。然后就可通过正交投影把他们投影到近面上去了。

在挤的过程中,近面上的点永远不变,近面和远面的距离不会变,远面的中心点也不会变。

任意一个点它会被如何挤压,通过相似三角形是清楚的。上面表示的是 y。x 是同样的道理。

经过挤压变换后得到的向量,因为齐次坐标的性质,将它乘上 z,得到的一定是同一个点。

针对一个点,它上下如何挤压,z 不知道。现在的情况是,我希望找出 ( x, y, z, 1 ) 左边乘上的那个矩阵,把它变成右边这样,有三个数我都已经知道了,那么我现在已经可以填上若干值了。

以上矩阵除了第三行,其他数值都可以求出来。把第三行求出来,就大功告成了。

用到上面的两点:近面所有点变换前后都不会发生变化;远面所有点变换前后 z 也不会发生变化。

用近面上的点来代入,即 z = n,那么这时向量的第三个数为 n2

且因为计算的是第三行,所以与 x 和 y 都没有关系,因此矩阵的第三行必然是 ( 0 0 A B ) 的形式,A、B为待求的未知数。

得到这一个性质还不够,还不足以求出这两个未知数。

还有一个点很关键,就是远平面的中心点,变换前后不变。

最后乘以 f 是因为 z = f,根据前面的公式要求向量的第四个值为 z 。

最后解出 A = n + f,B = - nf 。得到变换矩阵为:

最后再做一次正交投影,即可得到透视投影的结果:

 

posted @   HanselHuang  阅读(189)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示