I have got the following error with Three.js when I try to use an array with a non constant index:
'[]' : Index expression must be constant
With the following fragment shader:
precision mediump float;
varying vec2 vUV;
uniform vec2 screenResolution;
vec4 colors[2];
void main(void) {
vec2 uv = gl_FragCoord.xy / screenResolution.xy;
colors[0] = vec4(0.0);
colors[1] = vec4(1.0);
int index = int(floor(uv.y * 1.9));
gl_FragColor = colors[index];
}
This error does not occur with Babylon.js.
I know it was not possible to use non constant index for arrays in earlier versions of GLSL ES
but it should be possible now, right?
How can I know the GLSL versions used by Three.js and Babylon.js?
For the use of GLSL ES 3.0 in Three.js you've to create a WebGL 2.0 context.
Once you have checked that WebGL 2 is supported by the device, create a WebGLRenderer
with a given webgl2
context:
var canvas = document.createElement( 'canvas' );
var context = canvas.getContext( 'webgl2' );
var renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );
See the Three.js documentation: How to use WebGL2.
The version of the shader of the question is GLSL ES 1.0. The index of an array has to be a constant-expressions.
See OpenGL ES Shading Language 1.00 Specification - 13 Acknowledgements; page 109:
5 Indexing of Arrays, Vectors and Matrices
Definition: constant-index-expressions are a superset of constant-expressions. Constant-index-expressions can include loop indices as defined in Appendix A section 4.
The following are constant-index-expressions:
- Constant expressions
- Loop indices as defined in section 4
- Expressions composed of both of the above
When used as an index, a constant-index-expression must have integral type.
Uniforms (excluding samplers)
In the vertex shader, support for all forms of array indexing is mandated. In the fragment shader, support for indexing is only mandated for constant-index-expressions.#
This means the index of an array in a fragment shader has to be a constant or a loop index in any case.
This changes in GLSL ES 3.0. See OpenGL ES Shading Language 3.00 - 12.30 Dynamic Indexing; page 142:
For GLSL ES 1.00, support of dynamic indexing of arrays, vectors and matrices was not mandated because it was not directly supported by some implementations. Software solutions (via program transforms) exist for a subset of cases but lead to poor performance. Should support for dynamic indexing be mandated for GLSL ES 3.00?
RESOLUTION: Mandate support for dynamic indexing of arrays except for sampler arrays, fragment output arrays and uniform block arrays.
GLSL ES 3.0 shader have to be qualified by the version quailfier in the first line of the shade code:
#version 300 es
Further there are some syntactically differences like the qualifier for the shader inputs and outputs, which are in
respectively out
instead of attribute
or varying
.
For the use of GLSL ES 3.0 you've to create a WebGL 2.0 context.
See the Three.js documentation: How to use WebGL2.