OpenGL VAO VBO 着色器混淆

Posted

技术标签:

【中文标题】OpenGL VAO VBO 着色器混淆【英文标题】:OpenGL VAO VBO shaders confusion 【发布时间】:2015-01-13 07:21:29 【问题描述】:

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

【问题讨论】:

如果这个解决方案是最优的 - 没有人知道。您必须对其进行概要分析。 afaik 减少对绑定 vaos 和程序的调用量是最好的,不过我会对更多专家意见感兴趣 谢谢,那我就试试。在实施之前,我只是想知道我对 VBO/VAO 的总体思路是否正确。 “一个 VBO 连续存储所有网格”...根据数据更改的频率将数据分组到缓冲区中。如果某些数据每帧都发生变化,那么它可能不应该与静态数据在同一个缓冲区中。 【参考方案1】:

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

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

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

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

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

【讨论】:

以上是关于OpenGL VAO VBO 着色器混淆的主要内容,如果未能解决你的问题,请参考以下文章

顶点着色器 VAO 是不是需要 VBO?

OpenGL - 如何理解 VAO 与 VBO 之间的关系

没有 VAO 的每个着色器属性的 VBO 或不同的方法?

OpenGL 大项目、VAO-s 等

在 GLSL 着色器中访问 VBO/VAO 数据

OpenGL入门之着色器Shader