我是靠谱客的博主 阔达乐曲,最近开发中收集的这篇文章主要介绍一文带你认识 模型 视图 投影 矩阵一文带你认识 模型视图投影矩阵,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

模型(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,图不太明显),所有的蓝色物体都经过了相同的变形。因此,离摄像机近的物体就显得大一些,远的显得小一些。这和现实生活一样!
让我们从平截头体的”后面”看看它们的模样:

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

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


最后

以上就是阔达乐曲为你收集整理的一文带你认识 模型 视图 投影 矩阵一文带你认识 模型视图投影矩阵的全部内容,希望文章能够帮你解决一文带你认识 模型 视图 投影 矩阵一文带你认识 模型视图投影矩阵所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部