-->

建议对如何在墙上创建一个窗口(Suggestion on how to create a windo

2019-10-29 14:04发布

我工作的一个three.js所应用的时候,必须创建一个建筑结构(都在地面层),高度,宽度,长度将由用户指定。 用户可以改变墙壁和屋顶的颜色(这是使用纹理施加,正如我有图像用于与一些纹理每种颜色)。 他们还可以在选定的墙(如窗或门),它可以是随后被拖上同样选择墙添加任何附件。 决定他们想要把窗口(如)后,他们会点击一个按钮来确认位置。 现在,我要创建在墙上的窗口,这样我就可以在房间内看到。 请建议您在下面的方法访问量:

一旦用户确认门的位置 -

A)我可以添加窗口的网在主建筑目mainMesh.add(windowMesh); 。 但问题是,即使我的透明材料设置为窗口,墙体材料仍然显示。

湾)我可以减去从主建筑目(使用CSG,threeCSG)窗口网状buildingmeshcsg.subtract(windowmeshcsg)这产生在建筑物啮合的孔,然后我把窗口网状过该孔。 现在的问题是原始几何的面孔得到任何CSG操作毕竟混了,所以CSG操作之后,颜色,脸上的紫外线消失。

角),我可以在小部分创建墙, 像从一个角到窗口四角然后,从另一个窗口角到另一个壁的角落。 但是,这打乱了我已经在墙壁上应用的质地,因为我已经创建了一个正面和背面墙壁紫外线,因为质地不正确应用。

请提出你的意见。

必须做出这样的事情: https://forum.unity.com/threads/make-a-seethrough-window-without-making-hole-in-the-wall.286393/

Answer 1:

三*(所有版本)

这听起来像一个很好的候选人模板缓存。 绘制窗口和写入模版,绘制围绕写入的值的壁(0)然后绘制写入的值(1)内的壁。

这些都是你所感兴趣的方法:

https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/stencilOp https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/stencilFunc

您需要首先做到这一点:

const gl = renderer.getContext() //obtain the actual webgl context, because three has no stencil functionality

然后你需要管理你的绘制逻辑,这就是Object3D.onBeforeRender回调应该有所帮助。

因此,让我们假设你有这样的事情:

const myWindow, myWall //two meshes, you loaded them, instantiated them

//for a proof of concept you can do something like this

const maskScene = new THREE.Scene()
const wallScene = new THREE.Scene()
const windowScene = new THREE.Scene()

maskScene.add(myWindow)
wallScene.add(myWall)
windowScene.add(myWindow)

render(){
  gl.enable(gl.STENCIL_TEST) //enable stencil testing

  gl.clearStencil( 0 ) //set stencil clear value

  gl.clear( _gl.STENCIL_BUFFER_BIT ) //clear the stencil buffer with set value

  gl.stencilFunc( gl.ALWAYS, 1, 1) //always pass the stencil test, with ref 1


  gl.stencilOp( gl.REPLACE , gl.REPLACE , gl.REPLACE ) //replace the stencil value with the ref 

  gl.colorMask(false, false, false, false) //do not write any color 
  gl.depthMask(false) //do not write to depth

  myRenderer.render(maskScene, myCamera) //only the stencil is drawn


  //now you have a region in the frame buffer with stencil value of 1, and the rest 0, you can draw the wall in 0 and the window back at 1

  gl.colorMask(true, true, true, true) //enable writing
  gl.depthMask(true)

  gl.stencilFunc( gl.EQUAL , 0 , 1 )  //set the stencil function to EQUAL
  gl.stencilOp( gl.KEEP, gl.KEEP, gl.KEEP ) //keep the stencil value in all three tests

  myRenderer.render( wallScene, myCamera ) //draw the wall where stencil is 0 (around the window)


  gl.stencilFunc( gl.EQUAL , 1 , 1 ) // now func is EQUAL but to value 1

  myRenderer.render( windowScene, myCamera ) //draw the window

}

这是最基本的尝试,它没有进行测试。 由于它与WebGL的API直接合作,应该有三个中的任何版本。 stencilOp需要两个以上,使用它可以管理与深度测试会发生什么论据。



文章来源: Suggestion on how to create a window over a wall