Three.js:带有OrbitControls的Pepper的Ghost效果:相机平移/旋转的问题

时间:2019-05-23 14:33:58

标签: three.js camera orbit-controls

我想产生类似于Pepper的Ghost效果的效果,如下所示: https://threejs.org/examples/webgl_effects_peppersghost.html 但是可以使用鼠标旋转和缩放立方体(即使用OrbitControl)。 但是立方体不能绕某些轴旋转。

我设置了一个jsfiddle:https://jsfiddle.net/vesx5y8j/7/

'use strict';
var container;
		var camera, scene, renderer, effect, cubetest, _controls;
		var group;

		init();
		animate();

		function init() {

			container = document.createElement( 'div' );
			document.body.appendChild( container );
			
			scene = new THREE.Scene();
				
			camera = new THREE.PerspectiveCamera(  );
      camera.position.set( 0, 0, 6 );
		  camera.up.set(0,1,0);
		  camera.lookAt( new THREE.Vector3(0,0,0) );
	
			_controls = new THREE.OrbitControls(camera);
		  _controls.autoRotate = false;
		  _controls.autoRotateSpeed = 1.0;
      _controls.noPan = true;
      _controls.enabled = true;  
	   	_controls.update();
	   
	  
var axisHelper = new THREE.AxisHelper(100);
scene.add(axisHelper);
		
var cubeMaterials = [ 
    new THREE.MeshBasicMaterial({color:0xff0000, transparent:true, opacity:0.8, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color:0x00ff00, transparent:true, opacity:0.8, side: THREE.DoubleSide}), 
    new THREE.MeshBasicMaterial({color:0x0000ff, transparent:true, opacity:0.8, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color:0xffff00, transparent:true, opacity:0.8, side: THREE.DoubleSide}), 
    new THREE.MeshBasicMaterial({color:0xff00ff, transparent:true, opacity:0.8, side: THREE.DoubleSide}), 
    new THREE.MeshBasicMaterial({color:0x00ffff, transparent:true, opacity:0.8, side: THREE.DoubleSide}), 
]; 
// Create a MeshFaceMaterial, which allows the cube to have different materials on each face 
var cubeMaterial = new THREE.MeshFaceMaterial(cubeMaterials); 

cubetest = new THREE.Mesh( new THREE.CubeGeometry( 1, 2, 0.5), cubeMaterial  );
cubetest.position.set( 0, 0, 0 );
scene.add( cubetest );

renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );

effect = new THREE.PeppersGhostEffect( renderer );
effect.setSize( window.innerWidth, window.innerHeight );
effect.cameraDistance = 6;
            
			
window.addEventListener( 'resize', onWindowResize, false );

}

function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			effect.setSize( window.innerWidth, window.innerHeight );
}

function animate() {
      requestAnimationFrame( animate );
      render();
		}

