我想知道在较新的着色器模型中是否支持从目标帧缓冲区读回像素值。我认为这在绘图管道的后期(非可编程)阶段是完成的,这使我希望这个特性可能已被添加到可编程管道中。
我知道可以绘制到纹理绑定的帧缓冲区,然后将此纹理发送到着色器,我只是希望有一种更优雅的方式来实现相同的功能。
答案 0 :(得分:4)
正如Andrew所说,帧缓冲访问在逻辑上是与片段着色器分开的一个阶段,因此在片段着色器中读取帧缓冲是不可能的。其原因(回答安德鲁的问题)是性能和图形管道的排序要求的结合。渲染管道定义的方式,帧缓冲混合操作必须以与进入管道开头的三角形/基元相同的顺序发生。另一方面,片段着色器可以按任何顺序发生。因此,通过让它们成为独立的阶段,GPU可以尽可能快地运行片段着色器,因为它们的输入变得可用,而无需在它们之间进行同步。只要它保持足够的缓冲区空间来保持片段着色器的输出,以便它们可以被累积并允许帧缓冲区混合和写入按顺序发生,一切都很好,因为任何给定片段着色器的结果都是直到混合阶段后才能看到。
如果片段着色器有一种方法可以读取帧缓冲区,则需要进行某种同步以确保这些读取按顺序发生,从而大大减慢了速度。
答案 1 :(得分:3)
没有。如您所述,渲染纹理是实现该功能的方法。
如果你看一下GPU管道的方框图,你会发现混合阶段 - 片段着色器输出和帧缓冲器的组合 - 与片段着色器分开并且是固定功能。 / p>
我不是GPU设计师 - 所以我只能推测出这个原因。据推测,它是保持帧缓冲区访问速度快,并将片段着色器阶段与帧缓冲区隔离,以便更好地并行化。关于多次采样可能还有一些问题,等等。
(更不用说固定功能混合在大多数情况下都“足够好”。)
答案 2 :(得分:2)
实际上我认为现在可以使用Direct3D 11 SM 5.0(虽然我没有测试)。
您可以将UAV绑定到PS 5.0,以便使用方法OMSetRenderTargetsAndUnorderedAccessViews
对其进行读写操作。
在这种情况下,您渲染的交换链的后备缓冲区必须使用标记DXGI_USAGE_UNORDERED_ACCESS
创建(我猜)。
这用于DXSDK OIT11样本。
答案 3 :(得分:1)
可以使用Shader_framebuffer_fetch扩展回读片段着色器中帧缓冲区的内容。支持可以添加到GPU,但性能会有所下降。事实上,这些天我正在努力在消费电子市场的知名GPU品牌的OpenGL ES2.0驱动程序中添加此扩展的支持。
答案 4 :(得分:0)
您可以绘制到纹理TEX(使用渲染目标视图),然后将其作为输入绑定到另一个着色器(使用着色器资源视图)。然后TEXT是一个伪帧缓冲区。