Posts Tagged ‘programming’


Levels control shader

January 28, 2009

A little piece of code to reproduce the Levels control of Photoshop…


Input levels:

I already talked about the gamma correction (mid-tone slider), and I won’t explain what the shadows and highlights (black/white points) sliders are doing (excellent article here) but basically these can be used to remap the tonal range of the image. Here is how it’s calculated:

#define GammaCorrection(color, gamma)  pow(color, vec3(1.0 / gamma))
#define LevelsControlInputRange(color, minInput, maxInput) min(max(color – vec3(minInput), vec3(0.0)) / (vec3(maxInput) – vec3(minInput)), vec3(1.0))
#define LevelsControlInput(color, minInput, gamma, maxInput) GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma)

Example with values from the 1st screenshot (blackpoint = 90/255, gamma = 4, whitepoint = 150/255), red: original color, green: blackpoint & whitepoint modified, blue: same with gamma:


Output levels:

This is useful to shorten the tonal range meaning compressing it to reduce contrast and shift it, details here.

#define LevelsControlOutputRange(color, minOutput, maxOutput) mix(vec3(minOutput), vec3(maxOutput), color)

Example with values from the 1st screenshot (min output = 40/255, max output = 180/255), red: original color, green: output levels applied:


Putting it all together:

#define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput)

Same example but both input and output levels taken into account, red: original color, green: final result:


So these macros make it quite easy to increase or reduce contrast, shift and clip tonal range, lighten or darken shadows and highlights. I added the (GLSL / HLSL) code to the Photoshop Math shaders.


Photoshop gamma correction shader

January 22, 2009

After reproducing contrast, hue, saturation, brightness controls of Photoshop in pixel shaders, here is the gamma correction filter 🙂



There are 2 ways of changing gamma in Photoshop:

  • Image | Adjustments | Exposure…
  • Image | Adjustments | Levels… (or CTRL+L) and then move the midtone slider.

Gamma correction is not the same thing than Brightness at all, even if it can give the impression it is. For example here is the histogram of my original image:


Then after setting the gamma to 0.5 (it compresses the highlights and stretches the shadows):


And here it is after lowering the brightness (Image | Adjustments | Brightness/Contrast…):


Here you can see it clipped the values after some threshold in the shadows (and also in the highlights) and you’re loosing a lot of lighting information in this case. That’s actually why I wanted to have also a gamma control in my post-processing effects.


A little macro:

// Gamma from 9.99 to 0.1
#define GammaCorrection(color, gamma)   pow(color, 1.0 / (gamma))

color = GammaCorrection(color, 0.1);

Here are the curves it produces with extreme values (limits of Photoshop [9.99, 0.1]):


So you see it stays in the same range and give a non-linear luminance (if correction value is different than 1). By the way I used this awesome web function grapher here.

By zooming and taking a very close look I noticed a few tiny differences with Photoshop in the shadows (seriously you need to toggle screenshot from shader and photoshopped image quickly and scan the image to see where it’s not the same). Photoshop on the left, shader version on the right (gamma = 0.1).


I also saw that the gamma in Photoshop (on the left) produced some banding artefacts somewhere, and it didn’t in my shader (on the right),  well.. :):


I added the code in my Photoshop Math (GLSL/HLSL) shaders.


Photoshop math with HLSL shaders

January 8, 2009

See my original post about Photoshop math in GLSL (blending modes, contrast, desaturation, RGB to HSL). Now it’s also in HLSL!

Download PhotoshopMath.hlsl


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


Experimenting NodeBox

June 13, 2008

Heya! I recently discovered NodeBox, amazing software dedicated to computational art / creative & generative programming. I’m not gonna (re-)present anything about it, but here are some videos of my first two attempts with this fantastic tool.

Just changed 1 or 2 things from this little tutorial. If you keep looking at the center point, after watching the video, you’ll see the stopped image rotating in the inverse direction, heh.

The next one is another variation with some colors and cubes, and just a different way to rotate some objects.


GDC 2008: Hot or not ?

February 26, 2008

So what was cool at the GDC and what wasn’t? The following is just my opinion as a gameplay developer, general game dev fan, and gamer, on the sessions I saw so it may be not representative of the whole event. I’m not gonna summarize the techniques and talks I’ve seen but it’s more like a sum-up of a few lectures so you can check (or not) at the video recordings or powerpoint presentations you’re interested in, if they are online somewhere.

I saw 16 sessions during these 3 days, which are:

  • Storytelling in Bioshock: Empowering Players to Care about Your Stupid Story
  • Rules of Engagement: Blizzard’s Approach to Multiplayer Game Design
  • Star Wars: The Force Unleashed: How LucasArts is Building a Game, a Development Team and a Technology Pipeline… At the Same Time
  • Structure VS. Style (Chris Hecker)
  • Pollinating the Universe: User-generated Content in Spore
  • Uncharted Animation: An In-depth Look at the Character Animation Workflow and Pipeline
  • Uncharted: Drake’s Fortune Post-Mortem: Amazing Feats of Daring
  • Adventures in Data Compilation and Scripting for Uncharted: Drale’s Fortune
  • Beyond Printf: Debugging Graphics Through Tools
  • Prototype: Open World, Open Mind, Next Generation Thinking
  • Truer Impostors
  • Crysis Next Gen Effects
  • Practical Light and Color
  • Interactive Actors That Express Emotion (Ken Perlin)
  • Natural Motion: Runtime Character Animation with Morpheme
  • The Next 20 Years of Gaming (Ray Kurzweil’s keynote)

