簡體   English   中英

THREE.js 如何在 3d 房間模型中制作透明的前牆

[英]THREE.js how to make transparent front walls in 3d room model

我想在three.js中制作一個3d房間。 我希望攝像機視圖前面的牆壁在我旋轉房間時變得透明。

這是我需要的示例: http : //jsfiddle.net/tp2f2oo4/

似乎解決方案是將 THREE.BackSide 添加到材料中。

var material2 = new THREE.MeshPhongMaterial( {
    color: 0xffffff, 
    transparent: false,
    side: THREE.BackSide
} );

實際上,當一個房間充當單個 THREE.BoxGeometry 時,這非常有效,但在我的情況下,每個牆壁、天花板和地板都是單獨的 THREE.BoxGeometry 對象。 當在相機視圖前面時,有什么方法可以隱藏它們或不渲染它們?

您想根據某些條件隱藏網格。 這是使用onBeforeRender()onAfterRender()方法的完美用例。

// callbacks
var onBeforeRender = function() {

    var v = new THREE.Vector3();

    return function onBeforeRender( renderer, scene, camera, geometry, material, group ) {

        // this is one way. adapt to your use case.
        if ( v.subVectors( camera.position, this.position ).dot( this.userData.normal ) < 0 ) {

            geometry.setDrawRange( 0, 0 ); // it is too late to set visible = false, so do this, instead

        }

    };

}();

var onAfterRender = function( renderer, scene, camera, geometry, material, group ) {

    geometry.setDrawRange( 0, Infinity );

};

// mesh
mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, 0, 10 );
mesh.rotation.set( 0, 0, 0 );
scene.add( mesh );
mesh.userData.normal = new THREE.Vector3( 0, 0, - 1 );
mesh.onBeforeRender = onBeforeRender;
mesh.onAfterRender = onAfterRender;

小提琴: http : //jsfiddle.net/3qh815xa/

三.js r.114

您可以使用光線投射來確定要關閉哪些牆。 基本上,從你的相機拍攝一條光線,並設置它相交的牆的透明度。

有關簡化的情況,請參閱下面代碼段中的updateWallTransparency_simple 它從相機的中心發射光線,並設置相交牆的透明度。

但是,您可能會遇到字面意義上的極端情況,即從一堵牆過渡到另一堵牆。 您可以使用第二個光線投射對此進行補償,但您需要將兩條光線從中心偏移,這樣在拐角的情況下它們就不會與同一面牆相交。 有關updateWallTransparency_corners ,請參閱下面代碼段中的updateWallTransparency_corners

現在這是一個高度簡化的案例。 如果您的牆壁形狀更復雜,則需要執行進一步檢查以查看是否應隱藏某些牆壁。 此外,如果您將相機傾斜得太遠,您會注意到它會使后牆隱藏起來。 作為一個整體,這個問題還有很多需要考慮的地方,但這應該能讓你開始。

 var renderer, scene, camera, controls, stats; var WIDTH = window.innerWidth, HEIGHT = window.innerHeight, FOV = 35, NEAR = 1, FAR = 1000, degrad = (Math.PI / 180), walls = []; var raycaster = null, coords = null; function updateWallTransparency_simple() { // reset all walls. You can optimize this by storing which ones are transparent/not walls.forEach(function(wall) { wall.material.opacity = 1; }); raycaster.setFromCamera(coords, camera); var intersects = raycaster.intersectObjects(walls); if (intersects && intersects.length > 0) { intersects[0].object.material.opacity = 0.25; } } function updateWallTransparency_corners() { // reset all walls. You can optimize this by storing which ones are transparent/not walls.forEach(function(wall) { wall.material.opacity = 1; }); coords.set(-0.1, 0); raycaster.setFromCamera(coords, camera); var intersects = raycaster.intersectObjects(walls); if (intersects && intersects.length > 0) { intersects[0].object.material.opacity = 0.25; } coords.set(0.1, 0); raycaster.setFromCamera(coords, camera); var intersects = raycaster.intersectObjects(walls); if (intersects && intersects.length > 0) { intersects[0].object.material.opacity = 0.25; } } function populateScene() { var geo = new THREE.BoxBufferGeometry(20, 20, 0.1), mat = new THREE.MeshPhongMaterial({ color: "darkred", transparent: true, opacity: 1 }); var mesh = new THREE.Mesh(geo, mat); mesh.position.set(0, 0, -10); mesh.name = "backWall"; scene.add(mesh); mesh.updateMatrixWorld(true); walls.push(mesh); mesh = new THREE.Mesh(geo, mat.clone()); mesh.name = "frontWall"; mesh.position.set(0, 0, 10); scene.add(mesh); mesh.updateMatrixWorld(true); walls.push(mesh); mesh = new THREE.Mesh(geo, mat.clone()); mesh.name = "leftWall"; mesh.position.set(-10, 0, 0); mesh.rotation.set(0, (Math.PI / 180) * 90, 0); scene.add(mesh); mesh.updateMatrixWorld(true); walls.push(mesh); mesh = new THREE.Mesh(geo, mat.clone()); mesh.name = "rightWall"; mesh.position.set(10, 0, 0); mesh.rotation.set(0, (Math.PI / 180) * 90, 0); scene.add(mesh); mesh.updateMatrixWorld(true); walls.push(mesh); geo = new THREE.BoxBufferGeometry(50, 0.1, 50), mat = new THREE.MeshPhongMaterial({ color: "green" }); mesh = new THREE.Mesh(geo, mat); mesh.position.set(0, -10, 0); mesh.name = "ground"; scene.add(mesh); geo = new THREE.TorusKnotBufferGeometry(2, 0.5, 100, 16), mat = new THREE.MeshPhongMaterial({ color: "blue" }); mesh = new THREE.Mesh(geo, mat); mesh.name = "insideObject"; scene.add(mesh); } function init() { document.body.style.backgroundColor = "lightBlue"; renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); document.body.appendChild(renderer.domElement); document.body.style.overflow = "hidden"; document.body.style.margin = "0"; document.body.style.padding = "0"; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR); camera.position.z = 50; scene.add(camera); controls = new THREE.OrbitControls(camera); controls.enableZoom = false; controls.enablePan = false; controls.maxPolarAngle = Math.PI / 2; var light = new THREE.PointLight(0xffffff, 1, Infinity); camera.add(light); light = new THREE.HemisphereLight(0xffffbb, 0x00ff00, 1); scene.add(light); stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.top = '0'; document.body.appendChild(stats.domElement); resize(); window.onresize = resize; populateScene(); raycaster = new THREE.Raycaster(); coords = new THREE.Vector3(); animate(); } function resize() { WIDTH = window.innerWidth; HEIGHT = window.innerHeight; if (renderer && camera && controls) { renderer.setSize(WIDTH, HEIGHT); camera.aspect = WIDTH / HEIGHT; camera.updateProjectionMatrix(); } } function render() { renderer.render(scene, camera); } function animate() { requestAnimationFrame(animate); //updateWallTransparency_simple(); updateWallTransparency_corners(); render(); stats.update(); } function threeReady() { init(); } (function() { function addScript(url, callback) { callback = callback || function() {}; var script = document.createElement("script"); script.addEventListener("load", callback); script.setAttribute("src", url); document.head.appendChild(script); } addScript("https://threejs.org/build/three.js", function() { addScript("https://threejs.org/examples/js/controls/OrbitControls.js", function() { addScript("https://threejs.org/examples/js/libs/stats.min.js", function() { threeReady(); }) }) }) })();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM