着色器帧缓冲区读回
我想知道较新的着色器模型是否支持从目标帧缓冲区读回像素值。我认为这已经在绘图管道的后期(不可编程)阶段完成,这让我希望这个功能可能已添加到可编程管道中。
我知道可以绘制到纹理绑定帧缓冲区,然后将该纹理发送到着色器,我只是希望有一种更优雅的方式来实现相同的功能。
I was wondering if there is support in the newer shader models to read-back a pixel value from the target framebuffer. I assume that this is alrdy done in later (non-programmable) stages in the drawing pipeline which made me hope that this feature might have been added into the programmable pipeline.
I am aware that it is possible to draw to a texture bound framebuffer and then send this texture to the shader, I was just hoping for a more elegant way to achieve the same functionality.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如安德鲁所指出的,帧缓冲区访问在逻辑上是与片段着色器分开的阶段,因此在片段着色器中读取帧缓冲区是不可能的。这样做的原因(回答安德鲁的问题)是性能和图形管道的排序要求的结合。根据渲染管道的定义方式,帧缓冲区混合操作必须按照与进入管道开头的三角形/图元相同的顺序进行。另一方面,片段着色器可以按任何顺序发生。因此,通过让它们成为单独的阶段,GPU 可以在它们的输入可用时尽可能快地运行片段着色器,而无需在它们之间进行同步。只要它保持足够的缓冲区空间来保存片段着色器的输出,以便它们可以累积并允许帧缓冲区混合和写入按顺序发生,一切都很好,因为任何给定片段着色器的结果都是直到混合阶段之后才可见。
如果片段着色器有办法读取帧缓冲区,则需要某种同步来确保这些读取按顺序发生,从而大大减慢速度。
As Andrew notes, the framebuffer access is logically a separate stage from the fragment shader, so reading the framebuffer in the fragment shader is impossible. The reason for this (to answer Andrew's question) is a combination of performance and the ordering requirements of the graphics pipeline. The way the rendering pipeline is defined, framebuffer blending operations MUST occur in the same order as the triangles/primitives that went into the beginning of the pipeline. The fragment shaders, on the other hand, can happen in any order. So by having them be separate stages, the GPU is free to run fragment shaders as fast as it can, as their inputs become available, without having to synchronize between them. As long as it maintains enough bufffer space to hold on to the outputs of the fragment shaders, so that they can be accumulated and allow the framebuffer blends and writes to occur in order, all is well, as the results of any given fragment shader are not visible until after the blending stage.
If there was a way for the fragment shader to read the framebuffer, it would require some sort of synchronization to ensure that those reads happen in order, thus greatly slowing things down.
不。正如您提到的,渲染到纹理是实现该功能的方法。
如果您查看 GPU 管道的框图,您会发现混合阶段(将片段着色器输出与帧缓冲区相结合)与片段着色器是分开的,并且是固定功能的。
我不是 GPU 设计师 - 所以我只能推测其原因。大概是为了保持帧缓冲区访问快速并将片段着色器阶段与帧缓冲区隔离,以便可以更好地并行化。可能还存在有关多重采样等问题。
(更不用说固定功能混合在大多数情况下“足够好”。)
No. As you mention, rendering to a texture is the way to achieve that functionality.
If you take a look at a block diagram of a GPU pipeline, you'll see that the blending stage - which is what combines fragment shader output with the framebuffer - is separate from the fragment shader and is fixed-function.
I'm not a GPU designer - so I can only speculate the reason for this. Presumably it is to keep framebuffer access fast and insulate the fragment shader stage from the frame buffer so that it can be better parallelised. There are probably also issues regarding multi-sampling, and so on.
(Not to mention that fixed-function blending is "good enough" in most cases.)
实际上我认为现在 Direct3D 11 SM 5.0 可以实现这一点(不过我没有测试过)。
您可以将 UAV 绑定到 PS 5.0,以允许使用 OMSetRenderTargetsAndUnorderedAccessViews 方法对其进行读写操作。
在这种情况下,必须使用标志
DXGI_USAGE_UNORDERED_ACCESS
创建渲染的交换链的后缓冲区(我猜)。这在 DXSDK OIT11 示例中使用。
Actually I think this is now doable with Direct3D 11 SM 5.0 (I didn't test it though).
You can bind an UAV to a PS 5.0, for allowing read and write operations on it using method
OMSetRenderTargetsAndUnorderedAccessViews
.In that case the backbuffer of the swap chain in which you render has to be created with flag
DXGI_USAGE_UNORDERED_ACCESS
(I guess).This is used in DXSDK OIT11 sample.
可以使用 Shader_framebuffer_fetch 扩展在片段着色器中读回帧缓冲区的内容。可以将支持添加到 GPU,但会造成一些性能损失。事实上,这些天我正在致力于在消费电子市场上一个知名GPU品牌的OpenGL ES2.0驱动程序中添加对此扩展的支持。
It is possible to read back the contents of the frame buffer in the fragment shader with Shader_framebuffer_fetch extension. The support can be added to the GPU with some performance loss. In fact, these days I'm working on to add the support of this extension in the OpenGL ES2.0 driver of a well known GPU brand in the consumer electronics market.
您可以绘制纹理 TEX(使用渲染目标视图),然后将其作为输入绑定到另一个着色器(使用着色器资源视图)。那么 TEX 就是一个伪帧缓冲区。
You can draw to a texture TEX (using a render target view) and then bind that as an input to another shader (using a shader resource view). TEX is then a pseduo-framebuffer.