I was expecting a lot from the programming track, and actually the best sessions were the ones about game design! The programming ones were either too technical and short or not deep enough. I’m sure it’s very difficult to make a good lecture for the right audience, anyway I was a bit disappointed of the ones I attended to.

However, the most interesting (in the programming category) was maybe the one about the Next Gen effects in Crysis, and curiously I wasn’t expecting that much from this one! It was cool because by describing many steps of their effects, they kind of explained ‘why it is beautiful‘, especially by giving their secrets to make the water (procedural animation, caustics, light beams, shore, physics), the frozen things, and the different motion blurs (object motion blur, camera motion blur). I was surprised how their techniques for these motion blurs were simple (using depth and velocity masks). They did lack a little of time to cover everything but the slides (with shader codes) should be available online soon.

A nice surprise was the one called Truer Impostors. It was all about a new student’s technique for rendering lot of detail with a high frame-rate. I won’t explain it in here, his paper is a much better source for that, but just as an apetizer: his demo was a scene with 250 000 animated birds in the sky running at 30 fps on a 7800GT. It was a 20 mins lecture so a bit too short for such a technical subject. There are good chances his technique replaces all the other ways he talked about (parallax mapping, relief mapping, true impostors) in future games.

The most impressive live demos I’ve seen were the ones of Prototype and Star Wars: The Force Unleashed.

Prototype was REALLY spectacular with features like: climbing over all the buildings, cars, dynamic objects, a really huge and detailed city, and globally very cinematic and violent combat scenes (very good camera). After at least 10 minutes of explosive playing, I was asking myself: yeah but what’s gonna be the gameplay? I mean ok you kill everybody, you run away from monsters, you steal tanks and helicopters, you climb over everything and you make crazy jumps from the top of skyscrapers, but then what? The basic gameplay is to recover your memory by stealing the one of others, that’s good for 10 mins but what is it besides that? I hope there’s a deeper (macro) gameplay after that.

SW: The Force Unleashed was cool, because what we saw in the trailers is true and well working. I mean the simulation-based gameplay is not a lie, the combination of standard physics things, (all kind of) realistic breakable objects, and the AI/physics-based character animation (Euphoria technology) is awesome. But nothing new actually. I thought they would explain more technically how did they manage to get these 3 technologies working together, but they talked more about their whole production philosophy (new team, hiring, the name of their engines, ‘yeah it was hard but now it’s working’), beh .. ok then.

storytelling in bioshock

The best lecture I saw was: Storytelling in Bioshock: Empowering Players to Care about Your Stupid Story. I won’t explain anything because it would need a full post for it, but to make it simple, they had awesome game design ideas to make the player like the game for both hardcore story fans and the rest of the world that doesn’t care about the story and wants to finish the game 🙂

I’m starting to get bored of writing all this, but some ideas for the last sessions:

  • Craziest lectures: Structure vs. Style, The next 20 years of gaming.
  • A bit boring: Amazing Feats of Daring: An Uncharted Postmortem, Adventures in Data Compilation and Scripting for Uncharted: Drake’s Fortune.
  • I liked a lot: Interactive Actors That Express Emotion (Perlin), NaturalMotion: Runtime Character Animation with Morpheme, and part of the Practical Light and Color.
  • Momentum vs. Animation was canceled (or delayed of very late), too bad, great title.
  • We should really try morpheme and it’s API, Actor Machine (Perlin), FX Composer 2’s shader debugger.
  • I would have liked to see Uncharted Animation: An In-depth Look at the Character Animation Workflow and Pipeline.

I’m not talking about what I saw in the expo hall, that’s already a big post 🙂

If you’re reading this and were to the GDC, let me know your opinion!


GDC 2008

February 18, 2008

Hi there, today was my last presentation at school (there’s still my intership presentation at the end of the year but..) about my external activities during my 5th year, meaning my work at Ubisoft. So now I can really say my work ‘at school’ is over!

I’m working in the company for 2 years now, and tomorrow I’ll be flying to San Francisco with my friend and colleague Arnaud to assist to the Game Developer Conference (GDC) 2008. It’s only a 4 days trip, but I’m sure it totally worth it!


There are so many lectures and presentations, we can’t see everything we want to :/ But we’re really looking foward to watch some of them:

All these are in the Game Design track (remember we’re developers ;)) but seem to be very interesting from a gameplay point of view. And of course technical sessions like:

And personally, I would enjoy assist to the next ones but it’s often in the same time that to biggest ones above.

Here is the programming track (almost 100 sessions) and here is the game design one (about 150 sessions). These are the two tracks we’re really interested in. Too bad we can’t see the Ubisoft’s conferences.

I’m really exited with the idea of going to the United States for the first time! I’ll try to take a few photos of San Francisco, stay tuned.