Graphics 如何在不修改WebGL中的网格结构的情况下在对象中创建孔?

Graphics 如何在不修改WebGL中的网格结构的情况下在对象中创建孔?,graphics,webgl,Graphics,Webgl,我是WebGL的新手,对于一个赋值,我试图编写一个函数,它以一个对象作为参数,比如objectA。ObjectA不会被渲染,但是如果它与场景中的另一个对象重叠,比如说“objectB”,objectB中位于ObjectA内部的部分将消失。因此,效果是ObjectB中有一个孔,而不修改其网格结构。 我已经成功地让它在我自己的渲染引擎上工作,基于光线跟踪,它提供了以下效果: 图像初始场景: 已删除objectA的图像: 在第一幅图像中,绿色球体是objectA,蓝色立方体是objectB。 所以现在

我是WebGL的新手,对于一个赋值,我试图编写一个函数,它以一个对象作为参数,比如objectA。ObjectA不会被渲染,但是如果它与场景中的另一个对象重叠,比如说“objectB”,objectB中位于ObjectA内部的部分将消失。因此,效果是ObjectB中有一个孔,而不修改其网格结构。 我已经成功地让它在我自己的渲染引擎上工作,基于光线跟踪,它提供了以下效果:

图像初始场景:

已删除objectA的图像:

在第一幅图像中,绿色球体是objectA,蓝色立方体是objectB。 所以现在我尝试用WebGL编程,但我有点卡住了。由于WebGL基于光栅化而不是光线跟踪,因此必须以另一种方式进行计算。一种可能是修改Z-buffer算法,在该算法中,objectA中具有Z值的片段将被忽略

我想到的算法如下:通常只有z值最小的片段才会存储在包含颜色和z值的特定像素上。第一个修改是,在特定像素处,维护属于该像素的所有片段的列表。不会丢弃任何碎片。其次,每个片段存储一个额外的参数,其中包含它所属的对象。接下来,根据z值按递增顺序对片段进行排序

然后,如果第一个片段属于objectA,它将被忽略。如果下一个属于objectB,它也将被忽略。如果第三个属于objectA,第四个属于objectB,则将选择第四个,因为它位于objectA之外。 因此,将选择属于objectB的第一个片段,并限制之前属于objectA的片段数量为偶数。如果不均匀,则片段将位于objectA内部,并将被忽略

这在WebGL中可能吗?基于以下博客,我还尝试通过模具缓冲区实现它: 但这是为OpenGL编写的。我将代码指令转换为WebGL代码指令,但根本不起作用。但我不确定它是否适用于3D对象而不是2D三角形


提前多谢

为什么不在片段着色器aka pixel着色器中编写光线跟踪器

因此,您需要渲染一个全屏四边形两个三角形,然后片段着色器将负责光线跟踪。有很多资源可供阅读/学习

以下链接可能有用:

编辑:

光线跟踪和SDFs有符号距离函数(又名构造性立体几何CSG)是处理所需内容以及如何实现与对象相交的好方法。交叉点和布尔运算符一般来说,对于网格几何体,即由多边形构成的网格几何体,rahter在渲染过程中不会执行此操作。它使用特殊算法在渲染之前执行所有处理,因此生成的网格实际上存在于内存中,其拓扑结构实际上是计算出来的,然后才进行渲染

根据您拥有的特定场景,您可能能够在某些需求和限制下实现效果

有几件重要的事情需要考虑:深度剥离,即每一个像素存储多个碎片的深度值,三角形方向CW或CCW,多边形面方向正面或背面

例如,假设两个多边形都是凸的,然后渲染ObjectA的背面多边形,然后渲染ObjectB的背面多边形,然后渲染A的正面多边形,然后渲染B的正面多边形,可能会达到所需的效果。我不包括所有可能存在的重叠情况的完整计算

在其他一些限制条件下,您可能能够实现该效果

在您讨论的特定示例中,您已经显示了立方体的正面,然后在第二幅图像中可以看到立方体的背面。这已经意味着每像素至少存储了两个深度值

在屏幕空间、体积或面中相交也有区别。您的示例适用于面,最难的是有两种情况:您展示的一种情况是,网格A中位于网格B内的像素被简单丢弃,即,您在其曲面内钻了一个孔;另一种情况是,您执行布尔运算,从未在曲面上打过孔,但在体积上,通常是用计算输出网格的算法来完成的。SDF非常适合批量生产。屏幕空间是通过简单地使用深度测试来丢弃一些片段来实现的


同样,场景太多了,这取决于您试图实现的目标以及您正在处理的约束条件。

如果将问题长度减少到1/3,您的问题将受益匪浅。为什么不在片段着色器beca中编写光线跟踪器 用它的方式,哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