Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript THREE.js如何在三维房间模型中制作透明的前墙_Javascript_Three.js - Fatal编程技术网

Javascript THREE.js如何在三维房间模型中制作透明的前墙

Javascript THREE.js如何在三维房间模型中制作透明的前墙,javascript,three.js,Javascript,Three.js,我想在three.js中创建一个3d房间。我希望摄影机视图前面的墙在我旋转房间时变得透明 以下是我需要的示例: 看来解决办法是在材料的背面加上三个 var material2 = new THREE.MeshPhongMaterial( { color: 0xffffff, transparent: false, side: THREE.BackSide } ); 事实上,当一个房间作为一个单独的三盒几何体时,这种方法非常有效, 但在我的例子中,每面墙、天花板和地板都

我想在three.js中创建一个3d房间。我希望摄影机视图前面的墙在我旋转房间时变得透明

以下是我需要的示例:

看来解决办法是在材料的背面加上三个

var material2 = new THREE.MeshPhongMaterial( {
    color: 0xffffff, 
    transparent: false,
    side: THREE.BackSide
} );
事实上,当一个房间作为一个单独的三盒几何体时,这种方法非常有效,
但在我的例子中,每面墙、天花板和地板都是独立的三个.BoxGeometry对象。当它们位于摄影机视图前面时,有没有办法隐藏它们或不渲染?

可以使用光线投射来确定要关闭哪些墙。基本上,从相机中拍摄一条光线,并设置它与之相交的墙的透明度

有关简化的案例,请参见下面代码段中的updateWallTransparency\u simple。它从摄影机中心发射光线,并设置相交墙的透明度

但是,您可能会遇到一种文字上的转角情况,即从一面墙过渡到另一面墙。可以使用第二个光线投射对此进行补偿,但需要将两条光线从中心偏移,以便它们在拐角处不会与同一面墙相交。有关示例,请参见下面代码段中的updateWallTransparency

这是一个高度简化的案例。如果墙的形状更复杂,则需要执行进一步的检查,以确定是否应隐藏某些墙。此外,如果你把相机倾斜得太高,你会注意到它会使后墙隐藏起来。作为一个整体,这个问题还有很多要考虑的,但是这应该让你开始。

