glUniform与单一绘制调用性能

时间:2014-05-18 18:52:18

标签: opengl opengl-es

假设我有许多我想渲染的网格物体。我有两个选择:

  1. 将每个网格的变换和颜色烘焙到VBO中并使用单个绘制调用进行渲染。
  2. 使用glUniform进行变换和颜色,并使用许多绘制调用(但仍然只有一个VBO)
  3. 假设场景之间场景变化很小,哪种方法往往更好?

2 个答案:

答案 0 :(得分:2)

不止这两种选择。至少还有一个想到:

  1. ...
  2. ....
  3. 使用变换和颜色的属性并使用许多绘制调用。
  4. 选择3与选择2类似,但设置属性(使用glVertexAttrib4f等调用)大多比设置制服更快。制服的效率高度依赖于平台。但它们通常不打算经常修改。出于某种原因,它们被称为统一。 :)

    话虽这么说,选择1可能是最适合您的变换/颜色很少变化的用例。如果您还没有这样做,可以尝试保留在单独的VBO(使用GL_DYNAMIC_DRAW)中修改的属性,以及在自己的VBO中保持不变的属性(使用GL_STATIC_DRAW )。然后使用glBufferSubData对动态缓冲区进行必要的更新。

    现实情况是,没有简单的规则来预测最佳表现。它取决于数据的大小和绘制调用,数据更改的频率和大小,以及您运行的平台上的非常多。如果您想确信自己使用的是最有效的解决方案,则需要实施所有这些解决方案,并开始进行基准测试。

答案 1 :(得分:1)

通常,选项1(最小化绘制调用次数)是最好的建议。有几点需要注意:

我在至少一个移动设备上使用非常大的VBO时假设性能下降(假设与opengl-es标签相关)。解释(来自供应商)涉及超过一定大小的内部缓冲区。

如果把所有用制服传递的信息放到顶点属性中会显着增加顶点缓冲区的大小,那么你需要支付的价格(可能是昂贵的内存读取)来读取冗余信息(因为它没有每个顶点确实不同)可能会减少使用较少绘制调用的节省。

一如既往最好(但很烦人)的建议是测试(我知道这对于移动设备来说特别难以开发,因为有许多潜在的实现可以运行你的代码)。尽量保持您的管道/工具链足够灵活,以便您可以轻松地尝试并比较不同的选项。