A Branchless RGB to HSL Conversion

by Pol Jeremias on January 31, 2016

1 Comment

Last week I needed a branchless implementation of a colorspace conversion that would go from RGB (Red, Green, Blue) colors to HSL (Hue, Saturation, Lightness). Since I couldn’t find any other implementation that worked for my situations, I decided to write my own, which you will find below!

Code

vec3 rgb2hsl( in vec3 c )
{
    const float epsilon = 0.00000001;
    float cmin = min( c.r, min( c.g, c.b ) );
    float cmax = max( c.r, max( c.g, c.b ) );
    float cd   = cmax - cmin;
    vec3 hsl = vec3(0.0);
    hsl.z = (cmax + cmin) / 2.0;
    hsl.y = mix(cd / (cmax + cmin + epsilon), cd / (epsilon + 2.0 - (cmax + cmin)), step(0.5, hsl.z));

    vec3 a = vec3(1.0 - step(epsilon, abs(cmax - c)));
    a = mix(vec3(a.x, 0.0, a.z), a, step(0.5, 2.0 - a.x - a.y));
    a = mix(vec3(a.x, a.y, 0.0), a, step(0.5, 2.0 - a.x - a.z));
    a = mix(vec3(a.x, a.y, 0.0), a, step(0.5, 2.0 - a.y - a.z));
    
    hsl.x = dot( vec3(0.0, 2.0, 4.0) + ((c.gbr - c.brg) / (epsilon + cd)), a );
    hsl.x = (hsl.x + (1.0 - step(0.0, hsl.x) ) * 6.0 ) / 6.0;
    return hsl;
}

If you are curious about the actual RGB to HSL conversion, you should take a look at this article from Wikipedia, which explains the differences between HSL, HSV, HSI, RGB (and others), and describes the math behind the transformations, click here.

Also, I have done a very simple Shadertoy comparison between the branchless colorspace conversion (left side) and a traditional colorspace conversion that I found on the net.

You should see how colors transition from left to right without changes.

Live

Link

Here : https://www.shadertoy.com/view/MsKGRW

Leave a Reply