【问题标题】:Rendering multiple objects with OpenGL shaders使用 OpenGL 着色器渲染多个对象
【发布时间】:2015-12-02 19:43:51
【问题描述】:

在带有着色器的 OpenGL 中,我想渲染两个已加载为两个网格的对象。每个对象由一组顶点位置、一组顶点颜色和一组三角形顶点索引表示。

我可以想到三种方法来绘制这两个对象。最佳做法是什么?

1) 我将两个对象的顶点位置连接成一个长的顶点数组,顶点颜色和顶点索引也类似。然后我创建一个顶点位置缓冲区、一个顶点颜色缓冲区和一个索引缓冲区。渲染时,我会调用glBindBuffer(...)glDrawElements(...)

2) 我将两个对象的顶点位置连接成一个长的顶点数组,顶点颜色也类似。然后我创建一个顶点位置缓冲区和一个顶点颜色缓冲区。渲染时,我对glBindBuffer(...)glDrawElements(...) 进行两次调用,每个对象调用一次。

3) 我创建了两个顶点位置缓冲区、两个顶点颜色缓冲区和两个索引缓冲区。渲染时,我对glBindBuffer(...)glDrawElements(...) 进行两次调用,每个对象调用一次。

谢谢!

【问题讨论】:

  • 您真的只渲染两个对象吗?还是你只是用那个数字来简化解释?
  • 是的,它是两个 CAD 对象。两者都是我得到的网格。我想在同一个视口中渲染这两个对象。

标签: opengl graphics glsl


【解决方案1】:

OpenGL 优化的一般规则是尽量减少状态变化的次数。绑定缓冲区是一种状态变化。

所以,在所有其他条件相同的情况下,#1 可能是最快的。

但是,它并不总是特别有用。通常,不同的对象相对于彼此具有不同的变换。所以通常,你需要在渲染对象之间改变一些状态,所以#1不是一个选项。

即便如此,您也无需求助于选项 2。您可以使用与选项 1 相同的缓冲区设置,但只需发出两个绘图调用。每次绘制都会使用部分数组进行渲染。

同样重要的是,对于顶点数组,问题不在于绑定缓冲区(尽管它们并不便宜)。它正在改变您使用的vertex format,即属性的相对排列。如果您使用separate attribute format API,您可以轻松更改缓冲区绑定,而无需触及格式。通常,整个程序中可能只有 5-6 个顶点格式。

另一个问题是您还没有完全探索这里的各种可能性。例如,在所有情况下,位置、颜色、法线和其他属性都位于单独的缓冲区中。好吧...为什么它们在单独的缓冲区中? Interleaving your vertex attributes 通常会提供更好的性能。

真的,最佳性能的答案是“以上都不是”。

【讨论】:

  • 更改顶点格式非常便宜,至少在我熟悉的硬件架构上是这样。这只是一些状态设置命令。转换状态有一点 CPU 开销,但可以高度优化,尤其是在使用 VAO 的情况下。这肯定比绑定缓冲区的开销要少得多。
  • @RetoKoradi:嗯,NVIDIA and AMD seem to have data (~32 minutes) 说顶点格式更改比顶点绑定(又名:缓冲区绑定)更昂贵。所以我会按照他们说的去做。此外,在基于 GCN 的 AMD 硬件上,更改顶点格式需要修改顶点着色器,因为 GCN 硬件实际上没有顶点拉取硬件。
【解决方案2】:

仅渲染 2 个对象,这些选项都不会让您接近任何类型的性能瓶颈。如果您的目标帧速率与显示刷新率(通常约为 60 fps)相匹配,则您只需每秒渲染 120 个对象。

假设您需要对每个对象进行大量状态设置调用,这将使您处于每秒 1000 次状态设置调用的范围内。虽然性能特征当然是高度特定于平台/供应商的,但一个中等体面的驱动程序将能够每秒处理几百万个简单的状态设置调用(如绑定缓冲区、设置顶点属性等)。所以你至少比我开始担心吞吐量的水平低 3 或 4 个数量级。

现在,如果您有数千个对象,事情就会开始变得有些不同。我肯定会推荐两件事:

  • 使用交错属性。这意味着您按顺序存储一个顶点的位置和颜色,然后是下一个顶点的属性。假设您有 3 个分量 (xk, yk, pk) 用于位置,4 个分量 (rk, gk, bk, ak) 用于顶点颜色k,缓冲区的内存布局为:

    x0 y0 z0 r0 g0 b0 a0 x1 y1 z1 r1 g1 b1 a1 x2 y2 z2 r2 g2 b2 a2 ...
    
  • 使用 VAO(顶点数组对象)设置状态。这将允许您通过单个 glBindVertexArray() 调用设置对象的整个顶点属性状态。

是为每个对象使用单独的 VBO 更好,还是在对象之间共享更大的 VBO,通常很难说。拥有大量小型 VBO 肯定会损害性能,如果您可以相当容易地安排,共享它们可能是有益的。但我也可以想象拥有非常大的 VBO 可能会产生不利影响的场景。因此,如果您想在拥有大量对象的情况下获得最大性能,您可能必须尝试不同的选项。不幸的是,结果很可能取决于平台。

【讨论】:

    猜你喜欢
    • 2012-02-27
    • 2018-02-17
    • 1970-01-01
    • 2015-01-19
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    相关资源
    最近更新 更多