为什么像素着色器不让我们直接从帧缓冲区或深度缓冲区读取?


18

让我在像素着色器中采样帧缓冲区或深度缓冲区将是一个非常有用的功能。即使只是能够知道当前像素背后的深度或颜色,也会很有用。

为什么OpenGL和DirectX都不允许我这样做?我原本希望存在某种硬件限制,但是Alpha混合使用帧缓冲区中的颜色进行混合计算,而Z测试会在当前位置采样深度缓冲区。为什么不直接将这些价值观展示给我们呢?我希望以后能看到吗?

Answers:


20

硬件限制。片段着色器是可编程管线的一部分,但是与目标缓冲区的最终颜色混合此时无法在广泛使用的/商品硬件中进行编程(可以通过混合状态进行配置,但是您不能编写任意颜色替换GPU内置混合操作的代码)。

未为此构建硬件的原因可能与GPU大规模并行有关。他们一次处理许多碎片。这些片段中的某些片段最终可能会在目标缓冲区中相互交互,但是由于片段处理的异步特性,直到片段被处理并且发出最终颜色之后,才知道该怎么做...并非总是确定性地发生。

仅仅因为像素A将在最后一帧中位于像素B的后面,并不意味着像素A将始终完成片段处理并在B之前写入目标,特别是在多个渲染帧中。因此,在处理像素B的过程中从目标缓冲区读取的值将不会始终是像素A的值-有时将是清晰的值。

因此,我怀疑在片段阶段禁止直接目标缓冲区读取与阻止着色器程序员通过从读取结果中获得潜在的不确定性结果而使自己陷入困境相比,远比使混合阶段完全实现时的任何实际技术限制要重要得多。可编程的。通过严格控制读取操作(例如深度测试),GPU确保使用读取值完成的操作具有某种意义。

也就是说,可能还会有成本/收益方面的事情。使GPU流水线的这一方面可编程可在某种程度上使芯片设计复杂化,并且与其他功能相比,目标缓冲区读取的需求/需求相对较低。


只是为了对此进行扩展,帧缓冲区访问缓慢的历史原因是因为指令的流水线非常多。获得对给定帧缓冲区像素的访问权限将涉及暂停当前管线,直到刷新所有其他管线以完成与查询像素有关的任何渲染为止。即使在完全不并行的GPU的奇怪情况下,您仍然会为每个查询刷新整个管道,这是一个坏主意。毫无疑问,现在可编程硬件领域已经有些不同了,但是我希望可以应用类似的原理。
Kylotan

4

令人烦恼的是,它使硬件制造商能够灵活地以多种透明方式优化渲染过程。

例如,PowerVR硬件(通常用于白天,很长时间不使用)要等到要渲染的整个场景都提交后,再使用painters算法执行自动深度排序,而实际上并不需要生成深度缓冲区。它将把屏幕分成小块,然后依次渲染每个小块。


4

像素着色器无法从颜色和深度缓冲区读取,因为:

像素A和像素B在硬件中可能完全在同一时刻被着色,尽管像素B和像素B最终在像素A的顶部(“之后”)渲染。

如果这样做,则确保硬件在B之前先遮蔽A,则在A着色时,硬件的某些部分会无所事事,而在B着色时,硬件的某些部分将无所事事。

在可以想象的最坏情况下,您着色的所有像素都相互渲染,并且成千上万的GPU线程(除了一个以外的所有线程)都处于空闲状态。这个线程耐​​心地对像素A,然后B,然后C ...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.