Constant float values in GLSL shaders - any reason to use uniforms?

32,117

Solution 1

First off, the performance difference between using a uniform or a constant is probably negligible. Secondly, just because a value is always constant in nature doesn't mean that you will always want it be constant in your program. Programmers will often tweak physical values to produce the best looking result, even when that doesn't match reality. For instance, the acceleration due to gravity is often increased in certain types of games to make them more fast paced.

If you don't want to have to set the uniform in your code you could provide a default value in GLSL:

uniform float someConstantValue = 12.5;

That said, there is no reason not to use const for something like pi where there would be little value in modifying it....

Solution 2

Huge reason:

Error: Loop index cannot be compared with non-constant expression.

If I use:

uniform float myfloat;
...
for (float i = 0.0; i < myfloat; i++)

I get an error because myfloat isn't a constant expression.


However this is perfectly valid:

const float myfloat = 10.0;
...
for (float i = 0.0; i < myfloat; i++)

Why?

When GLSL (and HLSL for that matter) are compiled to GPU assembly instructions, loops are unrolled in a very verbose (yet optimized using jumps, etc) way. Meaning the myfloat value is used during compile time to unroll the loop; if that value is a uniform (ie. can change each render call) then that loop cannot be unrolled until run time (and GPUs don't do that kind of JustInTime compilation, at least not in WebGL).

Solution 3

I can think of two reasons:

  1. The developer reuses a library of shaders in several applications. So instead of customizing each shader for every app, the developer tries to keep them general.

  2. The developer anticipates this variable will later be a user-controlled setting. So declaring it as uniform is preparation for that upcoming feature.

If I was the developer and none of the above applies then I would declare it as "const" instead because it can give a performance benefit and I wouldn't have to set the uniform from my code.

Share:
32,117

Related videos on Youtube

kshahar
Author by

kshahar

LinkedIn: https://www.linkedin.com/in/shaharkosti GitHub: https://github.com/kshahar

Updated on September 02, 2020

Comments

  • kshahar
    kshahar over 3 years

    I'm looking at the source of an OpenGL application that uses shaders. One particular shader looks like this:

    uniform float someConstantValue;
    void main()
    {
        // Use someConstantValue
    }
    

    The uniform is set once from code and never changes throughout the application run-time.

    In what cases would I want to declare someConstantValue as a uniform and not as const float?

    Edit: Just to clarify, the constant value is a physical constant.

  • Adrian Seeley
    Adrian Seeley about 10 years
    These cases are very rare, and pop up in compute shaders more than anything (and some skeletal animation systems).
  • Tara
    Tara over 8 years
    "the performance difference between using a uniform or a constant is probably negligible" It's not good to guess. Declaring a constant value allows the GLSL compiler to perform optimizations that wouldn't be possible otherwise. But sadly GLSL compilers tend to have bugs and behave in unpredictable ways. So a general answer really isn't possible. I have encountered severe performance differences between using const and non-const arrays (depending on their length) even though their value will never be modified. I assume this is a compiler bug.
  • Emilian Cioca
    Emilian Cioca almost 7 years
    These days, you can expect modern OpenGL and D3D to perform just-in-time compilation for uniform values (any value that is not changed for the duration of one render call). For example, an if statement checking a boolean uniform variable would be compiled away when the render call is initiated - no runtime check would be done on the GPU. See this wiki for more information.
  • Emilian Cioca
    Emilian Cioca almost 7 years
    Although the previous comment was likely accurate at the time, this kind of just-in-time compilation can now be expected. Uniform values can be optimized as though they were constants. See this for more info.
  • Karu
    Karu over 6 years
    This is answering the opposite of the question - OP wants to know why you would use a uniform instead of a const, not the other way around.
  • abcthomas
    abcthomas over 6 years
    This is not rare with OpenGLES/WebGL
  • ToolmakerSteve
    ToolmakerSteve over 5 years
    Re "and I wouldn't have to set the uniform from my code". As fintelia shows, you can always set a default (initial) value of the uniform in your shader.
  • XCS
    XCS over 5 years
    So, theoretically speaking, consts could be more performant than uniforms? But uniforms are shared across all vertex shader calls, but constants are only initialized/shared within one call?