From the OpenGL ES spec section 2.10.4 (Shader Variables: Varying Variables):
The number of interpolators available for processing varying variables is given by the implementation-dependent constant
MAX_VARYING_VECTORS
.This value represents the number of four-element floating-point vectors that can be interpolated; varying variables declared as matrices or arrays will consume multiple interpolators.
When a program is linked, any varying variable written by a vertex shader, or read by a fragment shader, will count against this limit.
A program whose shaders access more than
MAX_VARYING_VECTORS
worth of varying variables may fail to link
In Chrome on my machine, gl.getParameter(gl.MAX_VARYING_VECTORS)
returns 15
, which means I can use 15 vec4
varyings in a shader.
I've verified this with a few tests. 15 vec4
varyings work OK, but when attempting to use 16, the program fails to link and gl.getProgramInfoLog()
returns "Varyings over maximum register limit"
.
But how many varyings of type vec3
, vec2
or float
can be used?
The OpenGL ES spec seems to hint at this, without being explicit:
any varying variable ... will count against this limit.
A program whose shaders access more than
MAX_VARYING_VECTORS
worth of varying variables may fail to link
I'm making two guesses:
- The maximum number of varying
float
s is given by:
MAX_VARYING_VECTORS * 4
(4float
s pervec4
vector) - If (for example)
MAX_VARYING_VECTORS
is8
, then each of the following can safely be used without causing any linking errors:- 8
vec4
varyings - 10
vec3
varyings - 16
vec2
varyings - 32
float
varyings - 3
vec4
, 3vec3
, 3vec2
and 5float
varyings - 1
vec4
varying array of length8
- 1
vec3
varying array of length10
- 1
vec2
varying array of length16
- 1
float
varying array of length32
- Any other combination of
vec4
/vec3
/vec2
/float
variables or arrays, which uses a maximum of 32float
s
- 8
So with my MAX_VARYING_VECTORS
value of 15
, I guess I can use a maximum of 60 float
s.
My tests seem to confirm this.
For example, 30 vec2
varyings work OK on my machine, but 31 causes a "Varyings over maximum register limit"
linking error.
So my questions are:
- Are my two guesses correct?
- If
MAX_VARYING_VECTORS
is8
, then is it safe to use 16vec2
varyings? Is this guaranteed to always work?
From the WebGL spec
So yes, if you read the algorithm if
MAX_VARYING_VECTORS
is 8 you can use 16vec2
s. You can not however use 10vec3
s. You could only use 8vec3
sThere are also array restrictions. For example you couldn't have an array of
float
s larger than 8 nor an array ofvec2
larger than 8 ifMAX_VARYING_VECTORS
is 8.