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

时间:2010-02-04 09:30:39

标签: opengl rendering gpu fbo

我很想知道很长一段时间处理OpenGL FrameBuffer对象(FBO)的最佳方法。 切换FBO可能成本很高,但也定义了新的附件。

你是如何做到的?快速

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

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

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

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

另外,我应该最小化FBO开关的数量(比如我最小化纹理绑定的数量)?

2 个答案:

答案 0 :(得分:14)

更新了参考文献:


NVIDIA 2005(可能已过时): 我所知道的NVIDIA上一次官方性能建议差不多有五年了。在他的GDC presentation中,Simon Green建议如下(幻灯片29):

  

为了提高绩效:

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

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

答案 1 :(得分:4)

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

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

也就是说,没有什么可以将您的应用程序与多个实现进行对比。

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