解析Three.js中OrbitControls初始化对相机世界矩阵的影响
OrbitControls初始化自动修改相机worldMatrix的原因
我开发了一个应用,使用OrbitControls让用户通过鼠标操控场景中相机的位置与朝向。发现仅初始化OrbitControls就会对相机的worldMatrix产生意外影响,特此寻求解释。
示例代码:
camera = new THREE.PerspectiveCamera (45, width/height, 1, 10000); console.log("camera.matrixWorld = "); console.log(JSON.stringify(camera.matrixWorld)); camera.position.y = 160; camera.position.z = 400; camera.lookAt (new THREE.Vector3(0,0,0)); console.log("camera.matrixWorld = "); console.log(JSON.stringify(camera.matrixWorld)); controls = new OrbitControls (camera, renderer.domElement); console.log("camera.matrixWorld = "); console.log(JSON.stringify(camera.matrixWorld));
输出结果:
camera.matrixWorld = {"elements":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]} camera.matrixWorld = {"elements":[1,0,0,0,0,1,0,0,0,0,1,0,0,160,400,1]} camera.matrixWorld = {"elements":[1,0,0,0,0,0.9284766908852593,-0.3713906763541037,0,0,0.3713906763541037,0.9284766908852593,0,0,160.00000000000003,400,1]}
可见未执行任何修改矩阵的指令、用户也未操作相机时,OrbitControls就修改了相机的worldMatrix,请问该如何理解这一现象?
这是因为OrbitControls的构造函数内部会自动调用一次update()方法,这个方法会同步相机状态与控件的内部参数,并重新计算相机的姿态矩阵,最终触发camera.matrixWorld的更新。
具体细节:
- 你调用
camera.lookAt(0,0,0)后,相机的朝向指向原点,但OrbitControls初始化时会默认将自身的target属性设为原点,和你设置的lookAt目标一致。 update()方法会基于相机当前位置和控件的target,重新计算相机的旋转角度,确保相机围绕目标点的姿态符合控件的控制逻辑,这个过程会直接更新相机的旋转属性,进而导致matrixWorld发生变化。- 本质上,OrbitControls在初始化时就完成了对相机姿态的“接管校准”,确保后续的交互控制能正常工作,所以即使没有用户操作,初始化动作也会触发矩阵更新。
如果想避免初始化时的矩阵变化,可以在初始化OrbitControls后,手动将相机的旋转或矩阵恢复到之前的状态,但通常不建议这么做——因为OrbitControls设计的初衷就是接管相机的姿态控制,初始化时的校准是保证后续交互正常的必要步骤。
内容的提问来源于stack exchange,提问作者aQuarkyName
相关产品推荐
相关产品推荐

