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

求助:在Three.js中实现不受相机位置影响的Earth模型rotateUp函数

解决地球固定向上旋转不受相机视角影响的问题

嗨,这个问题我之前做Three.js项目的时候也踩过坑!核心原因是你现在用的earth.rotation.x -= rad是基于地球的本地坐标系来旋转的,但当你用OrbitControl绕着地球旋转相机时,地球的本地坐标系相对于世界空间的方向会跟着相机视角“错位”,所以相机转到背面后,旋转方向就反过来了。

要实现不管相机怎么转,地球始终沿着世界空间的“向上”方向旋转,你需要基于世界坐标系的固定轴来做旋转,而不是模型的本地轴。Three.js里默认世界向上是Y轴((0,1,0)),我们就围绕这个轴来实现旋转:

推荐实现方式(用四元数,避免万向锁)

四元数是处理3D旋转更可靠的方式,不会出现欧拉角的万向锁问题,而且能精准对应世界空间的旋转:

function rotateEarthUp(rad) {
  // 定义世界空间的向上轴(默认Y轴,如果你场景用Z轴向上就改成(0,0,1))
  const worldUpAxis = new THREE.Vector3(0, 1, 0);
  // 创建围绕该轴旋转rad弧度的四元数
  const rotationQuat = new THREE.Quaternion().setFromAxisAngle(worldUpAxis, rad);
  // 将旋转应用到地球的四元数上(注意顺序:先乘当前旋转,保证叠加正确)
  earth.quaternion.multiply(rotationQuat);
}

如果习惯用欧拉角的替代方案

如果你更习惯用rotation属性,也可以先把世界轴转换到地球的父空间(这里地球如果直接在场景根节点下,父空间就是世界空间),然后计算旋转:

function rotateEarthUp(rad) {
  const worldUpAxis = new THREE.Vector3(0, 1, 0);
  // 将世界轴转换为地球的本地坐标系下的轴
  worldUpAxis.applyQuaternion(earth.quaternion.invert());
  // 围绕转换后的本地轴旋转
  earth.rotateOnAxis(worldUpAxis, rad);
}

为什么这个方法有效?

因为我们始终以固定的世界空间向上轴作为旋转基准,不管相机怎么绕地球旋转,世界Y轴的“向上”方向是不变的,所以地球的旋转方向不会随着相机视角反转。

另外要注意:尽量不要混用欧拉角(rotation)和四元数(quaternion)来控制同一个模型的旋转,否则容易出现旋转异常。推荐全程用四元数处理这种需要世界空间参考的旋转场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:38:43