7

I run

glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxVertUniformsVect);

and get 1024.

Than in GLSL I do

uniform mediump vec4[1020] instance_mat

and that was ok. But with vec3/vec2/float it fails:

uniform mediump float[1030] instance_mat;          // fails
//uniform mediump vec2[1030] instance_mat;         // and this
//uniform mediump vec3[1030] instance_mat;         // and this

With following error:

cannot locate suitable resource to bind variable "instance_mat". Possibly large array.

The question is: Does GL_MAX_VERTEX_UNIFORM_VECTORS return the number of all kind of arrays, no matter what size they are? I mean, no matter does this float/vec2/vec3/vec4 - all counts as one VERTEX_UNIFORM_VECTOR?


Vertex shader code, as is:

#version 120
uniform mediump float[1200] instance_mat;        //mat4x3
attribute mediump float instaceIdF;             // in range 0..1000 Will be converted to int

attribute mediump vec3 vertex_;
attribute lowp vec4 color;
uniform mediump mat4 matrix;
varying lowp vec4 v_color;

void main(void)
{
    v_color = color;


        int instaceId = int(instaceIdF) * 12;
        mediump mat4 offsetMat = mat4(
                                    vec4(instance_mat[instaceId],   instance_mat[instaceId+1], instance_mat[instaceId+2], 0),
                                    vec4(instance_mat[instaceId+3], instance_mat[instaceId+4], instance_mat[instaceId+5], 0),
                                    vec4(instance_mat[instaceId+6], instance_mat[instaceId+7], instance_mat[instaceId+8], 0),
                                    vec4(instance_mat[instaceId+9], instance_mat[instaceId+10], instance_mat[instaceId+11], 1)
                                 );

        /*mediump mat4 offsetMat = mat4(
                                    vec4(instance_mat[instaceId].xyz, 0),
                                    vec4(instance_mat[instaceId+1].xyz, 0),
                                    vec4(instance_mat[instaceId+2].xyz, 0),
                                    vec4(instance_mat[instaceId+3].xyz, 1)
                                 );*/
        gl_Position = matrix * offsetMat * vec4(vertex_, 1.0);
        //gl_Position = matrix * vec4(vertex, 1.0);


}
7
  • 1
    GL_MAX_VERTEX_UNIFORM_COMPONENTS returns aprox 16000. And I have nVidia, not ATI. So I think its true. :) Commented Dec 24, 2013 at 15:42
  • Can you show your entire shader? I think there is some confusion here, and the information in the accepted answer is incorrect. GL_MAX_VERTEX_UNIFORM_VECTORS refers to the sum total maximum size of all active uniforms in the vertex shader stage. If you have any other uniforms, the maximum length of an array you can support will be smaller. Commented Dec 24, 2013 at 17:45
  • Thank you for updating your question. Now, your issue is actually the version of GLSL you are using. There is no such thing as GL_MAX_VERTEX_UNIFORM_VECTORS in GLSL 1.20. All you have is GL_MAX_VERTEX_UNIFORM_COMPONENTS. In GLSL, this constant can be referenced by: gl_MaxVertexUniformComponents and it has a minimum implementation limit of 512. You are consuming 1200 + 16 uniform components in your vertex shader (1200 for the array and 16 for the mat4). Try declaring something along the lines of: uniform mediump float instance_mat [gl_MaxVertexUniformComponents - 16]; Commented Dec 24, 2013 at 19:41
  • You also have your array subscript around the wrong part of the declaration if you are trying to create a uniform array. Commented Dec 24, 2013 at 19:45
  • "uniform mediump float instance_mat [gl_MaxVertexUniformComponents - 16];" - Same error. Commented Dec 24, 2013 at 19:48

2 Answers 2

6

According to http://www.opengl.org/wiki/Uniform_%28GLSL%29 (Implementation limits):

Implementation note: OpenGL implementations are allowed to reject shaders for implementation-dependent reasons. So you can have fewer active uniform components by your reckoning and still fail to link due to uniform limits. This is usually on hardware that is innately vector hardware. Pre-GeForce 8xxx hardware, and all ATi hardware does this. In this case, you should assume that each separate uniform takes up 4 components, much like it would in D3D. That means a "uniform float" is 4 components, a mat2x4 is 16 components (each row is 4 components), but a mat4x2 is 8 components.

Which is my case, also. But it not has to be always like that. Of course, for compatible reasons it is always better to count each float/vec2/vec3 uniform value, as max size value (vec4)

Sign up to request clarification or add additional context in comments.

1 Comment

2

The OpenGL Docs says it all.

GL_MAX_VERTEX_UNIFORM_VECTORS

data returns one value, the maximum number of 4-vectors that may be held in uniform variable storage for the vertex shader. The value of GL_MAX_VERTEX_UNIFORM_VECTORS is equal to the value of GL_MAX_VERTEX_UNIFORM_COMPONENTS and must be at least 256.

Thereby that means that no matter the type, you can only hold an array of max GL_MAX_VERTEX_UNIFORM_VECTORS in length. Even though that vec4 == 4 floats

The maximum value of course vary by the different hardward implementations and how old/new the individual graphics card may be of OpenGL.

10 Comments

That is the GLSL ES specification you quoted. It has half the requirements of desktop GLSL on this matter. const int gl_MaxVertexUniformVectors = 256; in desktop GLSL.
@AndonM.Coleman Thanks for the comment, guess I posted a little too fast, but it's fixed now.
Also, I would not trust the online manual pages, because that information is clearly wrong. If you read the OpenGL 4.4 specification, on pg. 117 (7.6 Uniform Variables) it contradicts the statement that the value of that implementation-defined constant is identical to GL_MAX_UNIFORM_VECTOR_COMPONENTS. The GLSL specification agrees with the OpenGL 4.4 specification, so I have serious doubts about the accuracy of anything on that manual page, particularly since the value listed 1 line above is 1024, which is not 256.
@Tower120: Yes, but the information in this answer is incorrect. It is not the fault of Vallentin, just whoever misinterpreted this sentence in the OpenGL specification to create that page: "The implementation-dependent constants MAX_VERTEX_UNIFORM_VECTORS and MAX_FRAGMENT_UNIFORM_VECTORS have values respectively equal to the values of MAX_VERTEX_UNIFORM_COMPONENTS and MAX_FRAGMENT_UNIFORM_COMPONENTS divided by four." The page should actually say that GL_MAX_VERTEX_UNIFORM_VECTORS is equal to the value of GL_MAX_VERTEX_UNIFORM_COMPONENTS divided by four.
@tower120: I realize you are talking about vec3. But when OpenGL talks about a limit that includes the word VECTOR it means vec4. This applies to vertex attributes, uniforms, etc. For instance, a mat4 variable has the same storage requirements as 4 vectors (or 16 components total). Thus, although Valentin's answer implies you can have an array of up to 1024 mat4 uniforms that is not correct - you are limited to 256 mat4s because a mat4 = 4 x vec4. The real limit you need to observe is MAX_VERTEX_UNIFORM_COMPONENTS.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.