Branchless Photoshop Blend Modes

by Pol Jeremias on April 3, 2016

No Comments

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.

The blog post you are reading right now builds on top of the idea of having a branchless RGB to HSL conversion (, 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 :

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

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!


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.

Continue Reading

SNES & Mode 7 in Shadertoy

by Pol Jeremias on January 13, 2015

No Comments

Last Sunday, I was watching this video (“Super Nintendo Effects Dev Special – Did You Know Gaming? Feat. Mario Castañeda”) that talks about the different effects that could be achieved with the SNES and I realized I could write a very simple Shadertoy inspired by the Mode 7!

Let’s start with the basics though: Do you remember the SNES and its Mode 7?

If you don’t, you have probably seen it, it was used in many games, such as : F-Zero, Pilotwings, Yoshi’s Safari, Secret of Mana,  Final Fantasy (many), Super Mario RPG, Super Mario Kart, Super Mario World, Chrono Trigger, The Legend of Zelda: A Link to the Past…

Mode 7 in Mario Kart

Mode 7 in Mario Kart

Mode 7 is a graphics mode on the Super NES video game console that allows a background layer to be rotated and scaled on a scanline-by-scanline basis to create many different effects.

Disclaimer: I have never actually work with the original Mode 7, this post and its shadertoy are just guess work based on the Wikipedia article. If you did work with it, please share your thoughts, I would like to learn more about it.

From a technical perspective, looks like the Mode 7 is just a texture projection, a very special one, that results on an image that looks like it is 3D. If you look at the picture again, the actual circuit looks like it is using the special projection, however, the karts look like regular sprites that are scaled based on the distance.

Continue Reading

Deformation & Mandelbrot in Shadertoy

by Pol Jeremias on December 8, 2014

No Comments

Here is a couple Shadertoys that I wrote while traveling recently!

The first one, while coming back from Vancouver to San Francisco, is an exploration of what could be achieved deforming a texture. It is still a pure 2D shader, no raymarching or anything, just a UV deformation. The texture is calculated per pixel and it generates LEDs.

Continue Reading

Three Seconds A Day

by Pol Jeremias on November 23, 2014

No Comments

During last year I recorded 3 seconds of my day, every day. And, just recently I have made a video putting it all together.

I took the idea from Cesar Kuriyama‘s TED talk and change it around a little bit, so instead of one second every day I have played with the idea of giving a bit more context and storytelling by adding a couple more seconds.

In the video, you will see many of the changes that occurred to my life from April 2013 to April 2014, including the shutdown of LucasArts and the beginnings of SoMa Play (including the development of our first two games Tetris Ultimate and Boulder Dash). During this period of time, I also met my girlfriend and I turned 30! Finally, you can also see a sneak peak of Beautypi‘s next project and lots of Shadertoy.

And many, many, good times with all my good friends.

If you feel your life is passing really quickly, take a moment to record your special moments because many (many) great things happen every day!