通过计算着色器进行光线追踪 vs 通过屏幕四边形进行光线追踪

7

我最近在寻找关于OpenGL光线追踪的教程。大多数教程都使用计算着色器。我想知道为什么他们不直接渲染到纹理,然后将纹理作为四边形渲染到屏幕上。

使用计算着色器的方法与屏幕四边形相比有什么优缺点?


将屏幕填充的四边形转换为光栅需要一些时间。那么,当您从一开始就知道不需要完整的渲染管线时,为什么还要调用它呢? - BDL
光栅化会增加很多开销吗? - Simon Müller
1
我不会说“非常多”,但它确实增加了额外的开销。 - BDL
2个回答

14

简短回答:因为计算着色器提供了更有效的工具来执行复杂的计算

长回答:

也许在跟踪场景时,它们所提供的最大优势(就跟踪而言)是能够精确地控制在GPU上执行任务的方式。当您正在跟踪一个复杂的场景时,这一点非常重要。如果您的场景很简单(例如,Cornell Box),那么差异可以忽略不计。如果您将某些球体在片段着色器中进行跟踪,那么您将可以整天做这个操作。访问http://shadertoy.com/可以看到现代GPU和片段着色器可以实现的各种疯狂效果。

但是,如果您的场景和着色非常复杂,则需要控制如何进行工作。在四边形中进行渲染并在片段着色器中进行跟踪,最多只会使您的应用程序挂起,同时驱动程序会哭泣,改变其法定名称并移居世界的另一面……在最坏的情况下,会导致驱动程序崩溃。如果单个操作花费的时间太长,许多驱动程序将终止(在标准用法下几乎从不发生,但当您开始尝试跟踪1M多边形场景时,会非常快地发生)。

那么您在片段着色器中需要做的工作太多了……下一个逻辑步骤是什么?好吧,限制工作量。绘制较小的四边形以控制您一次跟踪屏幕上的多少内容。或者使用glScissor。使工作负载变得越来越小,直到您的驱动程序可以处理它。

我们刚刚重新发明了什么?计算着色器的工作组!工作组是计算着色器控制工作大小的机制,对于进行这种复杂任务时,它们是比片段级别的hackery(译注:hackery意思是“技巧”、“窍门”)更好的抽象。现在,我们可以自然而然地控制要分派多少条光线,并且我们可以这样做而不必紧密耦合到屏幕空间。对于简单的跟踪器,这增加了不必要的复杂度。对于“真正的”跟踪器,这意味着我们可以轻松地在抖动的网格上进行子像素射线投射以实现AA、每个像素进行巨量光线投射以进行路径跟踪等。

计算着色器的其他功能对于高效、工业级跟踪器很有用:

  • 线程组之间的共享内存 (例如允许数据包跟踪(packet tracing), 一次追踪一整个具有空间相干性的射线包,以利用内存协调性和与附近射线通信的能力)
  • 散发写入(Scatter Writes) 允许计算着色器写入任意图像位置(注意:图像和纹理在微妙的方式上不同,但优势仍然相关); 您不再需要直接从已知像素位置跟踪

总的来说,现代GPU的架构是设计为更自然地使用计算处理这种任务的。个人而言,我使用MLT、kd-tree加速和许多其他计算密集型技术编写了一个实时渐进路径追踪器(PT已经非常昂贵)。我尽可能地保持在片段着色器/全屏四边形中。一旦我的场景足够复杂需要加速结构,我的驱动程序无论我采用什么技巧都开始出现问题。我重新实现了CUDA(虽然不完全相同于计算,但利用了同样的基本GPU架构进步),一切都很好。

如果你真的想深入了解,可以看看这里3.1节:https://graphics.cg.uni-saarland.de/fileadmin/cguds/papers/2007/guenther_07_BVHonGPU/Guenter_et_al._-_Realtime_Ray_Tracing_on_GPU_with_BVH-based_Packet_Traversal.pdf。坦白地说,对于这个问题最好的回答将是关于GPU微架构的广泛讨论,而我根本没有资格给出那样的回答。查看像上面那篇现代GPU追踪论文将使您了解性能考虑有多深入。

最后需要注意的是:在光线追踪复杂场景时,计算着色相比于片元着色能够带来任何性能优势与栅格化/顶点着色器开销/混合操作开销等无关。对于复杂着色的复杂场景,瓶颈完全在追踪计算方面,而正如讨论过的那样,计算着色器可以更有效地实现这些工具。


2
我将完成Josh Parnell信息。
片段着色器和计算着色器的一个问题是它们都缺乏递归。
光线跟踪器本质上是递归的(是的,我知道总是可以将递归算法转换为非递归算法,但这并不总是那么容易)。
因此,看待问题的另一种方式可能是:
与其为每个像素拥有“一个线程”,不如为每个路径拥有一个线程(路径是您的光线的一部分(在两个反射之间))。
这样做,您正在调度您的“一堆”光线而不是您的“像素网格”。这样做简化了光线跟踪器的潜在递归,并避免了复杂材料中的分歧:
更多信息请参见: http://research.nvidia.com/publication/megakernels-considered-harmful-wavefront-path-tracing-gpus

我不确定你所说的“无递归”是什么意思。作为一个编写了雷达光线追踪器、场景追踪器和其他一些片段着色器的人,我不认为这是正确的。 要查看此方法的许多示例,请查看ShaderToy上的射线投射器。 - David Lannan
@DavidLannan 我是从射线的角度谈递归。 - Antoine Morrier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接