Opengl 绑定FBO(帧缓冲区对象)的成本有多高
绑定帧缓冲区对象的成本有多高,即使用glBindFramebuffer(GL_framebuffer,…)?我在谷歌上找不到任何关于每帧更改帧缓冲区的实际次数的信息。我之所以要求,是因为我编写了一个支持C++中的后处理的2D渲染器,并且在每个绘制调用开始时显式绑定帧缓冲区(多边形、线条、图像)是最优雅的代码路径,但到目前为止,我还没有足够的东西来画它。在每次绘制调用开始时绑定帧缓冲区的替代方法是始终保持绑定,除非我需要绘制到屏幕,但这需要我不交错调用两个不同的渲染器实例(这是可行的,但有限制) 我发现了,但它已经有四年多的历史了(引用的文本比它早了五年),而且它并没有完全回答相同的问题。每帧多次绑定和解除绑定FBO造成的性能损失是否足以保证手动管理绑定的帧缓冲区 绑定帧缓冲区对象的成本有多高 不多。从本质上讲,OpenGL实现的工作量并不比双缓冲区交换后多多少 真正影响性能的是切换FBO的附件,因为每次发生这种情况时,都必须检查FBO的有效性,这是一项成本高昂的操作Opengl 绑定FBO(帧缓冲区对象)的成本有多高,opengl,Opengl,绑定帧缓冲区对象的成本有多高,即使用glBindFramebuffer(GL_framebuffer,…)?我在谷歌上找不到任何关于每帧更改帧缓冲区的实际次数的信息。我之所以要求,是因为我编写了一个支持C++中的后处理的2D渲染器,并且在每个绘制调用开始时显式绑定帧缓冲区(多边形、线条、图像)是最优雅的代码路径,但到目前为止,我还没有足够的东西来画它。在每次绘制调用开始时绑定帧缓冲区的替代方法是始终保持绑定,除非我需要绘制到屏幕,但这需要我不交错调用两个不同的渲染器实例(这是可行的,但有限制)
有趣的是,在现有OpenGL实现中切换顶点数组对象(VAO)非常昂贵,到目前为止,业界的常见做法是重新绑定缓冲区对象和顶点属性指针/偏移。我只是提到这一点,因为从表面上看,FBO和VAO的外观和行为非常相似,但它们现在表现出非常不同的性能特征。由于性能特征通常是这样,因此没有一个简单的答案。这在很大程度上取决于硬件体系结构、驱动程序优化和使用条件 给你的tl;dr first:切换渲染曲面可能比较便宜,也可能非常昂贵。我的建议如下:
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glDraw...(...);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glDraw...(...);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
在本例中,您进行了glBindFramebuffer()
调用,但所有渲染都将转到同一个帧缓冲区。我希望大多数驱动程序能够检测到这些绑定调用是多余的,并且不会做任何严肃的工作。尽管有时在驾驶者是否应该检测到冗余状态变化的问题上存在哲学上的争议,但大多数情况下是这样的
在这种情况下,这取决于您对GPU/驱动程序供应商的信任程度。除非我做了基准测试,否则在这种情况下我倾向于偏执。如果在我的软件架构中有任何合理的方法可以做到这一点,我会避免冗余调用
实际帧缓冲区开关
正如我在介绍中提到的,这里发生的事情高度依赖于GPU和驱动程序。只需将状态切换为点渲染到不同的目标是便宜的。但还有很多
通常会有与活动渲染目标关联的额外内存分配。典型示例包括用于早期深度测试的缓冲区和压缩颜色缓冲区。当切换到不同的渲染目标时,这些分配会发生什么情况取决于硬件体系结构、驱动程序实现以及可能的其他条件:
- 只要有足够的空间,就有可能使循环经过的所有渲染曲面的这些分配保持活动状态,并在它们之间切换以及实际的渲染目标切换。在这种情况下,开销很小
- 如果这些分配在片上内存中,空间可能非常有限。如果没有足够的空间将它们全部保留在芯片上,则旧表面的分配可能会被逐出到视频内存(如果GPU有)或系统内存中,并重新加载新表面的分配。这可能相当昂贵
- GPU/驱动程序可能不支持收回和重新加载这些分配,并且可能必须将其内容解析为实际缓冲区(例如,展开压缩颜色缓冲区的内容,并将其写回完整颜色缓冲区)。这个很贵