I want to specify textures to be used when I render an array of sprites. So I put a texture index in their vertex data, and pass it as a flat value from my vertex shader to my fragment shader, but can't use it to index an array of samplers as expected because compiler sees it as "non-constant". Instead I have to resort to the disgusting code below. Can anyone explain what is going on here?
const int numTextures = 2;
uniform sampler2D textures[numTextures];
in vec2 uv;
flat in int tex;
out vec4 colour;
void main(void)
{
// this caused the compiler error
/// "sampler arrays indexed with non-constant expressions"
// colour = texture( textures[ tex ], uv );
// hence this (ugh) ...
switch ( tex )
{
case 0:
colour = texture( textures[0], uv );
break;
case 1:
colour = texture( textures[1], uv );
break;
default:
colour = vec4( 0.3f, 0.3f, 0.3f, 1.0f );
break;
};
}
Fragment shader reads a value from the same variable, automatically interpolated to that fragment. No need to declare these in the Java program.
The output of a fragment shader is a depth value, a possible stencil value (unmodified by the fragment shader), and zero or more color values to be potentially written to the buffers in the current framebuffers. Fragment shaders take a single fragment as input and produce a single fragment as output.
A uniform is a global Shader variable declared with the "uniform" storage qualifier. These act as parameters that the user of a shader program can pass to that program. Their values are stored in a program object.
Fragment shaders Fragment (or texture) shaders define RGBA (red, green, blue, alpha) colors for each pixel being processed — a single fragment shader is called once per pixel. The purpose of the fragment shader is to set up the gl_FragColor variable. gl_FragColor is a built-in GLSL variable like gl_Position .
[...] but can't use it to index an array of samplers as expected because compiler sees it as "non-constant" [...]
In GLSL up to version 3.30 respectively GLSL ES up to version 3.00, the index of an array of texture samplers has to be a constant expression:
GLSL 3.30 Specification - 4.1.7 Samplers (page 21)
GLSL ES 3.00 Specification - 4.1.7.1 Samplers (page 29):
Samplers aggregated into arrays within a shader (using square brackets [ ]) can only be indexed with integral constant expressions [...]
In later version, the index to an array of samplers has to be "dynamically uniform". This means the index has to be the "same" for all fragments (e.g. a constant or a uniform variable).
GLSL 4.60 Specification - 4.1.11. Opaque Types (page 31)
GLSL ES 3.20 Specification - 4.1.11. Opaque Types (page 32)
When aggregated into arrays within a shader, opaque types can only be indexed with a dynamically uniform integral expression. [...]
[...] Sampler types (e.g. sampler2D) are opaque types [...]
GLSL 4.60 Specification - 3.8.2. Dynamically Uniform Expressions (page 20)
GLSL ES 3.20 Specification - 3.9.3. Dynamically Uniform Expressions (page 22)
A fragment-shader expression is dynamically uniform if all fragments evaluating it get the same resulting value.
A flat
fragment shader input is invariant for a single primitive, but not for the entire mesh, not for all the primitives which are processed by a single "draw call" respectively it is not the same for an invocation group. A (flat
) fragment shader input is not Dynamically uniform.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With