function render() {
    //cubetest.rotation.x += 0.01;
    _controls.update();
		
		effect.render( scene, camera );
}
    
   
body {
						background: #777;
						padding: 0;
						margin: 0;
						font-weight: bold;
						overflow: hidden;
				}

				#info {
						position: absolute;
						top: 0px;
						width: 100%;
						color: #ffffff;
						padding: 5px;
						font-family: Monospace;
						font-size: 13px;
						text-align: center;
						z-index: 1000;
				}

				a {
						color: #ffffff;
				}

				#webglmessage a {
						color: #da0
				}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script data-name="PeppersGhostEffect.js">
 THREE.PeppersGhostEffect = function ( renderer ) {

	var scope = this;

	// Internals
	var _halfWidth, _width, _height;

	var _cameraF = new THREE.PerspectiveCamera(); //front
	var _cameraB = new THREE.PerspectiveCamera(); //back
  var _cameraL = new THREE.PerspectiveCamera(); //left
	var _cameraR = new THREE.PerspectiveCamera(); //right
	
	var _position = new THREE.Vector3();
	var _quaternion = new THREE.Quaternion();
	var _scale = new THREE.Vector3();

	// Initialization
	renderer.autoClear = false;

	this.setSize = function ( width, height ) {

		_halfWidth = width / 2;
		if ( width < height ) {

			_width = width / 3;
			_height = width / 3;

		} else {

			_width = height / 3;
			_height = height / 3;

		}
		renderer.setSize( width, height );
	};

	this.render = function ( scene, camera ) {
		
		scene.updateMatrixWorld();

		if ( camera.parent === null ) camera.updateMatrixWorld();

		camera.matrixWorld.decompose( _position, _quaternion, _scale );
		
		renderer.clear();
		renderer.enableScissorTest( true );
		
    //front camera
		_cameraF.position.copy( _position );
		_cameraF.quaternion.copy( _quaternion );
		_cameraF.lookAt( new THREE.Vector3(0,0,0)  );
		
    // back camera
		_cameraB.position.copy( _position );
		_cameraB.quaternion.copy( _quaternion );
	  _cameraB.translateZ( -2.*scope.cameraDistance);
   // 	_cameraB.translateZ( -2.*_position.z);
		_cameraB.up.set(0,-1,0);
		_cameraB.lookAt( new THREE.Vector3(0,0,0)  );
		
		// left camera
		_cameraL.position.copy( _position );
		_cameraL.quaternion.copy( _quaternion );
		_cameraL.translateZ( - scope.cameraDistance);
		_cameraL.translateX( - scope.cameraDistance);
   // _cameraL.translateZ( -_position.z);
	//	_cameraL.translateX( - _position.x);
		_cameraL.up.set(0,0,-1);
		_cameraL.lookAt( new THREE.Vector3(0,0,0));
	
		
    //right camera
		_cameraR.position.copy( _position );
		_cameraR.quaternion.copy( _quaternion );
		_cameraR.translateZ( - scope.cameraDistance);
		_cameraR.translateX( scope.cameraDistance);
		_cameraR.up.set(0,0,-1);
		_cameraR.lookAt( new THREE.Vector3(0,0,0) );
		
		
		renderer.setScissor( _halfWidth - ( _width / 2 ), 0, _width, _height );
		renderer.setViewport( _halfWidth - ( _width / 2 ), 0, _width, _height );
		renderer.render( scene, _cameraF );
		
		renderer.setScissor( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );
		renderer.setViewport( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height);
		renderer.render( scene, _cameraB);
		
		renderer.setScissor( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height);
		renderer.setViewport( _halfWidth - ( _width / 2 ) - _width, _height, _width,_height);
		renderer.render( scene, _cameraL);

		renderer.setScissor( _halfWidth + ( _width / 2 ), _height, _width, _height );
		renderer.setViewport( _halfWidth + ( _width / 2 ), _height, _width, _height );
		renderer.render( scene, _cameraR );
		

		renderer.enableScissorTest( false );

	};


};
</script>

前置摄像头(位于屏幕底部)是原始位置的摄像头。 在开始旋转或缩放之前,多维数据集将按预期显示。

关于后置摄像头: 当我旋转时,它可以按预期工作,但是缩放是反转的(当前立方体减小时,它会增大) 当我在html的第60行输入内容时: _cameraB.translateZ(-2。* _ position.z); 代替 _cameraB.translateZ(-2。* scope.cameraDistance); 然后缩放效果很好,但是旋转会产生奇怪的结果。

关于左右摄像头: 当我绕着绿色轴旋转时,旋转工作正常,但是当我绕着红色轴旋转时,旋转没有问题(然后,左右立方体不移动;它们应该旋转90度)。

我不知道我是否只是想念某些东西(也许是由于我使用四元数而不知道它们的工作原理)还是可能无法将摄像机移动与OrbitControls相结合?

替代方法是,不使用OrbitControls旋转照相机,而是旋转多维数据集。但是我没有发现可以应用于对象的类似于OrbitControls的东西(具有旋转和缩放的可能性)。

非常感谢您的帮助!

0 个答案:

没有答案