Posts Tagged ‘post-effect’


Photoshop math with GLSL shaders

January 5, 2009

I usualy play with Photoshop to try post-processing effects on photos or game screenshots, it’s a lot faster than coding directly anything in shaders, but at the end I wanted to see my effects running in real-time. So I adapted a big part of the C-like code from this famous Photoshop blending mode math page + missing blending modes to GLSL (and now HLSL!) code and I added a few other useful things from Photoshop, such as Hue/Saturation/Luminance conversion, desaturation, contrast.

For example, I tried combining a few things in my Editor:



Translating Photoshop operations on layers gives this kind of code:

uniform sampler2D Tex;
uniform sampler1D GradientMap;
uniform sampler1D GradientGround;

varying vec2 uv;

void main()

vec3 color = texture2D(Tex, uv).xyz;

// Split-tone
vec4 colorDesat = Desaturate(color, 1.0);
vec3 splitColor = texture1D(GradientMap, colorDesat.r).rgb;
vec3 pass1 = BlendColor(color, splitColor);

// Vertical gradient
vec4 verticalGradientColor = texture1D(GradientGround, uv.y);
vec3 pass2 = mix(pass1, BlendColor(pass1, verticalGradientColor.rgb), verticalGradientColor.a);

// Luminosity
vec3 pass3 = mix(pass2, BlendLuminosity(pass2, color + vec3(0.08)), 0.5);

// Linear light at 40%
vec3 pass4 = mix(pass3, BlendLinearLight(pass3, color), 0.4);

// Final
gl_FragColor = vec4(pass4, 1.0);


Here is the list of blending modes and functions I got:

Blending modes:

  • Normal
  • Lighten
  • Darken
  • Multiply
  • Average
  • Add
  • Substract
  • Difference
  • Negation
  • Exclusion
  • Screen
  • Overlay
  • SoftLight
  • HardLight
  • ColorDodge
  • ColorBurn
  • LinearDodge
  • LinearBurn
  • LinearLight
  • VividLight
  • PinLight
  • HardMix
  • Reflect
  • Glow
  • Phoenix
  • Hue
  • Saturation
  • Color
  • Luminosity


  • Desaturation
  • RGBToHSL (RGB to Hue/Saturation/Luminance)
  • HSLToRGB (Hue/Saturation/Luminance to RGB)
  • Contrast

Here is my GLSL code, almost all the blending modes are macros and some do per-channel operation so it could run faster using vector operations with masks (to take into account the values per component), but still I guess it could help 🙂

Download PhotoshopMath.glsl


Oh and by the way you noticed the Split-Tone pass in my example:

// Split-tone
vec4 colorDesat = Desaturate(color, 1.0);
vec3 splitColor = texture1D(GradientMap, colorDesat.r).rgb;
vec3 result = BlendColor(color, splitColor);

It’s just the same thing than the Gradient Map… of the Create new fill or adjustment layer in Photoshop but blended in Color mode, which reminds me Color Temperature and Cross-Processing effects 🙂


I updated the .glsl file, because I forgot a line in the ContrastSaturationBrightness() function and I had some issues on specific hardware due to conditional returns, so now it’s fixed.

And now, here is the HLSL version 🙂

Download PhotoshopMath.hlsl