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

Xem*_*uth 3 c++ opengl

我想知道如果我想使用相同的着色器绘制超过 6000 个不同的 VAO,最好的做法是什么。

目前我绑定了我的着色器,然后给它所有需要的信息(统一),然后循环遍历每个 VAO 来绑定和绘制它们。

这段代码使我的电脑下降到 ~ 200 fps 而不是 3000 或 4000。根据https://learnopengl.com/Advanced-OpenGL/Instancing,使用 glDrawElementsInstanced 可以让我处理大量相同的 VAO 但因为我有 ~ 6000个不同的VAO 好像用不上。

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

Nic*_*las 6

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

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

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

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

如果由于某种原因不能将所有数据放在同一个缓冲区中,那么您应该采用glVertexAttribFormatVAO 用法的风格。这样,您glVertexAttribFormat可以通过调用设置顶点格式数据,并且可以根据需要更改缓冲区,glBindVertexBuffers而无需接触顶点格式本身。众所周知,这比更改 VAO 更快。

老实说,glVertexAttribFormat无论如何你都应该采用,因为它是一个更好的 API,而不是愚蠢glVertexAttribPointer的同类。