GLSL (ES 3.0): reference a uniform using another uniform's location and an offset

1.1k views Asked by At

In GLSL for OpenGL ES 3.0, if I have the following code:

uniform mat4 matrix1;
uniform mat4 matrix2;
uniform mat4 matrix3;

is it possible to reference matrix2 or matrix3, using only the location of matrix1 plus an offset? This has to be dynamic i.e. the index will be an attribute.

EDIT: I mean using matrix2 and matrix3 in the shader itself with only the location of matrix1 and an offset, not getting the location of them on the CPU.

EDIT 2: In case it helps I'll add more context. I'm trying to solve this GPU-skinning issue, and it's come to my attention that Adreno doesn't support indexing uniform arrays with anything other than constant integers in their vertex shaders (contrary to what the OpenGL ES 3.0 GLSL spec mandates). I'm thinking of storing the array of matrices individually one after the other now, however still need to be able to access them with an index provided as an attribute.

2

There are 2 answers

4
Andon M. Coleman On BEST ANSWER

I mean using matrix2 and matrix3 in the shader itself with only the location of matrix1 and an offset, not getting the location of them on the CPU.

No, this cannot be done.

Uniform locations are only assigned after linking shaders, and there is no requirement that they be assigned sequentially in the same order that they appear in the shader source. While this is the only behavior I have ever witnessed, it is not a requirement.


Adreno doesn't support indexing uniform arrays with anything other than constant integers in their vertex shaders (contrary to what the OpenGL ES 3.0 GLSL spec mandates).

As for indexing uniforms by anything other than constant integers, this behavior depends on the shader stage, which you are already aware. In vertex shaders you can index them using any integer expression you want, in fragment shaders implementations are only required to support constant-index (though many support more than this). A constant integer and constant-index expression are not the same thing, constant-index is a little bit less restrictive (and can include loop control variables in some cases).

That said, dynamically indexing elements within a matrix is not guaranteed to be supported... (e.g. vec4 column = matrix1 [some_variable];). Some implementations will support this, others will not.

Are you correctly prefixing your GLSL shader with #version 300 es? The behavior described above applies to GLSL ES 1.0, which is what you will default to if you do not tell the compiler otherwise. A compliant implementation will give you a different set of restrictions if you do not use #version 300 es.

1
Mike D On

Uniform variables MUST be read from OpenGL using glGetUniformLocation.

They are not "generated" until compile time (and can change due to shader optimisation)