threejs ArrayCamera子摄像机设置lookAt无效

2023-11-22 12:43:41 浏览数 (1)

问题

代码语言:javascript复制
// 创建一个ArrayCamera
var arrayCamera = new THREE.ArrayCamera();
// 设置视角
var cameras = [];
cameras.push(new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100));
cameras.push(new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100));
cameras.push(new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100));
// 设置相机位置
for (var i = 0; i < cameras.length; i  ) {
  cameras[i].position.set(Math.sin(i * Math.PI * 2 / cameras.length) * 3, 0, Math.cos(i * Math.PI * 2 / cameras.length) * 3);
  // 此设置无效
  cameras[i].lookAt(0,0,0);
}
// 将相机添加到ArrayCamera中
arrayCamera.setCameras(cameras);
// 创建一个场景
var scene = new THREE.Scene();
// 创建一个立方体
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({ color: 0xffffff });
var cube = new THREE.Mesh(geometry, material);
// 将立方体添加到场景中
scene.add(cube);
// 将ArrayCamera添加到场景中
scene.add(arrayCamera);
// 调用渲染函数
renderer.render(scene, arrayCamera);

代码中设置子相机朝向不会生效

代码语言:javascript复制
cameras[i].lookAt(0,0,0);

解决

设置子相机位置和朝向后更新子相机世界变换矩阵

代码语言:javascript复制
cameras[i].updateMatrixWorld()

分析

Object3D对象的matrixWorldAutoUpdate属性默认值为true

  • three/src/core/Object3D.js
代码语言:javascript复制
Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true;

在renderer渲染时,会自动对scene和camera执行updateMatrixWorld更新其全局变换矩阵 并递归更新其所有子元素的全局变换矩阵

  • three/src/renderers/WebGLRenderer.js
代码语言:javascript复制
// Rendering
this.render = function ( scene, camera ) {
	...
	// 更新场景图形
	if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
	// 更新相机矩阵和视锥体
	if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
  • three/src/core/Object3D.js
代码语言:javascript复制
updateMatrixWorld( force ) {
	if ( this.matrixAutoUpdate ) this.updateMatrix();
	if ( this.matrixWorldNeedsUpdate || force ) {
		if ( this.parent === null ) {
			this.matrixWorld.copy( this.matrix );
		} else {
			this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
		}
		this.matrixWorldNeedsUpdate = false;
		force = true;
	}
	// 递归更新子元素
	const children = this.children;
	for ( let i = 0, l = children.length; i < l; i    ) {
		const child = children[ i ];
		if ( child.matrixWorldAutoUpdate === true || force === true ) {
			child.updateMatrixWorld( force );
		}
	}
}

但是ArrayCamera并没有将子相机加入其children成员中,导致无法自动更新

  • three/src/cameras/ArrayCamera.js
代码语言:javascript复制
class ArrayCamera extends PerspectiveCamera {
	constructor( array = [] ) {
		super();
		this.isArrayCamera = true;
		this.cameras = array;
	}
}

0 人点赞