During the conversion of shaders written in Cg/HLSL, we often find the saturate() function. This function is not valid in GLSL even though on NVIDIA, the GLSL compiler accepts it (do not forget that NVIDIA’s GLSL compiler is based on Cg compiler). But ATI’s GLSL compiler will reject saturate() with a nice error. This function allows to limit the value of a variable to the range [0.0 – 1.0]. In GLSL, there is a simple manner to do the same thing: clamp().

Cg code:

float3 result = saturate(texCol0.rgb - Density*(texCol1.rgb));

GLSL equivalent:

vec3 result = clamp(texCol0.rgb - Density*(texCol1.rgb), 0.0, 1.0);

BTW, don’t forget all float4, float3 and float2 which correct syntax in GLSL is vec4, vec3 and vec2.

Lors de la conversion de shaders écrits en Cg/HLSL, on trouve souvent la fonction saturate(). Cette fonction n’est pas valide en GLSL bien que sur les NVIDIA le compilateur l’accepte (n’oublions pas que le compilateur GLSL de NVIDIA repose sur le compilateur Cg). Mais le compilateur GLSL d’ATI générera une belle erreur à la vue de saturate(). Cette fonction sert à limité la valeur d’une variable entre 0.0 et 1.0. En GLSL il y un moyen tout simple de faire la même chose: clamp().

Code Cg:

float3 result = saturate(texCol0.rgb - Density*(texCol1.rgb));

Equivalent GLSL:

vec3 result = clamp(texCol0.rgb - Density*(texCol1.rgb), 0.0, 1.0);

Au passage lors des conversions, n’oubliez pas les float4, float3 et float2 qui s’écrivent en GLSL en vec4, vec3 et vec2.


6 thoughts on “Saturate function in GLSL”
  1. GLSL compiler will not accept the saturate(…) function even on NVIDIA – in a MacBook Pro; I suppose it’s due to the driver.

  2. A poor language-design choice since SAT is an assembly directive on all these GPUs (and in many or all cases, a FREE operative, like “PP” or “ABS”). So you have to hope that whatever math you use in place of SAT, the compiler is smart enough to recognize it and reduce it to a SAT. Classic OpenGL-ARB idiocy, making everyone’s code slower for the sake of some arbitrary political argument (Khronos: too late).

  3. @Bjorke
    I expect my compiler to do as you say. If it doesn’t then it isn’t Gl-ARB idiocy as you claim. The clamp approach is actually a better terminology:

    clamp(dot(lightDir – normalDir), 0.0, 1.0);

    Look familiar? The clamp function does what its name implies, whereas the use of saturate in this context is ambiguous . To saturate something in my mind means to set it to its full value (i.e. full colour), not clamp to 0 or 1
    my mind indicates that I wish to saturate to 100%, not clamp to 0 or 1.

    Saturate: Put (a device) into a state in which no further *increase* in current is achievable.

  4. Sorry for the bad post; in emacs. But I think you get what I am trying to say.

    clamp(dot(lightDir – normalDir), 0.0, 1.0);
    should read
    clamp(dot(lightDir , normalDir), 0.0, 1.0);

Leave a Reply

Your email address will not be published. Required fields are marked *

6 + 2 =