If you have used Adobe Photoshop you have probably seen that it allows users to draw (or create content) in different layers. These layers can after be combined in many different ways, the blend modes. https://en.wikipedia.org/wiki/Blend_modes.

The blog post you are reading right now builds on top of the idea of having a branchless RGB to HSL conversion (http://www.poljeremias.com/branchless-rgb-to-hsl), and it proposes branchless solutions to the most common color blending operations.

If you want to just play around with it, visit the following Shadertoy, there you can try live the different branchless blending operations : https://www.shadertoy.com/view/Md3GzX

This post contains implementations for the following blending operations :

- Source
- Destination
- Multiply
- Screen
- Exclusion
- Overlay
- Hard Light
- Soft Light
- Color Dodge

- Color Burn
- Linear Dodge
- Linear Burn
- Vivid Light
- Linear Light
- Pin Light
- Hard Mix
- Substract
- Divide

- Addition
- Difference
- Darken
- Lighten
- Invert
- Invert RGB
- Hue
- Saturation
- Color
- Luminosity

Continue Reading

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!

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.