2

我正在完成一个波前对象解析器,我想用它来构造通用网格对象。我的引擎使用 OpenGL 4 和着色器来绘制引擎中的所有内容。

我的问题是关于如何确保渲染网格的最佳渲染效率。

波前.obj 文件通常指定了许多对象子组。

可能会为子组分配特定的材料(例如闪亮的红色)。

因此,网格可能是相当复杂的子组集合,每个子组都分配有自己的材质。

我的问题是——

问:我是否需要分别绘制每个子组,例如为每个子组调用 glDrawElements ?(因此,如果我有 4 个单独的子组,我将不得不进行 4 次 glDrawElements 调用,从而通过 4 次统一更改(对于材质/纹理)调用着色器 4 次)

glDrawElements( GL_TRIANGLES, nNumIndicesInGroup, GL_UNSIGNED_INT, ((char*)NULL)+ first-vertex-offset );

如果这是正确的,那么我将不得不计算:

每个子组中的索引(意味着每个子组有一个单独的索引数组和 VAO) 子组开始的顶点偏移量

这似乎非常低效,我是在吠叫错误的树吗?

此外,来自Wavefront obj wiki 页面

Smooth shading across polygons is enabled by smoothing groups.
 s 1
 ...
  # Smooth shading can be disabled as well.
  s off
  ...

谁能建议平滑着色值表示什么?例如 s1、s2、s4 等。

4

1 回答 1

8

是的,您应该将每个子组与其他子组分开绘制。这是必需的,直到子组之间的状态不同。

但是你迈的太远了。

为避免多次绘制调用,您可以引入指示用于访问统一数组值(材质数组、纹理数组)的索引的顶点属性。这样一来,您只需要一次绘制调用,但您将承担一个附加属性及其相关管理的成本。

我会避免上述方法。如果一个子组有纹理而另一个没有呢?你如何区分是否纹理?引入其他属性?看起来很混乱。

第一点是缓冲区对象管理非常灵活。实际上,您可以拥有一个元素缓冲区对象和一个顶点缓冲区对象:使用偏移和交错可以满足每个级别的复杂性。然后,在现代硬件上,使用顶点数组对象可以最小化不同缓冲区绑定的成本。

第二点是您的软件可以将具有相同统一状态的不同子组分组,将多个绘图调用合并为一个。请记住,您可以使用Multi draw entry points 变体,并且还有可以帮助您的图元重启(在剥离图元的情况下)。

其他考虑没有用,因为无论如何你都必须画画,不管它是否复杂。随后,当您有正确的渲染时,您可以分析应用程序和渲染,切断热点。


平滑组是共享相同选项属性(法线、纹理坐标)的顶点的集合。这是元素索引顶点的情况。

要深入了解主题,请阅读通过谷歌搜索找到的规范之一。

于 2012-04-24T17:56:58.413 回答