【问题标题】:Shader framebuffer readback着色器帧缓冲区回读
【发布时间】:2011-05-21 22:16:33
【问题描述】:

我想知道较新的着色器模型是否支持从目标帧缓冲区读回像素值。我假设这已经在绘图管道的后期(非可编程)阶段完成,这让我希望这个功能可能已经添加到可编程管道中。

我知道可以绘制到纹理绑定帧缓冲区,然后将此纹理发送到着色器,我只是希望有一种更优雅的方式来实现相同的功能。

【问题讨论】:

    标签: glsl hlsl pixel-shader fragment-shader


    【解决方案1】:

    没有。正如您所提到的,渲染到纹理是实现该功能的方法。

    如果您查看 GPU 流水线的框图,您会发现混合阶段 - 将片段着色器输出与帧缓冲区相结合 - 与片段着色器分开并且是固定功能的。

    我不是 GPU 设计师 - 所以我只能推测其中的原因。大概是为了保持对帧缓冲区的快速访问,并将片段着色器阶段与帧缓冲区隔离,以便更好地并行化。可能还有关于多重采样等问题。

    (更不用说固定功能混合在大多数情况下“已经足够好”了。)

    【讨论】:

      【解决方案2】:

      正如 Andrew 所说,从逻辑上讲,帧缓冲区访问是与片段着色器分开的阶段,因此在片段着色器中读取帧缓冲区是不可能的。这样做的原因(回答 Andrew 的问题)是性能和图形管道的排序要求的结合。渲染管道的定义方式,帧缓冲区混合操作必须以与进入管道开头的三角形/基元相同的顺序发生。另一方面,片段着色器可以以任何顺序发生。因此,通过将它们设置为单独的阶段,GPU 可以在它们的输入可用时尽可能快地运行片段着色器,而无需在它们之间进行同步。只要它保持足够的缓冲区空间来保存片段着色器的输出,以便它们可以累积并允许帧缓冲区混合和写入按顺序发生,一切都很好,因为任何给定片段着色器的结果都是直到混合阶段之后才可见。

      如果片段着色器有办法读取帧缓冲区,则需要某种同步来确保这些读取按顺序进行,从而大大减慢速度。

      【讨论】:

        【解决方案3】:

        实际上,我认为 Direct3D 11 SM 5.0 现在可以做到这一点(虽然我没有测试过)。

        您可以将 UAV 绑定到 PS 5.0,以允许使用方法 OMSetRenderTargetsAndUnorderedAccessViews 对其进行读写操作。

        在这种情况下,必须使用标志 DXGI_USAGE_UNORDERED_ACCESS(我猜)创建您渲染的交换链的后缓冲区。

        这在 DXSDK OIT11 示例中使用。

        【讨论】:

          【解决方案4】:

          您可以绘制到纹理 TEX(使用渲染目标视图),然后将其作为输入绑定到另一个着色器(使用着色器资源视图)。 TEX 是一个伪帧缓冲区。

          【讨论】:

            【解决方案5】:

            可以在带有 Shader_framebuffer_fetch 扩展的片段着色器中读回帧缓冲区的内容。可以将支持添加到 GPU 中,但会造成一些性能损失。事实上,这些天来,我正在努力在消费电子市场知名 GPU 品牌的 OpenGL ES2.0 驱动程序中添加对这个扩展的支持。

            【讨论】:

              猜你喜欢
              • 2021-02-12
              • 2013-11-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-01
              • 2013-03-16
              相关资源
              最近更新 更多