Uniform equivalent of instanced arrays in 3.3 core?

Hi.

Instanced arrays can be used to provide per-instance data to a shader via something that looks like a vertex attribute (according to Vertex Specification - OpenGL Wiki). Is there a way to do the same thing but providing data to uniforms?

What I mean is, say I have a program such as:


uniform mat4 m_model;
uniform mat4 m_view;
uniform mat4 m_projection;
in vec4 v_position;

void main()
{
  gl_Position = m_projection * m_view * m_model * v_position;
}

… and I want to allocate a buffer object of matrices and, for each instance i, supply the ith matrix in the buffer object to the m_model uniform. Is this possible?

I’m trying to modify an existing engine to add instanced drawing and would rather not have to modify shaders to accomodate it (so don’t want to be passing in GLSL arrays as uniforms and indexing into them, or by adding new vertex attributes).

No, there’s no way to make instancing work transparently like that.

Also, that shader is really wasting a lot of time, multiplying the vector by 3 matrices. So changing it will improve things in more than one way.

OK. What’s the closest analogy? Would that be via interface blocks or something similar?

Also, that shader is really wasting a lot of time, multiplying the vector by 3 matrices. So changing it will improve things in more than one way.

It was just an example to demonstrate that m_model could vary per-instance.

You could create an RGBA32F 1D texture (or texture buffer) of size num_transforms *4, and pack the transform vectors into it. If you don’t have shears, you can use a 3x4 matrix since the last column will be (0,0,0,1). Then access it via:

uniform sampler1D models; // or samplerBuffer models; for a TBO

mat4 model = mat4(texelFetch(models, 0, gl_InstanceID*4),  // Note no 2nd '0' parm if using TBOs...
                  texelFetch(models, 0, gl_InstanceID*4+1),
                  texelFetch(models, 0, gl_InstanceID*4+2),
                  texelFetch(models, 0, gl_InstanceID*4+3));

Using a TBO would allow you to write to a GL buffer object, which is similar to what you’d do for a UBO update.