c++ - 使用相同的着色器但不具有相同的纹理或颜色绘制多个 VAO 的最佳方法是什么

标签 c++ opengl

我想知道如果我想画画最好做什么 超过约 6000 个不同的 VAO 使用相同的着色器。

目前,我绑定(bind)我的着色器,然后为其提供所需的所有信息(统一),然后循环遍历每个 VAO 来绑定(bind)并绘制它们。

此代码使我的计算机的帧速率下降到约 200 fps,而不是 3000 或 4000。 根据 https://learnopengl.com/Advanced-OpenGL/Instancing ,使用 glDrawElementsInstanced 可以让我处理大量相同的 VAO,但由于我有大约 6000 个不同的 VAO,所以我似乎无法使用它。

有人可以向我证实这一点吗?你们会怎么做才能吸引这么多 VAO 并尽可能节省性能?

最佳答案

第 1 步:不要有 6,000 种不同的 VAO。

毫无疑问,您将每个 VAO 视为一个单独的网格。别再这样做了。您应该将每个 VAO 视为单独的顶点格式。也就是说,如果您传递不同种类的顶点数据,则只需要一个新的 VAO。属性的个数和每个属性的格式构成了格式信息。

理想情况下,您只需要 4 到 10 组独立的顶点格式。鉴于您在多个 VAO 上使用相同的着色器,您可能已经有了这样的理解。

那么,如何对多个网格使用相同的 VAO?理想情况下,您可以通过将特定类型网格(即:顶点格式)的所有网格数据放入相同的缓冲区对象中来实现此目的。您可以通过glDrawElementsBaseVertex 的baseVertex 参数等技巧来选择为特定渲染操作检索哪些数据,或者仅通过为特定绘制命令选择要从中绘制的索引数据范围来选择。其他替代方案包括多绘制系列渲染函数。

如果由于某种原因您无法将所有数据放入同一个缓冲区中,那么您应该adopt the glVertexAttribFormat style of VAO usage 。这样,您可以使用 glVertexAttribFormat 调用设置顶点格式数据,并且可以根据需要使用 glBindVertexBuffers 更改缓冲区,而无需触及顶点格式本身。众所周知,这比更改 VAO 更快。

老实说,无论如何,您都应该采用 glVertexAttribFormat,因为它是一个更好的 API,并不像 glVertexAttribPointer 及其同类那样愚蠢。

关于c++ - 使用相同的着色器但不具有相同的纹理或颜色绘制多个 VAO 的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59595805/

相关文章:

c++ - 两个序列与 STL 的匹配数

c++ - 仅在发布版本中删除功能

c++ - CMake 找不到 QXmlSimpleReader

opengl - 如何使用 GLSL 正确解压缩 V210 视频帧?

c++ - 返回指向本地 char 变量的字符串对象是否安全

c++ - 类型名称后的括号是否与 new 不同?

c++ - 在 3d View 中动态渲染 2d 板

c++ - openGL中的随机点生成

opengl - 将对象从一个坐标系旋转到另一个坐标系

c++ - GLFW三角形不会变色