我正在完成一个波前对象解析器,我想用它来构造通用网格对象。我的引擎使用OpenGL 4和着色器在我的引擎中绘制所有内容。
我的问题是有关如何确保渲染网格的最佳渲染效率。
wavefront .obj file通常指定了许多对象子组。
可以为一个小组分配特定的材料(例如,发亮的红色)。
因此,网格可能是相当复杂的子组集合,每个子组都分配有自己的材料。
我的问题是-
问:我是否需要分别绘制每个子组,例如调用每个子组的glDrawElements吗? (因此,如果我有4个单独的子组,则必须进行4次glDrawElements调用,从而通过4次统一更改(对于材质/纹理)调用着色器4次)
glDrawElements( GL_TRIANGLES, nNumIndicesInGroup, GL_UNSIGNED_INT, ((char*)NULL)+ first-vertex-offset );
如果这是正确的,那么我将必须计算:
每个子组中的索引(暗含每个子组的单独索引数组和VAO)
子组起点的顶点偏移
这似乎效率很低,我是不是在树上叫错了?
另外,从Wavefront obj wiki page:
Smooth shading across polygons is enabled by smoothing groups.
s 1
...
# Smooth shading can be disabled as well.
s off
...
谁能建议平滑阴影值表示什么?例如。 s1,s2,s4等
最佳答案
是的,您应该将每个子组与其他子组分开绘制。这是必需的,直到子组之间的状态不同为止。
但是您迈出了太长的一步。
为了避免多次绘制调用,您可以引入一个顶点属性,该属性指示用于访问统一数组值(材质数组,纹理数组)的索引。这样,您只需要一个绘制调用,但是您将需要一个附加属性及其相关管理的费用。
我会避免上述方法。如果一个子组有纹理而另一个子组没有纹理怎么办?您如何区分是否纹理?引入其他属性?似乎令人困惑。
第一点是缓冲区对象管理非常灵活。实际上,您可能只有一个元素缓冲区对象和一个顶点缓冲区对象:使用偏移量和交织可以满足各个级别的复杂性。然后,在现代硬件上,使用顶点数组对象可以使不同缓冲区绑定的成本降至最低。
第二点是您的软件可以将具有相同统一状态的不同子组分组,从而将多个绘制调用合并为一个。请记住,您可以使用“多绘制入口点”变体,并且还有可以帮助您的原始重启(在去除原始的情况下)。
其他考虑因素没有用,因为无论复杂与否,您都必须进行绘制。连续地,当您具有正确的渲染时,您可以分析应用程序和渲染,从而切断热点。
平滑组是一组共享相同选项属性(法线,纹理坐标)的顶点。元素索引顶点就是这种情况。
要深入研究主题,请阅读通过谷歌搜索找到的specification之一。