16

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

你怎么做的

我在这三个之间犹豫:

  • 1个FBO,改变附件,但不要在FBO之间切换

  • 渲染路径中每个渲染目标(大小 + 格式)的 1 个 FBO。这意味着我将为类似的渲染目标重用相同的 FBO。但这种方式自定义模糊将花费 4+ FBO。

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

另外,我应该尽量减少 FBO 开关的数量(就像我尽量减少纹理绑定的数量一样)?

4

2 回答 2

14

更新的参考资料:


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

为了提高性能:

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

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

于 2010-02-04T23:10:28.443 回答
4

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

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

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

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

于 2010-02-04T12:09:14.843 回答