opengl - 如何加快大量 VAO 的渲染速度
问题描述
我有一个非常大的 VBO 和 VAOS 列表存储在一个静态数组中。每个 VBO 在数组中的相应偏移处与 VAO 绑定。任何 VBO/VAO 都可以独立更新,所以我不能把它转换成一个大的 VBO/VAO。
我的渲染循环看起来像这样:
for(int i = 0; i < VAO_COUNT; i++){
glBindVertexArray(vao[i]);
glDrawArrays(GL_TRIANGLES, ...);
}
对 glBindVertexArray 的大量调用使其执行相对于正在渲染的多边形数量非常慢。我知道绑定顶点数组的成本很高,但是根据我设置事物的方式,是否有不同的方法来呈现这个列表,效果会更好?
解决方案
渲染引擎的性能很大程度上取决于它对渲染的内容的控制程度。发动机施加的控制越少,发动机对性能的控制就越少。
因此,当您说“任何 VBO/VAO 都可以独立更新,因此我无法将其转换为一个大 VBO/VAO”时,这表示基本上无法控制顶点输入数据的任何方面。缺乏控制直接转化为缺乏绩效。您可以对正在渲染的网格的存储和布局施加的任何控制都可以转化为改进的性能。
注意:以下假设您使用单独的属性格式调用来操作您的 VAO。
理想情况下,某些类型的所有网格(蒙皮、未蒙皮地形、UI 等)将对其顶点数组使用相同的格式并使用相同的缓冲区对象进行存储。因此,渲染一系列网格将只是一个单一的 VAO 绑定、对 的调用glBindVertexBuffers
以及一些glDrawElementsBaseVertex
或等效的调用。这里的目标是,虽然您可以允许一些顶点格式和缓冲区,但渲染的内容量不会影响完成多少绑定调用。
下面的下一步是允许不同的网格(或网格组)使用不同的缓冲区对象。但是它们仍然会共享相同的顶点格式(又名:由 设置的状态glVertexAttribFormat
)。即使在这里,您也想尽可能多地尝试共享缓冲区对象。在这种情况下,绘制一系列使用相同顶点格式的网格开始于绑定 VAO 并迭代网格。对于每个网格,您调用glBindVertexBuffers
然后绘制它。如果多个网格使用公共缓冲区,那么您应该按缓冲区对绘制进行排序。
如果您不愿意至少控制顶点数据的格式,那么至少从这个角度来看,您能做的也不会更好。
推荐阅读
- java - Java 方法能否根据方法中的条件返回不同的类型?
- python - 在 python 中编写 Discord 机器人 - 如何让机器人从一组图像中发送随机图像?
- markdown - Mathjax + Markdown + Jekyll,移动设备白色对象覆盖数学文本问题
- ruby-on-rails - 未创建数据库记录,可能是关系问题?
- c++ - 为什么这些指针是相同的,却指向一个对象的不同实例?
- asp.net-core-webapi - 在 ASP NET Core Web API 中进行 OTP 验证后发出 JWT
- fluxcd - 有没有办法手动重试 FluxCD HelmOperator 的 HelmRelease?
- javascript - 如何在 react-native 中触发特定页面上的引用?
- python - 如何使用 Python 套接字模块连接到 node.js 中的 socket.io 服务器?
- python - 由于登录代码导致的 Django 属性错误,我无法运行迁移