一文带你认识 模型 视图 投影 矩阵

一文带你认识 模型视图投影矩阵

模型(Model)矩阵

视图/观察(View)矩阵
投影(Projection)矩阵

利用模型、观察和投影矩阵,可以将OpenGL从模型到屏幕显示的变换过程清晰地分解为三个阶段。虽然此法并非必需,但采用此法较为稳妥。我们将看到,这种公认的方法对变换流程作了清晰的划分。


模型矩阵
这个三维模型和可爱的红色三角形一样,由一组顶点定义。顶点的XYZ坐标是相对于物体中心定义的:也就是说,若某顶点位于(0,0,0),则其位于物体的中心。


我们希望能够移动它,玩家也需要用键鼠控制这个模型。这很简单,只需记住:缩放-旋转-平移就够了。在每一帧中,用算出的这个矩阵去乘(在GLSL中乘,不是在C++中!)所有的顶点,物体就会移动。唯一不动的是世界空间(World Space)的中心。



现在,物体所有顶点都位于 世界空间 。下图中黑色箭头的意思是: 从模型空间(Model Space)(顶点都相对于模型的中心定义)变换到世界空间(顶点都相对于世界空间中心定义)。


下图概括了这一过程:





视图/观察矩阵
这里再引用一下《飞出个未来》:
*引擎推动的不是飞船而是宇宙。飞船压根就没动过。*

仔细想想,摄像机的原理也是相通的。如果想换个角度观察一座山,您可以移动摄像机也可以……移动山。后者在实际中不可行,在计算机图形学中却十分方便。
起初,摄像机位于世界坐标系的原点。移动世界只需乘一个矩阵。假如你想把摄像机向 (X轴正方向)移动3个单位,这和把整个世界(包括网格)向 (X轴负方向)移3个单位是等效的!脑子有点乱?来写代码吧:
// Use #include <glm/gtc/matrix_transform.hpp> and #include<glm/gtx/transform.hpp>
glm :: mat4 ViewMatrix = glm :: translate( - 3.0 f, 0.0 f , 0.0 f);

下图展示了: 从世界空间(顶点都相对于世界空间中心定义)到摄像机空间(Camera Space,顶点都相对于摄像机定义)的变换过程。

趁脑袋还没爆炸,来欣赏一下GLM强大的glm::LookAt函数吧:
glm :: mat4 CameraMatrix = glm :: LookAt(
cameraPosition, // the position of your camera, in world space
cameraTarget, // where you want to look at, in world space
upVector ); // probably glm::vec3(0,1,0), but (0,-1,0) would make you looking upside-down, which can be great too

下图解释了上述变换过程:


投影矩阵
现在,我们处于摄像机空间中。这意味着,经历了这么多变换后,现在一个坐标X==0且Y==0的顶点,应该被画在屏幕的中心。但仅有x、y坐标还不足以确定物体是否应该画在屏幕上:它到摄像机的距离(z)也很重要!两个x、y坐标相同的顶点,z值较大的一个将会最终显示在屏幕上。
这就是所谓的透视投影(perspective projection):

好在用一个4x4矩阵就能表示这个投影 :
// Generates a really hard-to-read matrix, but a normal, standard 4x4 matrix nonetheless
glm :: mat4 projectionMatrix = glm :: perspective(
FoV, // The horizontal Field of View, in degrees : the amount of "zoom". Think "camera lens". Usually between 90&deg; (extra wide) and 30&deg; (quite zoomed in)
4.0 f / 3.0 f, // Aspect Ratio. Depends on the size of your window. Notice that 4/3 == 800/600 == 1280/960,
0.1 f, // Near clipping plane. Keep as big as possible, or you'll get precision issues.
100.0 f ); // Far clipping plane. Keep as little as possible.

最后一个变换:
从摄像机空间(顶点都相对于摄像机定义)到齐次坐空间(Homogeneous Space)(顶点都在一个小立方体中定义。立方体内的物体都会在屏幕上显示)的变换。
最后一幅图示:





再添几张图,以便大家更好地理解投影变换。投影前,蓝色物体都位于摄像机空间中,红色的东西是摄像机的平截头体(frustum):这是摄像机实际能看见的区域。


用投影矩阵去乘前面的结果(模型->视图),得到如下效果:



此图中,平截头体变成了一个正方体(每条棱的范围都是-1到1,图不太明显),所有的蓝色物体都经过了相同的变形。因此,离摄像机近的物体就显得大一些,远的显得小一些。这和现实生活一样!
让我们从平截头体的”后面”看看它们的模样:

这就是您得到的图像!看上去太方方正正了,因此,还需要做一次数学变换使之适合实际的窗口大小。

这就是实际渲染的图像啦!


  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值