• entries
14
17
• views
5782

# Fun hacks to fiddle with colour

212 views

HDR source image not included, it's too big - you can download several from Paul Debevec's site, then convert them to DDS with the texture tool in the DX SDK

This sort of effect is easiest to do as a post-process. You only need to do the calculations once per pixel. So, we start off by rendering our OMFG HDRTASTIC SCENE (TM) to a texture.
   float3 clrIn = tex2D(Texture0, texCoord).rgb;

Now to adjust the saturation. Real cameras (and eyes!) don't just take in red light, and make red, etc.; each pigment responds to different frequencies of light based on a nice smooth response curve. We can fake this by simply multiplying the input colour's R, G, and B components by constants and adding them together for each output channel. To make things easier, instead of specifying 3 complete colours, we're going to just use two constants, A and B, to specify how quickly the response falls off from the 'center' frequency. If A and B are 0, the output will be the same as the input; if they are 1, the output will be greyscale.
       float3 responseR = float3( 1.0,   b,    a);   float3 responseG = float3( b,   1.0,    b);   float3 responseB = float3( a,     b,  1.0);   clr.r = dot(clrIn, responseR);   clr.g = dot(clrIn, responseG);   clr.b = dot(clrIn, responseB);

Once we have this result, we can multiply the result by another colour to give the whole scene a slight tint (but don't go overboard - your entire scene probably does not need to be bright pink). After that, we do something fancy to get the exposure + gamma in a nice range (exp is used here), and output the final result.
   clr = 1 - exp(-exposure * tint.rgb * clr);      return float4(clr.r, clr.g, clr.b, 1);

HDR results
First, the original HDR input image with A=B=0, tint=1,1,1, and exposure = 1: (tonemapped so we can see it on an LDR monitor, but basically, this is what the original looks like)

Setting A=0.4 and B=0.2 takes away some of the colour by mixing the red, green, and blue values together. Setting the tint to 1,0.8,0.7 or so gives a nice sepia look. Also, if we adjust the values somewhat and give it a bluish tint, we can get a night-time effect (although the overly bright sky gives it away).

On the other hand, if we use negative values (here, A=-0.1 and B =-0.2), the colours become slightly richer (bump the exposure up slightly to compensate for the decreased brightness). However, exaggerating the effect can give unpleasant results - if you want a major increase in colour saturation, you will probably need to resort to a more sophisticated technique.

LDR results
But wait, you cry! Unlike most, I know that "HDR" is not another name for "massively overdone bloom", and I've realized that my game looks just fine without it! Well, guess what - it works just as well with ordinary images, as long as you don't try to push it too far. We only need to slightly change the end of our shader:
   clr = exposure * tint.rgb * clr;      return float4(clr.r, clr.g, clr.b, 1);

Top: Original screenshot (from CounterStrike: Source); sepia; Bottom: increased saturation; night.

These images have more extreme settings as well as some gamma adjustment.

There are no comments to display.

## Create an account

Register a new account