有没有办法从glm中的视图矩阵中提取变换矩阵?

Posted

技术标签:

【中文标题】有没有办法从glm中的视图矩阵中提取变换矩阵?【英文标题】:Is there any way to extract a transform matrix from a view matrix in glm? 【发布时间】:2019-04-03 15:41:36 【问题描述】:

我需要从我的相机中提取变换矩阵以将其分配给网格。

我在学校从事一个计算图形项目,目标是以第一人称视角模拟角色的手臂。

我的相机实现包括一个用于相机位置的vector3,所以我可以将它分配给我的网格,问题是我还不能从我的视图矩阵中提取相机的旋转。

我以这种方式在旋转函数中计算我的最终俯仰和偏航,x 和 y 是屏幕中的当前鼠标位置

m_yaw += (x - m_mouseLastPosition.x) * m_rotateSpeed;

m_pitch -= (y - m_mouseLastPosition.y) * m_rotateSpeed;

这就是我在视图矩阵发生变化时更新视图矩阵的方式

glm::vec3 newFront;

newFront.x = -cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));

newFront.y = sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));

newFront.z = sin(glm::radians(m_pitch));

m_front = glm::normalize(newFront);

m_right = glm::normalize(glm::cross(m_front, m_worldUp));

m_up = glm::normalize(glm::cross(m_right, m_front));

m_viewMatrix = glm::lookAt(m_position, (m_position + m_front), m_up);

现在我可以将相机的位置分配给我的网格,就像这样

m_mesh.m_transform = glm::translate(glm::mat4(1.0f), m_camera.m_position);

我可以成功分配相机位置,但不能旋转。

我希望将完整的相机 transform 分配给我的网格,或者独立提取 rotation 并将其分配给网格。

【问题讨论】:

什么是VECTOR3? GLM 没有这种类型。另外:“问题是我还不能从我的视图矩阵中提取相机的旋转”你为什么需要这样做?您不是使用“相机的旋转”创建了视图矩阵吗? 抱歉,VECTOR3 只是 glm::vec3 的 typedef,我已经编辑过了。是的,我知道我用旋转构建视图矩阵,但我只是不知道如何用这 3 个向量或我的俯仰和偏航独立创建变换矩阵。注意:我试图将我的视图矩阵分配给我的网格变换,结果是旋转有点逆,也许视图矩阵与变换相反?谢谢。 是的,我知道,代码不是问题,我的意思是 glm::vec3,我只是为 glm vec3 做了一个 typedef 如果您尝试顺时针旋转“相机”,物体会出现逆时针移动。在一张纸上画一个正方形,看着它,然后向右倾斜你的头。它似乎以哪种方式“移动”?您是否有理由自己执行触发而不是使用 glm::rotate? 【参考方案1】:

我一直遵循的设置模型视图投影矩阵的步骤(这并不意味着它 100% 正确),这似乎是您遇到的问题:

// Eye position is in world coordinate system, as is scene_center. up_vector is normalized.
glm::dmat4 view = glm::lookat(eye_position, scene_center, up_vector);
glm::dmat4 proj = glm::perspective(field_of_view, aspect, near_x, far_x);

// This converts the model from it's units, to the units of the world coordinate system
glm::dmat4 model = glm::scale(glm::dmat4(1.0), glm::dvec3(1.0, 1.0, 1.0));
// Add model level rotations here utilizing glm::rotate

// offset is where the objects 0,0 should be mapped to in the world coordinate system
model = glm::translate(model, offset);
// Order of course matters here. 
glm::dvec3 mvp = proj * view * model; 

希望对您有所帮助。

【讨论】:

【参考方案2】:

非常感谢您的回答,他们帮了很多忙。

我设法以一种非常简单的方式解决了我的问题,我只需使用相机的单独属性直接将最终变换分配给我的网格。

glm 对我来说太新了,我不熟悉它处理矩阵乘法的方式。

最终的代码采用相机位置的平移矩阵,然后我用我的俯仰在 Y 轴上旋转生成的矩阵,最后用我的偏航在 X 轴上旋转生成的矩阵。

m_mesh.m_transform = glm::rotate(glm::rotate(glm::translate(glm::mat4(1.0f), camera.m_position), glm::radians(-camera.m_yaw), glm::vec3(0.0f, 1.0f, 0.0f)), glm::radians(-camera.m_pitch), glm::vec3(1.0f, 0.0f, 0.0f));

【讨论】:

以上是关于有没有办法从glm中的视图矩阵中提取变换矩阵?的主要内容,如果未能解决你的问题,请参考以下文章

从视图矩阵中清除比例组件。独立于相机的缩放

GLM 视图矩阵导致模型矩阵无效

GLSL 和 GLM 之间的矩阵数学不一致,或者是不是存在“坏”视图矩阵之类的东西

使用 glm 根据光标位置旋转模型视图矩阵

three.js中的矩阵变换(模型视图投影变换)

剔除适用于从视图投影矩阵中提取平面,但不适用于投影矩阵