我的要求是让css3d渲染平面充当地板。并且三维立方体应位于飞机顶部。下面我附上了我试过的代码。平面和立方体共享相同的场景和相机。但渲染是不同的。但我无法将三维立方体放置在平面上方,平面和立方体的旋转也不同。
<!DOCTYPE html>
<html lang="en">
<head>
<title>3JS CODE</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="js/three.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<script src="js/renderers/CSS3DRenderer.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var HtmlElement = function ( id, x, y, z, rx ) {
var div = document.createElement( 'div' );
div.innerHTML = "Hello";
div.id = id; //'googleMap';
div.style.width = '1200px';
div.style.height = '950px';
div.style.backgroundColor = 'blue';
var object = new THREE.CSS3DObject( div );
object.position.set( x, y, z );
object.rotation.x = rx;
return object;
};
</script>
<script>
var container, stats;
var camera, controls, mapScene, group, renderer1,renderer2;
var objects = [];
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 5000 );
camera.position.z = 1000;
camera.position.set(0.18348775328760136, -334.5971567493426, 800.8398185862801);
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 3.0;
controls.zoomSpeed = 2.2;
controls.panSpeed = 2.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 1.3;
mapScene = new THREE.Scene();
// scene.background = new THREE.Color( 0xf0f0f0 );
group = new THREE.Group();
var mapObject = new HtmlElement( 'googleMap', 0, 0, 240, 270 );
group.add( mapObject );
///////////////
var geometry = new THREE.BoxGeometry( 200, 200, 200 );
for ( var i = 0; i < geometry.faces.length; i += 2 ) {
var hex = Math.random() * 0xffffff;
geometry.faces[ i ].color.setHex( hex );
geometry.faces[ i + 1 ].color.setHex( hex );
}
var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );
cube = new THREE.Mesh( geometry, material );
cube.position.x = 0;
cube.position.y = -300;
cube.position.z = 500;
group.add( cube );
mapScene.add( group );
// renderer
renderer1 = new THREE.CSS3DRenderer();
renderer1.setSize( window.innerWidth, window.innerHeight );
renderer1.domElement.style.position = 'absolute';
renderer1.domElement.style.top = 0;
container.appendChild( renderer1.domElement );
renderer2 = new THREE.WebGLRenderer( { antialias: true } );
renderer2.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer2.domElement );
stats = new Stats();
container.appendChild( stats.dom );
window.addEventListener( 'resize', onWindowResize, false );
render();
// initMap();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer1.setSize( window.innerWidth, window.innerHeight );
renderer2.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
controls.update();
renderer1.render( mapScene, camera );
renderer2.render( mapScene, camera );
}
</script>
</body>
</html>
答案 0 :(得分:2)
the docs不关心THREE.CSS3DObject
的深度缓冲区。它对深度缓冲甚至深度测试都没有任何线索。 CSS对象的顺序可以由WebGLRenderingContext
定义
你试图混合两种完全不同的技术,这些技术不会以这种方式相互作用。
但你仍然可以使它发挥作用。
为此,您必须将z-index元素的z-index定义为低于CSS3DRenderer
元素的z-index,以便WebGLRenderer
绘制“在...之前” CSS3DRenderer
。必须为WebGLRenderer
:
renderer1 = new THREE.CSS3DRenderer();
renderer1.setSize( window.innerWidth, window.innerHeight );
renderer1.domElement.style.position = 'absolute';
renderer1.domElement.style.zIndex = 0;
renderer1.domElement.style.top = 0;
container.appendChild( renderer1.domElement );
renderer2 = new THREE.WebGLRenderer( { antialias: true, alpha:true } );
renderer2.setSize( window.innerWidth, window.innerHeight );
renderer2.domElement.style.position = 'absolute';
renderer2.domElement.style.zIndex = 1;
renderer2.domElement.style.top = 0;
container.appendChild( renderer2.domElement );
然后您必须确保WebGLRenderer
负责CSS3DObject
。从技术上讲,这是不可能做到的。但你可以欺骗系统。
您可以渲染一个完全透明的平面,其大小相等,位置与CSS3DObject
中的WebGLRenderer
相同:
var HtmlElement = function ( id, x, y, z, w, h ) {
var div = document.createElement( 'div' );
div.innerHTML = "Hello";
div.id = id; //'googleMap';
div.style.width = w + 'px';
div.style.height = h + 'px';
div.style.backgroundColor = 'blue';
var object = new THREE.CSS3DObject( div );
object.position.set( x, y, z );
return object;
};
var WebGlObject = function ( x, y, z, w, h ) {
var material = new THREE.MeshBasicMaterial({
color: 0x0000000,
opacity: 0.0,
side: THREE.DoubleSide
});
var geometry = new THREE.PlaneGeometry(w, h);
var mesh = new THREE.Mesh(geometry, material);
mesh.position.x = x;
mesh.position.y = y;
mesh.position.z = z;
return mesh;
};
var mapObject = HtmlElement('googleMap', 0, 0, 0, 800, 800);
var planeMesh = WebGlObject( 0, 0, 0, 800, 800);
请参阅示例,该示例基于您的问题代码:
var HtmlElement = function ( id, x, y, z, w, h ) {
var div = document.createElement( 'div' );
//div.innerHTML = "Hello";
div.id = id; //'googleMap';
div.style.width = w + 'px';
div.style.height = h + 'px';
div.style.backgroundColor = 'lightblue';
div.style.color = "red";
div.style.fontSize="200px";
div.style.textAlign="center";
var iframe = document.createElement("iframe");
iframe.setAttribute("src", "https://www.google.com/maps/embed");
iframe.style.width = w + "px";
iframe.style.height = h + "px";
div.appendChild(iframe);
var object = new THREE.CSS3DObject( div );
object.position.set( x, y, z );
return object;
};
var WebGlObject = function ( x, y, z, w, h ) {
var material = new THREE.MeshBasicMaterial({
color: 0x0000000,
opacity: 0.0,
side: THREE.DoubleSide
});
var geometry = new THREE.PlaneGeometry(w, h);
var mesh = new THREE.Mesh(geometry, material);
mesh.position.x = x;
mesh.position.y = y;
mesh.position.z = z;
return mesh;
};
var container, stats;
var camera, controls, mapScene, group, renderer1,renderer2;
var objects = [];
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 5000 );
camera.position.set(-600, 300, 700);
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 3.0;
controls.zoomSpeed = 2.2;
controls.panSpeed = 2.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 1.3;
mapScene = new THREE.Scene();
// scene.background = new THREE.Color( 0xf0f0f0 );
group = new THREE.Group();
group.renderOrder=1;
var mapObject = HtmlElement( 'googleMap', 0, 0, 0, 800, 800 );
var planeMesh = WebGlObject(0, 0, 0, 800, 800);
group.add( mapObject );
var geometry = new THREE.BoxGeometry( 200, 200, 200 );
for ( var i = 0; i < geometry.faces.length; i += 2 ) {
var hex = Math.random() * 0xffffff;
geometry.faces[ i ].color.setHex( hex );
geometry.faces[ i + 1 ].color.setHex( hex );
}
var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );
cube = new THREE.Mesh( geometry, material );
cube.position.x = 0;
cube.position.y = 0;
cube.position.z = 102;
group.add( cube );
group.add( planeMesh );
mapScene.add( group );
// renderer
renderer1 = new THREE.CSS3DRenderer();
renderer1.setSize( window.innerWidth, window.innerHeight );
renderer1.domElement.style.position = 'absolute';
renderer1.domElement.style.zIndex = 0;
renderer1.domElement.style.top = 0;
container.appendChild( renderer1.domElement );
renderer2 = new THREE.WebGLRenderer( { antialias: true, alpha:true } );
renderer2.setSize( window.innerWidth, window.innerHeight );
renderer2.domElement.style.position = 'absolute';
renderer2.domElement.style.zIndex = 1;
renderer2.domElement.style.top = 0;
container.appendChild( renderer2.domElement );
window.addEventListener( 'resize', onWindowResize, false );
render();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer1.setSize( window.innerWidth, window.innerHeight );
renderer2.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
controls.update();
renderer2.render( mapScene, camera );
renderer1.render( mapScene, camera );
}
<script src="https://threejs.org/build/three.min.js"></script>
<!--script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script-->
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>
<script src="https://threejs.org/examples/js/renderers/CSS3DRenderer.js"></script>