GLM旋转物体出现偏移问题:旋转时位移但分解显示原点如何解决?
解决GLM旋转物体时出现偏移的问题
这种情况我之前做3D项目时也碰到过,核心原因就是矩阵变换的顺序搞反了——GLM用的是列主序矩阵,变换的实际应用顺序和你写代码的逻辑顺序是反过来的,搞混了就会出现“明明想绕自身旋转,结果却像绕世界原点转圈”的错觉。
问题出在哪?
你现在的代码应该是先平移到目标位置,再做旋转(或者逐步构建模型矩阵时把旋转乘在了平移之后),比如:
// 错误顺序:先平移,再旋转 glm::mat4 Model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 5.0f, 0.0f)); Model = glm::rotate(Model, glm::radians(15.f), glm::vec3(1.0f, 0.0f, 0.0f));
这时候模型矩阵是旋转矩阵 × 平移矩阵,顶点变换的顺序是先平移到目标位置,再绕世界原点旋转,物体自然会绕着世界原点画圈,看起来就像是位置“变高”了。而你分解平移数据时,可能只是提取了原始的平移分量,但实际上矩阵里的平移部分已经被旋转矩阵修改了,所以才会显示原点(或者你的分解方式没考虑矩阵乘法的影响)。
正确的做法:先旋转,再平移
要让物体绕自身中心旋转,再移动到目标位置,必须保证平移矩阵乘在旋转矩阵的左边,这样顶点会先完成旋转(绕自身原点),再被平移到目标位置。
两种实现方式:
- 直接组合矩阵
// 先创建旋转矩阵(绕自身X轴转15度) glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(15.f), glm::vec3(1.0f, 0.0f, 0.0f)); // 创建平移矩阵(移到目标位置) glm::mat4 translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 5.0f, 0.0f)); // 模型矩阵 = 平移 × 旋转(关键!顺序不能反) glm::mat4 Model = translation * rotation;
- 逐步构建时调整乘法顺序
如果你习惯逐步添加变换,要把新的变换矩阵乘在左边:
glm::mat4 Model = glm::mat4(1.0f); // 先添加旋转(此时Model是旋转矩阵) Model = glm::rotate(Model, glm::radians(15.f), glm::vec3(1.0f, 0.0f, 0.0f)); // 再把平移矩阵乘在左边,保证先旋转后平移 Model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 5.0f, 0.0f)) * Model;
额外提醒:物体枢轴点的问题
如果你的模型自身的中心不在原点(比如模型的几何中心在(0,2,0)),那还要先把模型移到原点,旋转后再移回中心,最后平移到目标位置:
glm::mat4 Model = glm::mat4(1.0f); // 1. 把模型中心移到世界原点 Model = glm::translate(Model, glm::vec3(0.0f, -2.0f, 0.0f)); // 2. 绕自身中心旋转 Model = glm::rotate(Model, glm::radians(15.f), glm::vec3(1.0f, 0.0f, 0.0f)); // 3. 移回模型中心 + 平移到目标位置 Model = glm::translate(Model, glm::vec3(0.0f, 2.0f + 5.0f, 0.0f));
按照这个顺序调整后,旋转就只会绕物体自身中心进行,不会出现奇怪的偏移了。
内容的提问来源于stack exchange,提问作者Bjoern Meier
相关产品推荐
相关产品推荐

