Dynamically Uniform Expression

From OpenGL.org
Revision as of 01:18, 24 November 2012 by Alfonse (talk | contribs) (Full page.)

Jump to: navigation, search
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.


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.


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.
    i; //Therefore, it is dynamically uniform.

  for(int i = fromRange.x; i < fromRange.y; ++i)
    i; //Not dynamically uniform; `fromRange` is not dynamically uniform.


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.