var渲染器、场景、摄影机、控件、统计信息; 变量宽度=window.innerWidth, 高度=窗内高度, FOV=35, 近=1, 远=1000, degrad=Math.PI/180, 墙=[]; var raycaster=null, coords=null; 函数updatewall\u simple{ //重置所有墙。您可以通过存储哪些墙是透明的/非透明的来优化此设置 墙{ wall.material.opacity=1; }; raycaster.setFromCameracoords,camera; var intersects=raycaster.intersectObjectswalls; 如果相交(&intersects.length>0{ 相交[0]。object.material.opacity=0.25; } } 函数updatewall\u corners{ //重置所有墙。您可以通过存储哪些墙是透明的/非透明的来优化此设置 墙{ wall.material.opacity=1; }; 坐标集-0.1,0; raycaster.setFromCameracoords,camera; var intersects=raycaster.intersectObjectswalls; 如果相交(&intersects.length>0{ 相交[0]。object.material.opacity=0.25; } coords.set0.1,0; raycaster.setFromCameracoords,camera; var intersects=raycaster.intersectObjectswalls; 如果相交(&intersects.length>0{ 相交[0]。object.material.opacity=0.25; } } 函数populateScene{ var geo=新的三箱缓冲Geometry20,20,0.1, mat=新的三点网格材料{ 颜色:黑色, 透明:是的, 不透明度:1 }; var mesh=新的三个。Meshgeo,mat; mesh.position.set0,0,-10; mesh.name=后壁; scene.addmesh; mesh.updateMatrix WorldTrue; 墙、网; mesh=新的三个.Meshgeo,mat.clone; mesh.name=前墙; mesh.position.set0,0,10; scene.addmesh; mesh.updateMatrix WorldTrue; 墙、网; mesh=新的三个.Meshgeo,mat.clone; mesh.name=leftWall; mesh.position.set-10,0,0; mesh.rotation.set0,Math.PI/180*90,0; scene.addmesh; mesh.updateMatrix WorldTrue; 墙、网; mesh=新的三个.Meshgeo,mat.clone; mesh.name=右墙; mesh.position.set10,0,0; mesh.rotation.set0,Math.PI/180*90,0; scene.addmesh; mesh.updateMatrix WorldTrue; 墙、网; geo=新的三箱缓冲几何50,0.1,50, mat=新的三点网格材料{ 颜色:绿色 }; 网格=新的三个。网格,网格; mesh.position.set0,-10,0; mesh.name=地面; scene.addmesh; geo=新的三个圆环几何量2,0.5100,16, mat=新的三点网格材料{ 颜色:蓝色 }; 网格=新的三个。网格,网格; mesh.name=内部对象; scene.addmesh; } 函数初始化{ document.body.style.backgroundColor=浅蓝色; renderer=new THREE.WebGLRenderer{ 反别名:是的, 阿尔法:是的 }; document.body.appendChildrender.doElement; document.body.style.overflow=隐藏; document.body.style.margin=0; document.body.style.padding=0; 场景=新的三个场景; 摄像机=新的三视角摄像机视野、宽度/高度、近距离、远距离; 摄像机位置z=50; scene.addcamera; 控件=新的三个。OrbitControlscamera; controls.enableZoom=false; controls.enablePan=false; controls.maxPolarAngle=Math.PI/2; var light=新的三点光源0xFFFFFF,1,无穷大; 照相机。addlight; 灯光=新的三个半球灯光0xFFFFBB,0x00ff00,1; scene.addlight; 统计数据=新统计数据; stats.domElement.style.position='绝对'; stats.domElement.style.top='0'; document.body.appendChildstats.doElement; 调整大小; window.onresize=调整大小; 流行期; raycaster=新的三个。raycaster; coords=新的三个矢量3; 使有生气 } 函数调整大小{ 宽度=window.innerWidth; 高度=窗内高度; 如果渲染器&&摄影机&&控件{ renderer.setSizeWIDTH,高度; camera.aspect=宽度/高度; camera.updateProjectionMatrix; } } 函数渲染{ renderer.renderscene,摄影机; } 函数动画{ 请求动画帧动画; //更新全部透明性\u简单; 更新所有角落的透明度; 提供 统计数据更新; } 功能三就绪{ 初始化; } 作用{ 函数addScripturl,回调{ 回调=回调函数{}; var script=document.createElementscript; script.addEventListenerload,回调; script.setAttributesrc,url; document.head.appendChildscript; } addScripthttps://threejs.org/build/three.js,功能{ addScripthttps://threejs.org/examples/js/controls/OrbitControls.js,功能{ addScripthttps://threejs.org/examples/js/libs/stats.min.js,功能{ 三就绪; } } }
}; 您希望根据某些条件隐藏网格。这是使用onBeforeRender和onAfterRender方法的完美用例

小提琴:


three.js r.114

Hi@WestLangley我一直在努力使墙的不同位置x和z偏移+20,y偏移+8。我知道您上面所做的是一个更简单的用例。若你们能帮我处理其他x、y和z位置的墙的数学问题,我将不胜感激。修改更新的几何位置@noobMama我更改了算法,因此更直观。您的用例:非常感谢。这有助于我更好地概念化soo:快速跟进。现在,墙已使用drawRange属性隐藏,只有当墙不可见时,才有有效的方法使用光线投射器拾取墙后的对象吗?默认情况下,光线投射器似乎只过滤出visible=false的对象。但是我们这里没有那种奢侈。@noobMama如果你需要帮助,最好是发一个新问题。
// 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;