When instancing should I use multiple buffers if I need to load multiple vertex attributes

So I need to pass matrices and color data for instances and I was wondering if the best way to do this would be to load the matrix data and the color data into two separate buffers, as opposed to I guess interleaving data?

layout(location = 10) in mat4 mats;
layout(location = 14) in vec3 colors;

If so would specifying the instanced data format with two buffers look like this (with the two buffers having index 1 and 2)?

glVertexArrayAttribFormat(vao, 10, 4, GL_REAL, GL_FALSE, 0);             
glVertexArrayAttribFormat(vao, 11, 4, GL_REAL, GL_FALSE, 1*sizeof(vec4));
glVertexArrayAttribFormat(vao, 12, 4, GL_REAL, GL_FALSE, 2*sizeof(vec4));
glVertexArrayAttribFormat(vao, 13, 4, GL_REAL, GL_FALSE, 3*sizeof(vec4));
glVertexArrayAttribFormat(vao, 14, 3, GL_REAL, GL_FALSE, 0);
glVertexArrayAttribBinding(vao, 10, 1);      
glVertexArrayAttribBinding(vao, 11, 1);
glVertexArrayAttribBinding(vao, 12, 1);
glVertexArrayAttribBinding(vao, 13, 1);
glVertexArrayAttribBinding(vao, 14, 2);
//set glEnableVertexArrayAttrib for all

glVertexArrayBindingDivisor(vao, 1, 1);
glVertexArrayBindingDivisor(vao, 2, 1);


You also need calls to glVertexArrayVertexBuffer.

In terms of the GPU reading data, interleaving may have a slight performance advantage, particularly if you’re using an element (index) array.

OTOH, the fact that one of the elements is vec3 might favour separate arrays, as the larger array will be aligned to a multiple of vec4 with only the smaller array unaligned.

Also, the choice of interleaving versus separate arrays is influenced by how data will be written by the client. Updating a contiguous region is more efficient than updating specific elements in an interleaved array. So if different attributes are updated at different times, that would favour separate arrays.

1 Like