将非多重采样的FBO复制到多重采样的FBO

时间:2016-12-03 23:59:42

标签: opengl-es fbo opengl-es-3.0 msaa

我一直在尝试在我们的应用程序中使用GLES 3实现渲染到纹理方法,我已经使它工作但我对帧速率下降有点失望。

到目前为止,我们已经直接渲染到主FBO,它是使用EGL_SAMPLES = 8创建的多重采样FBO。

我想要的基本上是能够抓住已经绘制的像素,而我还在画画。所以我认为渲染纹理方法应该这样做。然后,我只需要在我想要的时候阅读屏幕外FBO纹理的一部分,当我完成渲染时,我会把整个事情搞砸到主要的FBO。 / p>

深入研究我发现我必须实现一个带有多重采样FBO的系统以及一个非多重采样纹理FBO,我必须在其中解析多重采样的FBO。然后只是将解决方案搞砸到主要的FBO。

这一切都有效,但问题是通过使用上面的系统和非多重采样的主FBO(EGL_SAMPLES = 0),与我使用主FBO时获得的帧速率相比,我获得了相当大的帧速率下降使用EGL_SAMPLES = 8。

进一步深入研究我发现人们在线报道以及此处的帖子https://community.arm.com/thread/6925表示最快的多重采样方法是使用EGL_SAMPLES。事实上,这也是我们目标板上的jetson tk1的样子。

这最终引出了我的问题,并为长篇介绍道歉:

有没有什么方法可以设计这个来使用非多重采样的屏幕外fbo进行所有渲染,最终会被渲染到使用EGL_SAMPLES的主多重采样FBO?

2 个答案:

答案 0 :(得分:0)

  

有没有什么方法可以设计这个来使用非多重采样的屏幕外fbo进行所有渲染,最终会被渲染到使用EGL_SAMPLES的主多重采样FBO?

没有任何真正有用的方式。

帧缓冲区blitting确实允许从单采样缓冲区到多重采样缓冲区的blits。但所有这一切都是为像素中的每个样本提供与源中的样本相同的值。

Blitting无法生成新信息。所以你不会得到任何实际的抗锯齿。所有你得到的是以相当低效的方式存储的相同数据。

答案 1 :(得分:0)

MSAA的唯一要点是消除锯齿几何边缘。如果多个三角形边出现在同一像素中,它只会带来好处。为了渲染正在进行多次屏幕外传递的管道,您需要为包含几何体的离屏通道启用多个样本(通常是管道中的早期传递之一,在任何后处理效果之前)。

在最终blit的管道末端应用MSAA将提供零利益,并且可能不是免费的(在基于磁贴的渲染器上,例如IMG Series 6和Mali(您链接的博客),它将接近免费,在你的Jetson板上使用Nvidia等立即模式渲染时,自由度较低。

对于屏幕外抗锯齿的注意事项,“标准”方法呈现为MSAA帧缓冲,然后作为第二遍进行解析(例如,使用glBlitFramebuffer进行blit到单个采样缓冲区)。这种反弹在许多架构上都是低效的,因此这个扩展可以帮助:

实际上,这提供了与EGL窗口表面功能相同的隐式解析。

在评论中回答您的问题。

  

在这种情况下,生成的纹理是多重采样纹理吗?

从应用的角度来看,没有。多重采样数据位于由驱动程序分配的隐式分配的缓冲区内。请参阅规范的这一部分:

“实现使用TEXTURE_SAMPLES_EXT样本分配隐式多重采样缓冲区,并使用与指定纹理级别相同的内部格式,宽度和高度。”

这个可能需要在某些GPU架构的主内存中分配一个真正的MSAA缓冲区(因此没有比没有扩展的手动glBlitFramebuffer方法更快),但是已知是有效地释放其他人(即基于磁贴的GPU,其中隐式“缓冲区”是GPU内部的一个小RAM,而不是主内存中的。)

  

目标是模糊小部件背后的背景

MSAA绝不是通用模糊 - 它只对与三角形边缘重合的像素进行反锯齿。如果你想模糊三角形面,你最好只使用一对片段着色器实现的可分离高斯模糊,并将其作为2D后处理过程实现。