旋转矩阵的问题(openGL/glm)[关闭]

Posted

技术标签:

【中文标题】旋转矩阵的问题(openGL/glm)[关闭]【英文标题】:issues rotating a matrix (openGL/glm) [closed] 【发布时间】:2020-07-07 22:12:11 【问题描述】:

我最近一直在创建一个基本的 gui,我试图让用户能够旋转形状/图像/精灵。但是,当我使用 glm::rotate 尝试更改模型矩阵时,我得到了一些意想不到的结果。转换后的形状会改变尺寸,旋转太远,并且还会围绕看似随机的点旋转。

着色器代码:

#version 330 core

layout(location = 0) in vec2 pos;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;

void main()

    gl_Position = projection * view * model * vec4(pos.x, pos.y, 1.0f, 1.0f);

轮换代码:

m_modelMatrix = glm::mat4(1.0f);
m_modelMatrix = glm::rotate(m_modelMatrix, 45.f, glm::vec3(0, 0, 1);

查看和投影设置

glm::mat4 proj = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
proj = glm::perspective(glm::radians(53.f), 1.f, 0.1f, 100.f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));  

一切都是二维的。

【问题讨论】:

度数通常用弧度指定,45.f 是一个巨大的值。 是的,对不起,我本来打算写 glm::radians(45.f)。但是,无论哪种方式,它仍然无法正常工作。 您必须使用投影矩阵,它负责处理视口的纵横比。此外请注意,对象围绕 (0, 0) 旋转。 我确实有一个投影矩阵和一个视图矩阵。 @cummiesinmytummy 请用当前代码更新问题并显示投影矩阵的设置方式。 【参考方案1】:

欢迎来到堆栈溢出! :)

我假设您已经有了一个带有投影和视图矩阵的设置,就像您在 cmets 中指出的那样。应该是这样的,

#version 330 core

layout(location = 0) in vec2 pos;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

void main()

    gl_Position = projection * view * model * vec4(pos.x, pos.y, 1.0f, 1.0f);

投影矩阵应该是用

创建的
glm::ortho( ... );

glm::perspective( ... );

并且应该已经创建了视图矩阵

glm::lookAt( ... );

如https://glm.g-truc.net/0.9.2/api/a00245.html 中所述。 如果需要进一步解释,我建议您查看https://learnopengl.com/Getting-started/Coordinate-Systems 作为参考。

我还假设问题源于之前的转换以及如何使用这种旋转来修改现有模型矩阵。例如。仅当您指定了除单位矩阵以外的模型矩阵时,才会出现此问题。

创建模型矩阵时,必须确保使用正确的乘法顺序:

glm::mat4 translation = ... ;
glm::mat4 rotation = ... ;
glm::mat4 scale = ... ;
glm::mat4 model = translation * rotation * scale;

由于您要将右侧的向量乘以模型矩阵,因此此顺序可确保不会发生失真。向量会先缩放,然后旋转,最后平移。

当您尝试旋转模型矩阵时,

glm::rotate(model, angle, axis);

您实际上是从右侧乘以旋转矩阵并打破模型矩阵的乘法顺序。

model * rotation_from_user_input
= translation * rotation * scale * rotation_from_user_input

你必须像这样改变模型矩阵的旋转

rotation *= rotation_from_user_input;

然后更新模型矩阵本身以修复失真。

model = translation * rotation * scale;

【讨论】:

但在这种情况下,我根本没有平移或缩放矩阵。我也不相信这是关于先前应用于模型矩阵的转换的错误,因为就在我旋转它之前,我写道:m_modelMatrix = glm::mat4(1.0f); 我旋转它的方式也等同于它在这里的完成方式:learnopengl.com/Getting-started/Transformations跨度> @cummiesinmytummy 我无法找到代码中问题的原因。您能否更新您的问题,使其与您的实际顶点着色器和投影矩阵相匹配?它还有助于查看应用程序代码(例如渲染循环)。 确定。现在更新了。 我喜欢你的解释:很中肯。 @cummiesinmytummy 也许这是分辨率的问题。我可以看到你的投影矩阵的屏幕比例是 1:1。以下函数调用中的第二个参数glm::perspective(glm::radians(53.f), 1.f, 0.1f, 100.f);如果你的窗口比例不是1:1(例如16:9),结果会失真。

以上是关于旋转矩阵的问题(openGL/glm)[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL glm旋转

如何将 N x N 矩阵旋转 90 度? [关闭]

C ++ / OpenGL glm无法将矩阵插入着色器中的统一

OpenGL - GLM 和 GLSL,它们有何不同?

旋转矩阵

旋转矩阵的简介