首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >关于如何在墙上创建窗户的建议

关于如何在墙上创建窗户的建议
EN

Stack Overflow用户
提问于 2017-10-06 18:32:06
回答 1查看 1.2K关注 0票数 1

我在一个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/

EN

Stack Overflow用户

发布于 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

您需要先这样做:

代码语言:javascript
运行
复制
const gl = renderer.getContext() //obtain the actual webgl context, because three has no stencil functionality

然后你需要管理你的渲染逻辑,这就是Object3D.onBeforeRender回调的用武之地。

所以让我们假设你有这样的东西:

代码语言:javascript
运行
复制
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还接受两个参数,您可以使用它们来管理深度测试发生的事情。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46603751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档