glVertexAttribPointer() 的索引应该是连续的吗?

Should the indices of glVertexAttribPointer() be contiguous?

glVertexAttribPointer()的第一个参数是一个索引,表示顶点属性所在的位置,Opengl 至少提供 16 个插槽。

我希望所有 16 个都代表不同的顶点属性(position=0、uvs=1、colors=3、weights=8 等)并且这些属性在每个顶点类型中都是恒定的,即使顶点没有'不要使用该属性。

我的问题是,如果给定顶点的索引不连续,这有什么关系吗?例如,这会不会效率低下:

enum Attrib : GLuint {
    aPos        = 0,
    aUv1        = 1,
    aUv2        = 2,
    aColor1     = 3,
    aColor2     = 4, 
    aNormal     = 5,
    aTangent    = 6,
    aBitangent  = 7,
    aBoneIndex  = 8,
    aBoneWeight = 9,
    aAttrib1    = 10,
    aAttrib2    = 11,
    aAttrib3    = 12,
    aAttrib4    = 13, 
    aAttrib5    = 14,
    aAttrib6    = 15, 
    a__count    = 16
};

glVertexAttribPointer(aPos, ...);
glVertexAttribPointer(aUv1, ...);
glVertexAttribPointer(aAttrib1, ...);

对于顶点数组使用任意属性索引没有已知的性能损失。为了对此增加一些理由,最近的 API(如 Vulkan 和 D3D12)有机会强制属性索引的连续性。作为更底层的 API,如果通过这样的限制可以获得一些性能,他们就会强加它。

他们没有。

相比之下,Vulkan 有效地使顶点格式成为程序管道状态的一部分,从而在程序和顶点格式之间强制执行直接关联。因此,与 OpenGL 相比,Vulkan 并不是不愿意限制事物。