我想产生类似于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的东西(具有旋转和缩放的可能性)。
非常感谢您的帮助!