You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于自定义CAMERA结构体实现glm::lookAt()相机上下左右平移?

解决相机上下左右平移不符合预期的问题

先揪出核心问题:你的view_M()方法里调用glm::lookAt的参数完全错了!glm::lookAt的第二个参数要求传入相机看向的目标点(也就是你的AT成员),但你现在传的是相机方向向量cameraDirection,这直接导致视图矩阵计算逻辑混乱,自然平移的视觉效果和预期不符。

第一步:修正视图矩阵生成函数

这是一切的基础,先把view_M()改回标准用法:

glm::mat4 view_M() {
    // glm::lookAt标准参数:相机位置、目标位置、世界上方向
    // 内部会自动计算相机的右、上、前方向,无需手动重复计算
    return glm::lookAt(this->EYE, this->AT, this->UP);
}

如果你想保留自己的向量计算逻辑,也可以手动构建视图矩阵,但务必保证参数传递正确——错误的视图矩阵会让所有相机操作的效果都偏离预期。

第二步:实现正确的相机平移

你的平移思路是对的(同时移动EYE和AT,保持相机看向的相对位置不变),修正视图矩阵后,用更简洁的方式实现即可:

上下平移(沿相机自身Up方向)

// 可自定义平移速度
float moveSpeed = 1.0f;
glm::vec3 upOffset = camera.Up() * moveSpeed;
// 同时偏移相机位置和目标点,保持看向关系
camera.EYE += upOffset;
camera.AT += upOffset;

左右平移(沿相机自身Right方向)

float moveSpeed = 1.0f;
glm::vec3 rightOffset = camera.Right() * moveSpeed;
camera.EYE += rightOffset;
camera.AT += rightOffset;

如果你坚持想用矩阵乘法实现平移,代码本身是没问题的,修正视图矩阵后也能正常工作:

float moveSpeed = 1.0f;
glm::mat4 transMat = glm::translate(glm::mat4(1.0f), camera.Up() * moveSpeed);
camera.EYE = glm::vec3(transMat * glm::vec4(camera.EYE, 1.0f));
camera.AT = glm::vec3(transMat * glm::vec4(camera.AT, 1.0f));

关于你的卫星式旋转代码

你的环绕原点旋转逻辑是正常的——通过旋转EYE和UP向量保持看向原点的姿态,修正视图矩阵后这部分代码会继续正常工作,无需改动。

总结

  1. 视图矩阵参数错误是平移效果异常的根本原因,优先修正view_M();
  2. 平移时只需沿相机自身的Up/Right方向,同时偏移EYE和AT即可,直接向量加法比矩阵乘法更直观高效;
  3. 所有相机姿态相关的计算,都要基于正确的视图矩阵逻辑。

内容的提问来源于stack exchange,提问作者sunkue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 15:32:51