# Dynamically Uniform Expression

Core in version | 4.5 | |
---|---|---|

Core since version | 4.0 |

A **Dynamically Uniform Expression** is a GLSL expression in which all invocations of that shader within a particular rendering command will compute the same value. This concept only matters in GLSL 4.00 and above.

## Contents

## Before GLSL 4.00

If an expression is said to be dynamically uniform, and you're not using GLSL 4.00 or above, this should be read as "constant expression". Only 4.00-class hardware and greater is able to make this distinction.

## Definition

An expression in a GLSL shader is said to be dynamically uniform if, and *only* if, every shader invocation for the shader will compute the same value, in the same order. This means that the expression's value must depend only on compile-time constant data, uniforms, and expressions/functions derived from them. This includes any conditional branches that might change the value of a variable. Input variables cannot be involved in any way.

Compile-time constant expressions (literals and const-qualified global and local variables) are always dynamically uniform. uniform-qualified variables are dynamically uniform. Mathematical expressions based on these are dynamically uniform. Values sampled from images using constant or uniform expressions are dynamically uniform.

Most important of all, if you execute a loop over values, where the initializing expression, offset, and test condition all use dynamically uniform expressions, then the loop counter *itself* will be dynamically uniform.

While accessing textures will be dynamically uniform (if the texture coordinates are dynamically uniform), accessing image variables or Atomic Counters is not necessarily so. These are modifiable memory, so each invocation may not get the same value. If the image variable is read-only, then accessing it is dynamically uniform (if the image coordinates are dynamically uniform).

## Uses

There are places where GLSL requires the expression to be dynamically uniform. All of the following must use a dynamically uniform expression:

- The array index for arrays of opaque types.
- The index to buffer-backed interface blocks.
- In Compute Shaders, the expressions leading to the execution of a barrier() call. So if there is a loop or a conditional statement or somesuch, all of these conditions must be dynamically uniform expressions, so that every compute shader invocation encounters every barrier() statement in the same sequence and the same number of times.

## Examples

Here are some examples of expressions that are and are not dynamically uniform:

in vec3 fromPrevious; in uvec2 fromRange; const int foo = 5; const uvec2 range = uvec2(2, 5); uniform vec2 pairs; uniform sampler2d tex; void main() { foo; //constant expressions are dynamically uniform. uint value = 21; //value is dynamically uniform. value = range.x; //still dynamically uniform. value = range.y + fromRange.y; //not dynamically uniform; current value comes from a non-dynamically uniform source. value = 4; //dynamically uniform again. if(fromPrevious.y < 3.14) value = 12; value; //NOT dynamically uniform. The value of this variable depends on fromPrevious, an input variable. float number = abs(pairs.x); //number is dynamically uniform. number = sin(pairs.y); //still dynamically uniform. number = cos(fromPrevious.x); //not dynamically uniform. vec4 colors = texture(tex, pairs.xy); //dynamically uniform, even though it comes from a texture. //It uses the same texture coordinate, thus getting the same texel every time. colors = texture(tex, fromPrevious.xy); //not dynamically uniform. for(int i = range.x; i < range.y; ++i) { //loop initialized with, compared against, and incremented by dynamically uniform expressions. i; //Therefore, it is dynamically uniform. } for(int i = fromRange.x; i < fromRange.y; ++i) { i; //Not dynamically uniform; `fromRange` is not dynamically uniform. } }