我在一个three.js应用程序上工作,我必须创建一个建筑结构(所有在一楼),高度,宽度,长度将由用户指定。用户可以更改墙壁和屋顶的颜色(这是使用纹理应用,因为我有一些纹理的每种颜色的图像)。他们还可以在选定的墙上添加任何附件(如窗或门),然后可以将其拖放到同一选定的墙上。在决定要把窗户放在哪里之后(例如)他们会点击一个按钮来确认位置。现在我必须在墙上创建一扇窗,这样我就可以看到房间的内部。请提出您对以下方法的看法:
一旦用户确认门的位置-
a.)我可以在主建筑网格mainMesh.add(windowMesh);中添加窗户的网格。但问题是,即使我将透明材质设置为窗,墙材质仍然显示。
b.)我可以从主要的建筑网格(使用CSG,threeCSG) buildingmeshcsg.subtract(windowmeshcsg)中减去窗口网格,这会在建筑网格上创建一个洞,然后我将窗口网格放在那个洞上。现在的问题是,在任何CSG操作之后,原始几何体的面都会变得混乱,所以在csg操作之后,面的颜色和UV会消失。
c.)我可以在很小的部分中创建墙,

就像从一个角落到窗角,然后从另一个窗角到另一个墙角。但这弄乱了我在墙上应用的纹理,因为我为前面和后面的墙创建了UV,因为纹理没有正确应用。
请提出你的观点。
我必须做这样的事情:https://forum.unity.com/threads/make-a-seethrough-window-without-making-hole-in-the-wall.286393/
发布于 2017-10-07 00:40:56
三*(任何版本)
这听起来像是模板缓冲区的一个很好的候选者。绘制窗口并写入模板,在写入值(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应用程序接口一起工作,因此它应该可以与three的任何版本一起工作。stencilOp还接受两个参数,您可以使用它们来管理深度测试发生的事情。
https://stackoverflow.com/questions/46603751
复制相似问题