在 OpenGL 中处理 FBO 的最佳方法是什么?

发布于 2024-08-20 01:52:39 字数 390 浏览 8 评论 0原文

长期以来我一直想知道处理 OpenGL 帧缓冲区对象 (FBO) 的最佳方法是什么。 切换 FBO 的成本可能很高,但也需要定义新的附件。

如何快速做到这一点?

我在这 3 个之间犹豫不决:

  • 1 个 FBO 用于所有内容,更改附件但不在 FBO 之间切换

  • 每个渲染目标 1 个 FBO渲染路径中的(大小+格式)。这意味着我将针对类似的渲染目标重用相同的 FBO。但这样一来,自定义模糊将花费 4 个以上的 FBO。

  • 每个渲染目标 1 个 FBO,仅设置一次附件,然后在 FBO 之间切换

另外,我应该尽量减少 FBO 切换的数量(就像我最小化纹理绑定的数量)?

I wonder since a long time what would be the best way to handle OpenGL FrameBuffer Objects (FBO).
Switching FBOs can be costly but defining new attachments too.

How do you do it fast ?

I hesitate between these 3:

  • 1 FBO for everything, change attachment but don't switch between FBOs

  • 1 FBO for each render target (size + format) in the rendering path. That means i will reuse the same FBO for similar render targets. But this way a custom blur would cost 4+ FBOs.

  • 1 FBO for each render target, set attachments only once and then switch between FBOs

Also, should I minimize the number of FBO switches (like I minimize the number of texture bindings) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初与友歌 2024-08-27 01:52:39

更新参考:


NVIDIA 2005(可能已过时):
据我所知,NVIDIA 的最后一次官方性能推荐已经快五年了。 Simon Green 在他的 GDC 演示中推荐以下内容(幻灯片 29):

按照性能提高的顺序:

  1. 多个 FBO
    • 为要渲染的每个纹理创建一个单独的 FBO
    • 使用BindFramebuffer()进行切换
    • 在 Beta NVIDIA 驱动程序中,速度比 wglMakeCurrent() 快 2 倍
  2. 单个 FBO,多个纹理附件
    • 纹理应具有相同的格式和尺寸
    • 使用FramebufferTexture()在纹理之间切换
  3. 单个 FBO,多个纹理附件
    • 将纹理附加到不同颜色的附件
    • 使用glDrawBuffer()将渲染切换到不同颜色的附件

根据我的经验,第二种情况确实比第一种情况更快(ATI Radeon HD4850、Geforce 8800GT)。我没有尝试第三种情况,因为它会使我的代码变得复杂。

Updated references:


NVIDIA 2005 (probably outdated):
The last official performance recommendation by NVIDIA I know is almost five years old. In his GDC presentation, Simon Green recommends the following (slide 29):

In order of increasing performance:

  1. Multiple FBOs
    • create a separate FBO for each texture you want to render to
    • switch using BindFramebuffer()
    • can be 2x faster than wglMakeCurrent() in beta NVIDIA drivers
  2. Single FBO, multiple texture attachments
    • textures should have same format and dimensions
    • use FramebufferTexture() to switch between textures
  3. Single FBO, multiple texture attachments
    • attach textures to different color attachments
    • use glDrawBuffer() to switch rendering to different color attachments

In my experience, the second case is really faster than the first (ATI Radeon HD4850, Geforce 8800GT). I've not tried the third case, as it would have complicated my code.

久随 2024-08-27 01:52:39

从哲学上来说,修改对象状态需要重新验证它。相反,简单地更改对象绑定(从前一帧开始已经有效)对于驱动程序来说应该更快[1]。

因此,作为第一个实现,我会为每个渲染目标选择 1 个 FBO(或更准确地说,渲染目标设置。通常会一次渲染到多个缓冲区)。

也就是说,没有什么比针对多个实现对您的应用程序进行基准测试更好的了。

[1] 我提到驱动程序,因为 FBO 更改可能会强制 GPU 刷新,具体取决于架构。大多数情况下会产生气泡。所以这绝对是你不想经常做的事情。它比优化纹理绑定更重要,例如

As a matter of philosophy, modifying an object state requires that it be re-validated. Instead, simply changing the object binding (that's already valid from the previous frame) should be faster for the driver [1].

So as a first implementation, I'd go for 1 FBO for each render target (or more precisely, render target set. You usually render to multiple buffers at once).

That said, nothing beats benchmarking your app against multiple implementations.

[1] I mention for the driver, because an FBO change can force a GPU flush, depending on architecture. It will introduce bubbles in most cases. So it is definitely something that you don't want to do often. It's more important than optimizing the texture bindings, e.g.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文