使用glm实现OpenGL相机旋转时模型位置偏移问题排查
OpenGL相机旋转时模型既旋转又偏移的原因分析
问题描述
我尝试实现OpenGL相机旋转,但实际效果却是模型既发生旋转又出现位置偏移。相关代码如下:
C++代码
float m_CameraRotation = 30.0f; TShader.Bind(); glm::mat4 proj = glm::ortho(0.0f, 1000.0f, 0.0f, 1000.0f, -1.0f, 1.0f); glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0)); glm::mat4 vp = proj * view; glm::mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)) * glm::rotate(glm::mat4(1.0f), glm::radians(m_CameraRotation), glm::vec3(0, 0, 1)); TShader.UniformSetMat4f("u_ViewProjection", vp); TShader.UniformSetMat4f("u_Transform", transform);
着色器代码
gl_Position = u_ViewProjection * u_Transform * vec4(aPos, 1.0);
三角形顶点数据
float TriangleVertices[] = { // positions // colors 500.0f, 700.0f, 0.0f, 1.0f, 0.0f, 0.0f, // top 250.0f, 300.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left 750.0f, 300.0f, 0.0f, 0.0f, 0.0f, 1.0f // bottom right }; unsigned int TriangleIndices[] = { 0, 1, 2 };
效果对比
无旋转时三角形显示效果:
m_CameraRotation = 30.0f时的显示效果:
请问导致该问题的原因是什么?
问题原因
你当前的代码是对模型矩阵做旋转,而非实现相机旋转:
- 你的三角形顶点中心在(500, 500)附近,直接对
u_Transform模型矩阵应用旋转时,是绕坐标原点(0,0)旋转,所以三角形会围绕原点做圆周运动,最终表现为既旋转又偏移。 - 你的视图矩阵
view是单位矩阵加零平移,完全没有处理相机旋转逻辑。
相机旋转的本质是场景做反向运动:相机绕某轴旋转θ角,等价于整个场景(包括模型)绕同一轴旋转-θ角。因此旋转操作应该应用在视图矩阵中,而非模型矩阵。
修正方案
把旋转逻辑移到视图矩阵中,使用负角度实现反向旋转(对应相机的正向旋转):
float m_CameraRotation = 30.0f; TShader.Bind(); glm::mat4 proj = glm::ortho(0.0f, 1000.0f, 0.0f, 1000.0f, -1.0f, 1.0f); // 相机旋转:场景反向旋转对应相机正向旋转 glm::mat4 view = glm::rotate(glm::mat4(1.0f), glm::radians(-m_CameraRotation), glm::vec3(0, 0, 1)); glm::mat4 vp = proj * view; // 模型矩阵保持单位矩阵,无需额外变换 glm::mat4 transform = glm::mat4(1.0f); TShader.UniformSetMat4f("u_ViewProjection", vp); TShader.UniformSetMat4f("u_Transform", transform);
若你需要的是模型绕自身中心旋转,则需要先将模型平移到原点,旋转后再平移回原位置,但这属于模型变换,并非相机旋转逻辑。
内容的提问来源于stack exchange,提问作者user20295136
相关产品推荐
相关产品推荐

