4.opengl中变换

变换

1.向量

向量有一个方向(Direction)和大小(Magnitude,也叫做强度或长度)。

数学家喜欢在字母上面加一横表示向量,比如说v¯v¯。当用在公式中时它们通常是这样的:

在这里插入图片描述

1.1.向量相乘

1.1.1.点乘

在这里插入图片描述

我们该如何计算点乘呢?点乘是通过将对应分量逐个相乘,然后再把所得积相加来计算的。

在这里插入图片描述

1.1.2.叉乘

叉乘只在3D空间中有定义,它需要两个不平行向量作为输入,生成一个正交于两个输入向量的第三个向量。如果输入的两个向量也是正交的,那么叉乘之后将会产生3个互相正交的向量。

在这里插入图片描述

下面你会看到两个正交向量A和B叉积:

在这里插入图片描述

2.矩阵

2.1.矩阵相乘

相乘还有一些限制:

  1. 只有当左侧矩阵的列数与右侧矩阵的行数相等,两个矩阵才能相乘。
  2. 矩阵相乘不遵守交换律(Commutative),也就是说A⋅B≠B⋅AA⋅B≠B⋅A。

相乘规则实例:

在这里插入图片描述

2.2.矩阵与向量相乘

如果我们有一个M×N矩阵,我们可以用这个矩阵乘以我们的N×1向量,因为这个矩阵的列数等于向量的行数,所以它们就能相乘。用这个矩阵乘以我们的向量将变换(Transform)这个向量。

2.3.单位矩阵

在OpenGL中,由于某些原因我们通常使用4×4的变换矩阵,而其中最重要的原因就是大部分的向量都是4分量的。我们能想到的最简单的变换矩阵就是单位矩阵(Identity Matrix)。单位矩阵是一个除了对角线以外都是0的N×N矩阵。

在这里插入图片描述

3.缩放

如果我们把缩放变量表示为(S1,S2,S3)我们可以为任意向量(x,y,z)定义一个缩放矩阵:

在这里插入图片描述

4.位移

在4×4矩阵上有几个特别的位置用来执行特定的操作,对于位移来说它们是第四列最上面的3个值。如果我们把位移向量表示为(Tx,Ty,Tz),我们就能把位移矩阵定义为:

在这里插入图片描述

向量的w分量也叫齐次坐标。想要从齐次向量得到3D向量,我们可以把x、y和z坐标分别除以w坐标。我们通常不会注意这个问题,因为w分量通常是1.0。

5.旋转

沿x轴旋转:

在这里插入图片描述

沿y轴旋转:

在这里插入图片描述

沿z轴旋转:

在这里插入图片描述

但是对于3D空间中的旋转,一个更好的模型是沿着任意的一个轴,比如单位向量 ( 0.662 , 0.2 , 0.7222 ) (0.662, 0.2, 0.7222) (0.662,0.2,0.7222)旋转,而不是对一系列旋转矩阵进行复合。这样的一个(超级麻烦的)矩阵是存在的,见下面这个公式,其中(Rx,Ry,Rz)代表任意旋转轴:

在这里插入图片描述

扩展部分:

上述绕轴旋转,和绕任意轴旋转存在万向节死锁问题(绕任意轴旋转会极大地避免)。避免万向节死锁的解决方案是使用四元数(Quaternion),它不仅更安全,而且计算会更有效率。万向锁,四元数不在此展开,需要时,单独了解。

6.矩阵的组合

使用矩阵进行变换的真正力量在于,根据矩阵之间的乘法,我们可以把多个变换组合到一个矩阵中。

实例:

在这里插入图片描述

在这里插入图片描述

用整合后的单个矩阵乘以向量,实现向量先缩放2倍,然后位移了(1, 2, 3)个单位。

7.GLM&OpenGL实例

// 4*4单位矩阵
glm::mat4 transform = glm::mat4(1.0f); 
// transform=transform*glm::vec3(0.5f, -0.5f, 0.0f)对应的平移矩阵
transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f));
// transform=transform*[glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f)]所确定的旋转矩阵
transform = glm::rotate(transform, glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
        
ourShader.use();
// 获得着色器中命名uniform变量位置
unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
// 用于设置着色器中类型mat4的变量
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));

对glUniformMatrix4fv:

第二个参数告诉OpenGL我们将要发送多少个矩阵,这里是1。第三个参数询问我们是否希望对我们的矩阵进行转置(Transpose),也就是说交换我们矩阵的行和列。OpenGL开发者通常使用一种内部矩阵布局,叫做列主序(Column-major Ordering)布局。GLM的默认布局就是列主序,所以并不需要转置矩阵,我们填GL_FALSE。最后一个参数是真正的矩阵数据,但是GLM并不是把它们的矩阵储存为OpenGL所希望接受的那种,因此我们要先用GLM的自带的函数value_ptr来变换这些数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值