延迟渲染与前片段着色器深度剔除



延迟渲染的所谓优势是它只允许片段着色器执行 numLights * numPixel 次。这是因为在前向渲染中,同一像素多次渲染两次。但是,如果在片段着色器之前和几何着色器之后执行深度剔除或 z 剔除,这将使其与延迟渲染一样高效,并且不需要大型 G 缓冲区。我相信在较新版本的OpenGL中可以做到这一点,那么为什么没有人这样做呢?如果我的想法有错误,请告诉我。

注意:也许这不是一个合适的问题,但我不知道我还能在哪里发布这个。

但是,如果在片段着色器之前和几何着色器之后执行深度剔除或 z 剔除,这将导致它与延迟渲染一样有效

不,不会。

您仍将为每个光源执行一次所有顶点处理阶段,因为标准前向渲染需要为每个光源绘制每个模型。在延迟渲染中,每个模型只绘制一次,因此可以节省顶点处理时间。

这很重要,因为许多现代硬件都使用所谓的"统一着色器架构"。这意味着硬件能够动态分配着色器工作负载。如果渲染大量顶点,但使用较短的片段着色器,则可以为 VS 阶段分配更多着色器单元。如果使用简单的 VS 但使用复杂的 FS 渲染 4 个顶点,则它可以为顶点阶段分配很少的硬件,而为片段着色器分配更多的硬件。

因此,在延迟渲染中,您将花费更多的可用着色器处理器时间来做有用的工作。通过前向渲染,您将 GPU 的资源拆分为有用的 FS 工作和重复且无用的 VS 工作。

接下来,您可能建议使用转换反馈来捕获呈现结果并重新呈现它们。但是现在你只是用一个瓶颈换另一个瓶颈:你占用更多的内存,你用VS工作换取内存带宽。


我只执行一次绘制调用,因此没有多余的几何体,而是使用灯光阵列作为统一来遍历片段着色器中的所有光源。

这只会用一种低效率换取另一种低效率,尽管这通常更快(但不太灵活)。您不必多次渲染每个网格,而是对不一定可见的片段运行非常耗时的 FS 调用。

早期的深度测试并不能保证任何事情。硬件无法保证执行的每个 FS 调用都是可见的,因为 GPU 可能尚未栅格化遮挡对象。早期的深度测试并不能确定事物的绘制顺序。

保证所有 FS 调用都可见的唯一方法是执行深度预传递。也就是说,您可以渲染场景中的所有内容,但没有片段着色器。所以唯一更新的是深度。然后,使用实际着色器再次渲染场景。

但是,您将渲染整个场景两次。着色器负载平衡可能要困难得多,因为整个对象都被剔除。

您必须认识到的另一件事是,延迟渲染并不能保证性能。它只是另一种渲染方法,有其自身的优点和缺点。您可以创建延迟渲染比任何前向渲染变体慢的情况。您还可以创建延迟渲染速度更快的环境。虽然随着光源数量的增加,延迟渲染通常是最好的选择,但总有一些情况可以使另一种渲染技术在性能上更胜一筹。

最新更新