OpenGL VAO VBO 着色器混淆

OpenGL VAO VBO shaders confusion

本文关键字:VAO VBO OpenGL      更新时间:2023-10-16

我正在编写一个渲染器,并且正在选择处理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 中拥有多种交错格式。

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

但是,与切换着色器相比,切换 VBO 和 VAO 通常非常便宜。这意味着在您的情况下,瓶颈可能是切换着色器。

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

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

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