首页 > 解决方案 > 如何加快大量 VAO 的渲染速度

问题描述

我有一个非常大的 VBO 和 VAOS 列表存储在一个静态数组中。每个 VBO 在数组中的相应偏移处与 VAO 绑定。任何 VBO/VAO 都可以独立更新,所以我不能把它转换成一个大的 VBO/VAO。

我的渲染循环看起来像这样:

for(int i = 0; i < VAO_COUNT; i++){
    glBindVertexArray(vao[i]);
    glDrawArrays(GL_TRIANGLES, ...);
}

对 glBindVertexArray 的大量调用使其执行相对于正在渲染的多边形数量非常慢。我知道绑定顶点数组的成本很高,但是根据我设置事物的方式,是否有不同的方法来呈现这个列表,效果会更好?

标签: openglvbovao

解决方案


渲染引擎的性能很大程度上取决于它对渲染的内容的控制程度。发动机施加的控制越少,发动机对性能的控制就越少。

因此,当您说“任何 VBO/VAO 都可以独立更新,因此我无法将其转换为一个大 VBO/VAO”时,这表示基本上无法控制顶点输入数据的任何方面。缺乏控制直接转化为缺乏绩效。您可以对正在渲染的网格的存储和布局施加的任何控制都可以转化为改进的性能。

注意:以下假设您使用单独的属性格式调用来操作您的 VAO。

理想情况下,某些类型的所有网格(蒙皮、未蒙皮地形、UI 等)将对其顶点数组使用相同的格式使用相同的缓冲区对象进行存储。因此,渲染一系列网格将只是一个单一的 VAO 绑定、对 的调用glBindVertexBuffers以及一些glDrawElementsBaseVertex或等效的调用。这里的目标是,虽然您可以允许一些顶点格式和缓冲区,但渲染的内容量不会影响完成多少绑定调用。

下面的下一步是允许不同的网格(或网格组)使用不同的缓冲区对象。但是它们仍然会共享相同的顶点格式(又名:由 设置的状态glVertexAttribFormat)。即使在这里,您也想尽可能多地尝试共享缓冲区对象。在这种情况下,绘制一系列使用相同顶点格式的网格开始于绑定 VAO 并迭代网格。对于每个网格,您调用glBindVertexBuffers然后绘制它。如果多个网格使用公共缓冲区,那么您应该按缓冲区对绘制进行排序。

如果您不愿意至少控制顶点数据的格式,那么至少从这个角度来看,您能做的也不会更好。


推荐阅读