3

我正在编写一个渲染器,并且正在选择一种处理 vao/vbo/shader 管理的最终方法。在网上,我发现关于实际推荐的信息高度矛盾。目前思路如下:

-一个VBO连续存储所有网格。

- 每个“着色器映射”创建一个 VAO 以将特定的指针映射存储到 VBO。(“着色器映射”,在具有相同输入的不同着色器中保持一致)

然后通过“着色器映射”对实体进行排序,并使用主 VBO 中的偏移量进行渲染,从而最大限度地减少着色器和 VAO 开关。就像是:

for(shaders by mapping)
    bindVAO(); //set pointers
    for(shader)
        for(entity using shader)
            entity.setUniforms();
            drawArrays(entity.offset, entity.size);

因为这将包括大量的重构,所以我想问一下这个解决方案是否是最优的。我还想知道是否有可能在单个 VBO 中具有多种交错格式。

4

1 回答 1

4

使用不同的着色器重用 VAO 是一种很好的做法。

然而,与切换着色器相比,切换VBO 和 VAO通常非常便宜。这意味着在您的情况下,瓶颈可能无论如何都会切换着色器。

出于同样的原因,将所有网格放在同一个 VBO 中可能有点过分(但只要您不需要更新它就不会受到伤害)。

此外,根据您正在渲染的内容,按深度/混合状态或按深度(通常是从前到后)对绘制调用进行排序可能比按着色器对它们进行排序更好的解决方案。但这需要仔细衡量。(有关排序的更多信息在这里)。

编辑:要回答您的第二个问题,可以将不同类型的顶点放在同一个 VBO 中,尽管我从未尝试过。这很棘手,因为您需要注意顶点对齐。例如,在调用glDrawArrays(mode, first, count)时,您需要计算firstfirst * sizeof(YourCurrentVertexType)等于您将数据放入 VBO 的偏移量。无论如何,这样做可能不是一个好主意。有些司机可能不喜欢它,就像我上面所说的那样,它可能不会产生明显的变化。

于 2015-01-13T20:40:05.527 回答