在着色器中为光线追踪器加载三角形顶点的更好方法

Better ways to load triangle vertices in your shader for ray tracer

目前我正在尝试在 WebGL 2 中使用三角形网格实现光线追踪器。到目前为止,我正在将数据加载到缓冲区纹理中,然后像这样解压它们:

for (int i = 0; i < vertsCount; i += 3) {

            a = texelFetch(uMeshData, ivec2(i, 0), 0);
            b = texelFetchOffset(uMeshData, ivec2(i, 0), 0, ivec2(1, 0));
            c = texelFetchOffset(uMeshData, ivec2(i, 0), 0, ivec2(2, 0));


            bool isHit = hitTriangleSecond(R_.orig, R_.dir, a.xyz, b.xyz, c.xyz, uvt, triangleNormal, intersect, z);;
            if (isHit) {

                if (z<mindist && z > 0.001) {
                    //weHitsomething    
                }
            }      
        } 

你知道问题出在哪里。当我尝试加载一个包含许多三角形的网格时,它变得太慢了,尤其是当我添加了 4 次反射级别时,因为我必须检查每个三角形、每一帧……所以不是最佳的。

我听说过边界框技术和一些树存储数据。但我不知道该怎么做。

如果有人能提供一些相关信息就好了。除此之外。

我也在考虑第二个纹理,其中包含关于我加载的每个网格的一些信息,但是当你有索引时,texelfetch 不像数组,所以你知道光线击中的这个方向上有哪些对象。

所以我的问题是如何检查射线方向上的 "nearest" 个三角形。

在 WebGL 中实现光线追踪器是一项相当高级的任务。我建议从简单开始。例如,使用 3D 纹理并在其每个 cells/pixels 中存储最多 4 个三角形索引。 (您必须在纹理中进行光线扫描,直到遇到三角形。)一旦有了三角形索引,您就可以在第二个纹理中查找顶点(在您的代码中称为 uMeshData。)

您可以在初始化阶段在 Javascript 中构建 3D 纹理数据。 (稍后,您可以通过将三角形渲染到 3D 纹理的 2D 切片上,使用深度缓冲区 select 到每个像素最近的三角形来在 GPU 上实现这一点。)

如果超过 4 个三角形与 3D 纹理重叠,这将无法产生正确的结果 cell/pixel。它也不是很有效(由于固定步长光线行进的冗余),但至少让你朝着正确的方向前进。完成后,您可以尝试更高级的解决方案(这可能涉及树,例如边界体积层次结构。)