1

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

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

我想要的基本上是能够在我仍在绘制的同时获取已经绘制的像素。所以我认为应该使用渲染到纹理的方法。然后我会随时阅读屏幕外 FBO 纹理的一部分,当我完成对它的渲染时,我会将整个内容传送到主 FBO。

深入研究这一点,我发现我必须实现一个具有多重采样 FBO 和非多重采样纹理 FBO 的系统,其中我必须解决多重采样的 FBO。然后只需将已解析到主 FBO 即可。

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

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

这最终将我引向了这个问题,并为冗长的介绍道歉:

有什么方法可以设计它以使用非多重采样的屏幕外 fbo 进行最终被传送到使用 EGL_SAMPLES 的主多重采样 FBO 的所有渲染?

4

2 回答 2

1

MSAA 的唯一目的是消除几何边缘的锯齿。只有当多个三角形边缘出现在同一个像素中时,它才会提供好处。对于执行多个屏幕外通道的渲染管道,您希望为包含您的几何体的屏幕外通道启用多个样本(通常是管道中的早期通道之一,在任何后处理效果之前)。

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

注意屏幕外抗锯齿的“标准”方法是渲染到 MSAA 帧缓冲区,然后作为第二遍解析(例如,使用 glBlitFramebuffer 将 blit 放入单个采样缓冲区)。这种反弹在许多架构上效率很低,所以这个扩展的存在是为了帮助:

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

在评论中回答您的问题。

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

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

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

可能需要在某些 GPU 架构上的主内存中分配真正的 MSAA 缓冲区(因此不会比glBlitFramebuffer没有扩展的手动方法快),但已知在其他架构上是有效的(即基于图块的 GPU,其中隐含的“缓冲区" 是 GPU 内部的一个小 RAM,根本不在主存储器中)。

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

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

于 2016-12-05T11:48:28.790 回答
0

有什么方法可以设计它以使用非多重采样的屏幕外 fbo 进行最终被传送到使用 EGL_SAMPLES 的主多重采样 FBO 的所有渲染?

不是以任何真正有用的方式。

Framebuffer blitting 确实允许从单采样缓冲区到多采样缓冲区的 blit。但所做的只是为像素内的每个样本赋予与源样本相同的值。

位图无法生成新信息。所以你不会得到任何实际的抗锯齿。您将得到的只是相同的数据以一种效率低得多的方式存储。

于 2016-12-04T02:57:21.400 回答