Posts Tagged ‘code’

h1

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:

photoshopmath_tn

photoshopmath_editor_tn

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

Functions:

  • 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

Update:

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 🙂

Update:

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

Advertisement
h1

Barcelona D-1

March 11, 2008

Hi! I’ve been quite silent since I got back from the SF’s GDC, so here are some news.

I’ll be flying to Barcelona, Spain tomorrow for a few days trip for Ubisoft where I’ll meet the team responsible for a new project. I really can’t say more about it because the game hasn’t be announced yet. The goal is to learn from a specific technology they’re developing over there which is very exiting (couldn’t tease more I guess), help them on their new game, and see how it could be used in other upcoming projects.

I’ve already done this kind of mission before for another technology made by the Montpellier team, a bit the same genre and older, but still confidential. So I’m glad to renew the experience with another studio, that I don’t know yet. Actually I already worked with the Barcelona team on Driver Parallel Lines for Wii last year, on the Wii-specific controls for the character/camera and vehicle, so I know a few of them.

As usual, I didn’t pack my stuff yet, the last time I did the same for my travel to San Francisco and the result was that I couldn’t find my digital camera battery recharger:/

Beside that, I told you I was making a small game engine and tool on top of Ogre and wxWidgets… Well it only has a few days of work, so the editor has nothing fancy for now (I’m still discovering wxWidgets), but the engine starts to be interesting from a usage point of view. There’s nothing Next-Gen in it but with a bit of work it’s gonna be … “wait for it … LENGEN…”, no, just cool.

ogre-editor-code

In fact, in my end of studies project, as soon as I wanted to make a test with Ogre (or with the physics engine) I added things in my current in-game gamestate or player or camera class, and everytime it was making the code uglier with lots of previous test in the usual Update() methods (I’m summarizing but you can imagine), because I had only ONE game, so with my new project, the goal is to be able to make a new ‘demo’ with a few clicks (like a game on itself). I’ll explain that idea next time (moreover the editor part of this process hasn’t been done yet). Anyway here is a screenshot of it :

ogre-editor-small

It hasn’t any name yet, but I’m working on it 🙂 The only cool thing for now is that the wxAUI and wxPropertyGrid parts of wxWidgets produce controls that look like the .net ones (auto-hide, dockable, drag’n drop, properties, blabla…).