OSL
Using smoothstep


return to main index



Introduction

The function smoothstep() is part of OSL shading language. Given three values, min, max and input, the function will return a number between 0 and 1 that represents the relationship of the input value to the min and max values.

If input is less than min, smoothstep() will return 0.
If input is equal to, or larger than max, smoothstep() will return 1.
If input is between min and max, smoothstep() will return a value (proportionately) between 0 and 1.0.

For example, suppose the min and max values are 0.3 and 0.6. Using the smoothstep function with input values of 0.4 and 0.8 we get output values of 0.35 and 1.0.



smoothstep(0.3, 0.6, 0.4);
returns 0.35




smoothstep(0.3, 0.6, 0.8);
returns 1.0
low_freq

Applying Smoothstep

As shown below the smoothstep function can be used to control the blending of colors - listing 1.


low_freq
Figure 1



Listing 1 (smoothcolor.osl)


shader
smoothcolor(float s = 0 [[int lockgeom = 0]],
            float t = 0 [[int lockgeom = 0]],
            float s_min = 0.3,
            float s_max = 0.8,
            color beginRGB = color(0.6,0.6,0.0),
            color endRGB = color(0.6,0.121,0.0),
        output color resultRGB = 0)
{
float blend = smoothstep(s_min, s_max, s);
resultRGB = mix(beginRGB, endRGB, blend);
}


Double Smoothstep

Often a shader must control a blending factor by smoothly increasing and decreasing an effect - listing 2.

The trick here is to notice that subtracting the values returned from the smoothstep() function from 1.0 has the effect of inverting its effect ie. the output values decrease from 1.0 to 0.


low_freq
Figure 2



Listing 2 (smoothcolor2.osl)


shader
smoothcolor2(float s = 0 [[int lockgeom = 0]],
             float t = 0 [[int lockgeom = 0]],
             float s_mid = 0.6,
             float s_width = 0.3,
             float blur = 0.1,
             color beginRGB = color(0.6,0.6,0.0),
             color endRGB = color(0.6,0.121,0.0),
        output color resultRGB = 0)
{
float s_min = s_mid - s_width/2;
float s_max = s_mid + s_width/2;
  
float blend = smoothstep(s_min, s_min + blur, s) *
                (1 - smoothstep(s_max - blur, s_max, s));
                
resultRGB = mix(beginRGB, endRGB, blend);
}


low_freq
Figure 3


Multiple Smoothsteps

The double ramping seen in the previous section can also be achieved in 's' and 't' directions - listing 3.



low_freq
Figure 4



Listing 3 (smoothcolor4.osl)


shader
smoothcolor4(float s = 0 [[int lockgeom = 0]],
             float t = 0 [[int lockgeom = 0]],
             float s_mid = 0.5,
             float s_width = 0.7,
             float t_mid = 0.5,
             float t_width = 0.7,
             float blur = 0.1,
             color beginRGB = color(0.6,0.6,0.0),
             color endRGB = color(0.6,0.121,0.0),
        output color resultRGB = 0)
{
float s_min = s_mid - s_width/2;
float s_max = s_mid + s_width/2;
  
float t_min = t_mid - t_width/2;
float t_max = t_mid + t_width/2;
  
float blend = smoothstep(s_min, s_min + blur, s) *
                (1 - smoothstep(s_max - blur, s_max, s)) *
             smoothstep(t_min, t_min + blur, t) *
                (1 - smoothstep(t_max - blur, t_max, t));
                
resultRGB = mix(beginRGB, endRGB, blend);
}




© 2002- Malcolm Kesson. All rights reserved.