gpt4 book ai didi

javascript - 使css3d渲染平面充当3JS中的地板?

转载 作者:搜寻专家 更新时间:2023-11-01 04:28:42 24 4
gpt4 key购买 nike

我的要求是制作一个css3d渲染平面作为地板。一个 3d 立方体应该在飞机的顶部。下面我附上了我试过的代码。平面和立方体共享相同的场景和相机。但渲染不同。但是我无法将 3d 立方体放在平面的顶部,并且平面和立方体的旋转是不同的。

    <!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>

这是输出
here's the output

最佳答案

THREE.CSS3DObject不关心 WebGLRenderingContext 的深度缓冲区.它对深度缓冲区甚至深度测试一无所知。 CSS 对象的顺序可以由 z-index 定义.
您尝试混合两种完全不同的技术,它们不会以那种方式相互作用。


但您仍然可以让它发挥作用。

为此,您必须定义 CSS3DRenderer 的 z-index低于 WebGLRenderer 的 z-index 的元素元素,以便 WebGLRendererCSS3DRenderer“前面”绘制。必须为 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。从技术上讲这是做不到的。但是你可以欺骗系统。您可以渲染一个完全透明的平面,大小相同,位置相同,如 WebGLRenderer 中的 CSS3DObject:

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>

关于javascript - 使css3d渲染平面充当3JS中的地板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50602684/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com