多个缓冲器和 VAO 性能
Posted
技术标签:
【中文标题】多个缓冲器和 VAO 性能【英文标题】:Multiple buffers and VAO performance 【发布时间】:2014-10-04 11:34:18 【问题描述】:使用一个 vao 和一个缓冲区(VAO 将捕获对一个 VBO 的 glVertexAttribPointer 调用)和使用一个 vao 和多个缓冲区(VAO 将捕获对不同 VBO 的 glVertexAttribPointer 调用)之间是否存在性能差异。 ?
在这两种情况下,我必须在绘制之前绑定一次VAO,但是这个绑定调用的执行时间会改变吗?
【问题讨论】:
【参考方案1】:简而言之,是的,但实际上,执行时间非常短,可以忽略不计。如果您要制作任何动态场景,通常需要多个顶点缓冲区。将所有内容放在一个缓冲区中只会使事情复杂化。记住一句格言:从不及早优化。
【讨论】:
我不同意绑定VAO/VBO的执行时间可以忽略不计的说法。如果您分析受 CPU 限制的 OpenGL 应用程序(这很常见),那么设置顶点状态(包括 VAO/VBO 绑定)通常在 CPU 时间消耗者列表中非常重要。【参考方案2】:是的,它会变慢。为什么?因为渲染过程现在必须访问来自不同 VBO 的数据才能获得一个顶点的数据。数据分布在内存中,而如果一切都在一个 VBO 中,则您的数据是“交错的”。这会导致内存访问时间更快。
【讨论】:
我知道,我从来没有说过 VAO 是绑定 VBO 的。但是,当您绑定 VAO 并且使用多个 VBO 调用 glVertexPointer 调用时,VAO 必须指向多个 VBO 的数据,因此绑定调用应该更慢 哦,我明白了。好吧,是的,多个 VBO 会慢很多。最好将数据集中在一个地方。这会导致更快的内存访问时间。【参考方案3】:理论上,如果您使用一个 VBO,那么您不会导致很多缓存未命中,但是如果您有很多顶点,每个顶点都有位置、法线、紫外线、颜色、切线......那么驱动程序可能会决定将数组存储在客户端内存中,因此在这种情况下,使用多个 VBO 是有意义的。 个人而言,无论大小如何,我都会使用多个 VBO。
【讨论】:
【参考方案4】:在您的问题中,您假设您只会使用 VAO。在最近的 OpenGL 版本中,VAO 是强制性的,但您可以不使用 VAO(只需在初始化时绑定 1 个 VAO,然后您就会忘记它:这种解决方案被广泛使用)。
为每个 VBO 使用 VAO 或为每个 VBO 调用 glVertexAttribPointer 是否更快?这取决于驱动程序。为一个驱动程序进行优化时所招致的风险是使另一个驱动程序的速度变慢。
使用多个 VBO 还是使用少量 VBO 更快(它不依赖于您的 VAO)?这取决于你的瓶颈:
增加 VBO 的数量可能有助于进行截锥体剔除或遮挡剔除,从而有效地减少 GPU 的工作量(减少过度绘制和要处理的基元数量),但过多的 VBO 可能会导致最坏的情况更多 drawcalls 无论如何都会减慢速度。
没有更好的解决方案,这完全取决于您的问题和分析。
【讨论】:
错字。以下陈述假定“强制性”而非“非强制性”。我现在修好了以上是关于多个缓冲器和 VAO 性能的主要内容,如果未能解决你的问题,请参考以下文章
OpenGL - 正确地将 VAO 定义与 VBO 和其他缓冲区创建分开
c_cpp 使用VAO(顶点数组对象)和顶点缓冲区定义和绘制矩形。