多个帧缓冲对象,帧率急剧下降

Posted

技术标签:

【中文标题】多个帧缓冲对象,帧率急剧下降【英文标题】:Multiple frame buffer object, frame rate drop dramatically 【发布时间】:2013-05-08 12:01:40 【问题描述】:

情况如下: 我使用 2 个 FBO,1 个用于图像过滤分辨率 640*480,另一个用于使用过滤图像分辨率 1024*768 进行真实渲染。然而,帧率远低于我的预期,例如 30+ fps -> 15 fps。 我检查了代码的每一步,发现(这是我创建的一个额外的 FBO):

// Render to our holefilling framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, holeFillingFramebufferName);
//Attach depth buffer to the FBO
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthBufferTexture, 0);
// No color output in the bound framebuffer, only depth.
glDrawBuffer(GL_NONE);

// Always check that our framebuffer is ok
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    return false;
// image filtering staff

这部分需要很长时间,我相信平均需要 30 毫秒。于是我评论了glCheckFramebufferStatus行,发现时间转移到了下面的部分。我认为这是因为系统需要时间在图像过滤作业开始之前准备 FBO。我试图将两个 FBO 更改为相同的分辨率,但似乎没有任何区别。 有什么加快速度的技巧吗?

附:我使用 OpenGL/glsl 3.3 和 glfw,VS2010 Win7

【问题讨论】:

您是否尝试过不将相同的纹理绑定到每一帧的深度附件?我就呆在那里;在设置 FBO 时,您只需执行一次。 是的,没错。我明天试试。顺便说一句,我想知道OpenGL操作是否昂贵,我在哪里可以找到相关文档?它应该取决于卡和平台,对吧?我猜纹理附件很昂贵,因为它可能涉及许多状态和缓存更改。 我认为“纹理附件很昂贵”的想法是错误的......在这个链接“songho.ca/opengl/gl_fbo.html”中,据说“帧缓冲区对象(FBO)提供了一种有效的切换机制;分离前面的来自FBO的framebuffer-attachable图像,并将新的framebuffer-attachable图像附加到FBO。切换framebuffer-attachable图像比在FBO之间切换要快得多。FBO提供glFramebufferTexture2D()切换2D纹理对象,glFramebufferRenderbuffer()切换渲染缓冲区对象。” 【参考方案1】:

避免更改 FBO 上的附件。这是一项昂贵的操作,因为它会导致驱动程序需要重新验证 FBO,这就是您的示例中发生的情况。您只需要绑定一次深度附件,而不是每帧。如果每帧绑定它,就会导致驱动程序每帧都验证 FBO,这很昂贵。

不幸的是,MagicTracy 引用的建议与事实完全相反。切换 FBO 很便宜,而更改 FBO 的附件很昂贵(同样,因为它需要重新验证)。

Valve 在他们的演讲“将源代码移植到 Linux - Valve 的经验教训”中描述了这一点。请参阅第 64 和 65 页:https://developer.nvidia.com/sites/default/files/akamai/gamedev/docs/Porting%20Source%20to%20Linux.pdf。

【讨论】:

以上是关于多个帧缓冲对象,帧率急剧下降的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL帧缓冲性能问题

COLOR_ATTACHMENT's - 如何将多个纹理渲染为帧缓冲区对象内的颜色附件?

OpenGL阴影映射,具有多个glDrawElements的帧缓冲区

如何在多采样纹理上渲染帧缓冲区对象?

显示 MTKView 的当前帧率

多个视口与多个帧缓冲区之间的使用差异是啥?