首页 > 编程知识 正文

OpenGL 矩阵变换顺序与MVP矩阵变换,矩阵初等变换的顺序

时间:2023-05-05 09:19:23 阅读:222869 作者:537

一、矩阵变换的顺序

对于一个坐标点,一般都是先缩放、后旋转、最后平移,

但是变换矩阵是和变量进行右乘的,所以要先计算平移矩阵、再旋转、再计算缩放。

这里重点讲述矩阵变换为什么一定要按照缩放、旋转、平移的顺序,不然就会出错。

矩阵变换的顺序解释参考:https://blog.csdn.net/pizi0475/article/details/9840921,这篇博客做了一些简单讲述,但是还不够详细清楚。

首先要知道这些矩阵变换是用来干什么的,当我们把一个物体从一个坐标系放入到另一个坐标系中,这两个坐标系可以视为是完全重合的(但是这个时候所有的顶点的坐标都是在新坐标系下的,只不过在没有进行变换的时候,这些坐标的xyz是和原坐标系下相同的,做过变换之后就不同了,但是不要混淆了这一点,到了新坐标系下,所有的顶点坐标都是基于新坐标系的),我们要做的,就是把物体放置到一个合适的位置(平移变换),摆放一个合适的角度(旋转变换),调整到一个合适的大小(缩放变换),然后再重新计算在新坐标系下顶点坐标。那如何计算呢,我们必须先知道如何计算,才能知道为什么变换顺序不能打乱,这是一切一切的基础。

先以缩放变换举例,一个坐标(x,y,z)放大到2倍,通过矩阵的计算公式,它的坐标会变化为(2x,2y,2z),这个时候就必须要明确一点,这个缩放的原点以及缩放的方向是什么,对于x,它缩放的原点就是坐标系的原点,缩放的方向就是(1,0,0),缩放的倍数是2,记住,它的缩放是以这组数据为参数的,这个参数的数据只和矩阵里的那四行四列也就是你设置的数字有关,与其它坐标系什么的都没有关系,甚至于要明白,缩放矩阵的只是为了设置缩放的大小,理论上对于所有的旋转矩阵来说,它的缩放方向和缩放的参考点都还是原来的那些参数。

那如果我们先旋转再缩放会出现什么情况呢?我们可以在世界变换中分析一下这个问题,其它类型的变换都是类似的。

先旋转,旋转之后再缩放,我们希望的效果是这个物体依然能够按照模型坐标系来进行缩放,可事实确实它的缩放变换矩阵还是那个矩阵,也就是意味着对于x来说,它缩放的方向仍然是(1,0,0),但这是世界坐标系下的(1,0,0)了,而不是模型坐标系下了,所以理所当然要出问题。

平移后再旋转的问题也可以类似分析,顶点的旋转必须要知道的两个参数,旋转轴和旋转角度,而旋转轴又需要通过旋转方向和一个点的坐标来确定。分析旋转矩阵里的行列数字就可以知道,旋转的方向由不同旋转矩阵分别指定,但是旋转的轴心点就是原点(0,0,0),而且对于所有的旋转矩阵都是如此,所以如果平移之后再旋转,我们本是希望物体能按照自己本地坐标系下的原点进行旋转,但是它的旋转矩阵已经决定了它只能按照世界坐标系下的(0,0,0)进行旋转,所以就会出错。

二、mvp矩阵与基础矩阵变换联系

mvp矩阵即模型矩阵,观察矩阵和投影矩阵,前两个矩阵都是由上面三种基础矩阵变换生成的。

其中,模型矩阵用来从模型坐标系变换到世界坐标系中,主要用到平移变换,旋转变换和放缩变换。

观察变换就是从世界坐标系下变换到观察坐标系下,就是在世界坐标系下设置个观察点(相机位置以及相机方向),然后把世界坐标系下的坐标变换到相机空间,主要用到平移变换和旋转变换。对于摄像机来说,如果它在世界空间中的位置是(0,0,3),那么我们如果要转换到观察坐标系下,就要把物体所有的顶点向z轴负方向移动三个单位,因为摄像机向前移动就相当于物体向后移动。所以在计算高光的时候,我们通常要获取观察点的位置,这个观察点的位置正好和观察矩阵中的平移矩阵的平移向量相反。

先进行模型矩阵的计算,后进行观察矩阵,那么问题来了,有可能你在模型矩阵里进行平移,之后在观察矩阵里进行了旋转,这不就出现了上面讲到的错误顺序了吗,其实在观察矩阵里,我们改变观察点就相当于反向改变顶点位置,我们就是要围绕观察坐标系的原点进行变换,而不是绕着物体的原点进行变换了,想想一下一个外围的相机绕着正方体转一圈,不就是相当于正方体绕着相机旋转一圈吗。

投影矩阵是不同于上面两个的,OpenGL提供了专门的接口来创建。

注意:在一幅画面当中,我们只有一个相机能作为当前相机,也就是所有物体的观察矩阵必须是相同的,不能在一个场景中同时为物体设置不同的观察矩阵,也就是设置不同的相机,那样渲染的画面肯定是错误的结果。

三、矩阵的平移、旋转和缩放

3D坐标为什么要用四维向量表示:因为三维矩阵不能做平移操作,所以我们需要将三维矢量转换为四维矢量;

转换方式:前三个坐标代表了x,y,z,第四个w要么扩展为1,1说明(x,y,z)的意义是一个坐标点;要么扩展为0,0代表(x,y,z)的意义是一个向量。这个是有很多应用的,例如zyddb学习不同的光源类型的时候,第四个分量可以帮助我们来区分方向光和点光源;

旋转矩阵的计算,参考:http://www.cnblogs.com/meteoric_cry/p/7987548.html,还可以直接使用和差角公式来计算。

绕x轴进行旋转(在yz平面顺时针旋转)

 

绕y轴进行旋转(在zx平面顺时针旋转)

 

绕z轴进行旋转(在xy平面顺时针旋转)

这里绕x轴和z轴很类似,但是y轴却不同,区别就是绕y轴是在zx平面内,而不是xz平面内,所以如果是在xz内,它的角度就是负的,那么sin(-A)=-sin(A),这就理清了。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。