使用顶点缓冲对象处理非常动态的数据在性能方面是否是个好主意?

17

我有许多粒子,每帧的顶点都会改变。当前使用客户端内存中的顶点数组进行绘制。如果我使用顶点缓冲对象,可以期望什么性能特征?

由于我必须使用多个glBuffersubData来更新粒子顶点,因此我每帧都会将顶点传输到视频内存中(就像使用普通的顶点数组一样),在这种情况下,VBO是否有任何好处?

这是为iOS设备准备的。实际绘制调用:glDrawElements(GL_POINTS,num_particles,GL_UNSIGNED_SHORT,pindices);

我应该使用GL_STREAM_DRAW还是GL_DYNAMIC_DRAW?

2个回答

5

苹果公司的文档似乎建议在所有情况下都使用VBO。如果你正在使用ES 2.x,那么GL_STREAM_DRAW顶点缓冲类型专门用于“当你的应用程序需要创建临时几何体,并渲染少量次数后将其丢弃。当你的应用程序必须每帧以无法在顶点着色器中执行的方式动态更改顶点数据时,这是最有用的。”然后直接提倡使用glBufferSubData。

逻辑上讲,我想,仅在完全提供数据和将其发送到现有的GL_STREAM_DRAW或GL_DYNAMIC_DRAW缓冲区之间的唯一区别是可以一次分配内存映射空间(GPU或CPU,取决于芯片- MBX实际上不支持VBOs,但苹果支持它们出于其他性能原因)而不是每帧分配并释放。

使用文档中提供的对齐和打包技巧可能比切换到VBOs更有利,因为否则CPU只需在glDrawElements时解压和重新打包数据。虽然您很可能已经意识到这一点,我很感激它并不直接涉及问题——我主要是将其作为性能优化的比较猜测。


CPU需要做的取决于图形芯片和驱动程序。对齐与性能无关,数据类型有关,而重新打包是由驱动程序完成的。关键是使用图形芯片中的内部数据类型,然后驱动程序就没有什么要做的了。 - BЈовић
相反,苹果的文档(在我的回答中提供链接)明确指出:“未对齐的数据需要更多的处理,特别是当您的应用程序使用顶点缓冲区时。”请看最后一句话。假设您是ADC会员,请参见例如https://devforums.apple.com/message/320610#320610,这是苹果员工再次解释对齐速度优势。内存控制器通常通过读取两个相邻值并组合结果来读取未对齐的值-因此一个读取需要两个内存获取而不是一个。 - Tommy
好的,我对 iPhone 没有任何了解,而且我也不知道这个问题是关于 iPhone 的。我的回答是针对 OpenGL(适用于 PC)的一般性回答。 - BЈовић
哦,是的,完全同意。对齐只是因为苹果公司已经很好地记录了驱动程序和硬件规格,超出了GL规范。希望我没有听起来很粗鲁。 - Tommy
很不幸,我正在使用ES 1.1,所以我不能使用STREAM_DRAW。我仍然不确定VBO是否更快,因为我必须为每个粒子索引做一个子缓冲区(如果我在数组中进行创意,可能会少一些)。或者为所有内容创建一个大的子缓冲区。而没有VBO,它只会为“活动粒子”(根据我发送的索引数量)分配/复制。尽管这是一个非常特定的优化案例,但如果它成为瓶颈,我将进行一些测试。感谢您找到苹果的官方说法。 - Ari Ronen
鉴于您计划进行测试,并且无法讨论开发人员计划成员可用的任何Beta软件,我认为重复苹果公开表示的内容(例如,http://developer.apple.com/technologies/tools/whats-new.html)可能是相关的。关于Xcode 4版本中Instruments的新功能包括:“[n]ew数据收集工具也可用,包括OpenGL ES,可跟踪iPhone图形性能”。 - Tommy

2
通过正确设置VBO,您可以使用最佳的方式将数据传输到GPU。这样做可能会跳过某些驱动程序处理。唯一确定提升了多少性能的方法是进行测量。不同的显卡有所不同。
有关如何使用VBO,请参见此页面:VBO教程 编辑:忘记回答问题了:是个好主意。但是请先进行测量。

我不认为VBO始终是最优的,由众多BufferSubDatas甚至更糟糕的mapBuffer引起的开销(因为它必须将缓冲区复制回客户端)可能比顶点数组的开销更大。确实需要对每个显卡进行彻底的测试才能确定,我只是想看看是否可以从群众的知识中汲取经验...因为在这一点上,这种测试工作并不值得。 - Ari Ronen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接