【问题标题】:Should I update multiple VBO's with multiple glBufferSubData() calls or a single VBO with one glBufferSubData() call?我应该使用多个 glBufferSubData() 调用更新多个 VBO,还是使用一个 glBufferSubData() 调用更新单个 VBO?
【发布时间】:2017-02-15 00:03:31
【问题描述】:

我有 38 个具有不同着色器的粒子系统,每个粒子系统可以在世界上不同的地方(发射器)渲染多达 200 次。 每帧我唯一需要更新(上传到 GPU)的是发射器位置(可能还有某些系统中的其他一些属性), 当且仅当任何粒子系统处于活动状态且在视锥中可见。

我是否应该像这样分配和更新所有内容: - 为每个可以处理多达 200 个发射器的粒子系统分配一个 VBO。使用 glBufferSubData() 为每个粒子系统每帧更新 0 到 200 个发射器。 为每个粒子系统执行一次绘制调用。

在最坏的情况下,我们需要执行 38 次 glBufferSubData() 调用!

或者,我应该这样做(共享 VBO): -分配一个非常大的 VBO,最多可以处理 38(粒子系统)* 200(每个粒子系统的发射器)。使用单个更新所有粒子系统 调用 glBufferSubData()。在这种情况下,我们需要对每个粒子系统的所有发射器进行分组, 因为每个绘制调用都必须知道每个粒子系统及其发射器的起始偏移量。 为每个粒子系统执行一次绘制调用。

我们只需要调用一次 glBufferSubData() !

案例 nr 2 显然是赢家,但我有一些疑问。我们知道 38 个粒子系统共享一个 VBO, 但是如何停止 GPU 流水线呢? 当且仅当所有 38 个粒子系统都完成渲染时,图形驱动程序才能执行 VBO 更新,即不从 VBO 读取任何数据。

我发现了这一点:考虑使用多个缓冲区对象以避免在数据存储更新期间停止渲染管道。如果管道中的任何渲染引用了由 glBufferSubData 更新的缓冲区对象中的数据,尤其是来自正在更新的特定区域的数据,则该渲染必须从管道中排出,然后才能更新数据存储。

这里:https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferSubData.xhtml

对于案例 nr 2,我应该使用双倍甚至三倍缓冲吗?

【问题讨论】:

  • 38*200 = 7600 个职位不算什么。 GPU 应该在短暂的闪烁中渲染它们。为什么要打扰?
  • 每个发射器位置代表 GPU 上的 150-300 个粒子。最大的问题是,应该如何处理 CPU-GPU 传输,而不是 GPU 计算/渲染部分。
  • 好的。 200万不算小,但也不算大。对其进行基准测试。如果两种方式都很慢(第一种方式,绘制一半,上传并绘制其余部分)您最好阅读第 28 章异步...openglinsights.com
  • 感谢 Ripi2,一篇非常好的文章!我的解决方案:使用 Round Robin 分配三重缓冲,并在每帧调用一次 glBufferSubData()(如果在我们的截锥体中可见任何粒子系统)。 glMapBufferRange() 可以比 glBufferSubData() 更快,但是即使我们根据 AZDO(接近零驱动程序开销)指定 GL_MAP_UNSYNCHRONIZED_BIT,多线程驱动程序也可以强制同步。持久映射流需要 OpenGL 4.4...

标签: opengl vbo


【解决方案1】:

与图形方面的许多优化一样,这是一种权衡。通过将所有缓冲区合并为一个缓冲区,您可以减少为平均情况绘制粒子系统所需的状态更改次数。但是,如果您在系统不在截锥体中时跳过glBufferSubData(),那么您就会错过减少的总线带宽。

除非整个缓冲区的大小超过几 MB(想想高分辨率视频流中一两帧的大小),否则我不会担心 GPU 管道的停滞。更改 VBO 比更改着色器或帧缓冲区更便宜。

这主要取决于您有更多的空闲时间:GPU 处理/同步时间(以状态更改的形式)或 PCI-e 总线带宽。

【讨论】:

  • 感谢您的回答!是的,有时很难在不同的解决方案之间做出选择。我的解决方案:使用循环分配三个大缓冲区对象(避免隐式同步)并分配一个大的浮点向量。这个向量包含了我们在这个帧中可以看到的所有信息,并且这个向量将通过调用 glBufferSubData() 上传到 GPU。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多