# Difference between revisions of "Dynamically Uniform Expression"

(→Uses) |
(Full page.) |
||

Line 6: | Line 6: | ||

== Definition == | == 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, [[Uniform (GLSL)|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 {{code|const}}-qualified global and local variables) are always dynamically uniform. {{code|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. | ||

=== Examples === | === Examples === | ||

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

+ | <source lang="glsl"> | ||

+ | 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. | ||

+ | } | ||

+ | } | ||

+ | </source> | ||

== Uses == | == Uses == | ||

Line 18: | Line 67: | ||

* The index to [[Interface_Block_(GLSL)#Buffer_backed|buffer-backed interface blocks]]. | * The index to [[Interface_Block_(GLSL)#Buffer_backed|buffer-backed interface blocks]]. | ||

* In [[Compute Shader]]s, the expressions leading to the execution of a {{code|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 {{code|barrier()}} statement in the same sequence and the same number of times. | * In [[Compute Shader]]s, the expressions leading to the execution of a {{code|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 {{code|barrier()}} statement in the same sequence and the same number of times. | ||

− | |||

− | |||

[[Category:OpenGL Shading Language]] | [[Category:OpenGL Shading Language]] |

## Revision as of 02:18, 24 November 2012

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.

## 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.

### 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.
i; //Therefore, it is dynamically uniform.
}
for(int i = fromRange.x; i < fromRange.y; ++i)
{
i; //Not dynamically uniform; `fromRange` is not 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.