您的位置:首页 > 运维架构

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

2018-02-24 17:39 465 查看

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

模型(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.0f, 0.0f ,0.0f);
下图展示了:从世界空间(顶点都相对于世界空间中心定义)到摄像机空间(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 nonethelessglm::mat4 projectionMatrix = glm::perspective( FoV, // The horizontal Field of View, in degrees : the amount of "zoom". Think "camera lens". Usually between 90° (extra wide) and 30° (quite zoomed in) 4.0f / 3.0f, // Aspect Ratio. Depends on the size of your window. Notice that 4/3 == 800/600 == 1280/960, 0.1f, // Near clipping plane. Keep as big as possible, or you'll get precision issues. 100.0f ); // Far clipping plane. Keep as little as possible.
最后一个变换:从摄像机空间(顶点都相对于摄像机定义)到齐次坐空间(Homogeneous Space)(顶点都在一个小立方体中定义。立方体内的物体都会在屏幕上显示)的变换。最后一幅图示:


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


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


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


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


这就是实际渲染的图像啦!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息