Monday, 12 April 2010

Orange & Teal - colour grading


If you have read the article about orange & teal abyss in the Hollywood movies you may wonder how such an effect can be accomplished in games. It is very simple and I will cover it in this entry.


Normally, in the image and photography processing a lot of effects (including mentioned orange & teal) can be achieved by means of editing curves. Typical curves tool in Photoshop or Gimp looks as follows:


It's one of the most powerful tools and is used in many scenarios, eg. enhancing contrast or changing tonal atmosphere.

A curve is a function where arguments are input tones (on the x axis) and the results are output tones (y axis). Normally it is linear (meaning output image doesn't differ from the source one) but to change feeling and atmosphere of the image it is sometimes desirable to change its shape (in many scenarios so called s-curve will do which is presented in the image above). Thus contrast for instance can be enhanced or tonal atmosphere can be altered. Also some special effects can be achieved thanks to that (eg. one can do colour inversion this way). I don't want to cover a theory behind editing curves as there are a lot of tutorials on this subject regarding editing photos in Photoshop and Gimp so now I'm moving to the implementation details.

If we limit our input and output to the range of [0; 1] - i.e. typical colours range - then it is very simple to achieve this in the shader - this function can be passed as a 1D texture. Arguments are u-coordinates, and results are colours. In case we treat all the channels the same way, it will be texture in gray scale. However, it may be sometimes desirable to operate on red, green and blue channels separately - then it will be regular RGB texture. Underneath is the texture I used for achieving effect from the first image:
It is stretched of course to make it easier to analyze. Black (all channels equal 0) is mapped onto black (as all channels are 0 u-coordinate is also 0) as always, however white (all channels equal 1) is mapped to a very light orange (right of the image; u-coordinate being 1).

For each of the channels we compute their value as:

colour.r = tex2D(gradingTex, float2(scene.r, 0.5f)).r;

Where scene is our source image and gradingTex is the function to be used.

All we have to do is to get the pixel from the scene image and multiply each of its component by the value read from the curve texture at the place equal to the each of the channels.

Here are some examples using this simple yet so powerful approach:

Source image:
 High- and low-contrast respectively:
 And once again orange & teal:

10 comments:

  1. A different way to achieve this (in a shader) is to convert your color into HSV-space, and project onto the line between orange and teal.

    This will give you a gradual interpolation between our two hero-colors (and grayish if the initial color is nothing like it).

    ReplyDelete
  2. Good idea but it is more specialized approach if I got it right?

    ReplyDelete
  3. This effect can be increased by desaturating image and adding glow at the end of process.
    This is a method that I used in AAP (with some blur on parts of the screen).

    ReplyDelete
  4. In the end, it's all about processing the image. Exactly the same techniques to the ones used in photography ;)

    ReplyDelete
  5. You might be interested in some simple technique we've developed for controllable run-time color correction: http://tridemax.blogspot.com/2010/01/color-correction.html

    ReplyDelete
  6. Thanks Maksym, I came across similar solution to yours once but I decided to go with something different this time :)

    ReplyDelete
  7. BTW just another solution is to desaturate shadow-tones while increasing saturation of highlights. It works well in some of the scenes and I learnt this 'trick' when doing some of my HDRs ;) will give example of that soon.

    ReplyDelete
  8. It's worth adding that this technique may be seen just as a "lookup table" and you can call your texture a "lookup texture". Another name for this is "mapping" (it's available in GIMP under this name).

    ReplyDelete
  9. True, although look up table/texture is a more general term. What I did was really editing curves in Gimp and then just generating texture based on their settings. What I wanted to show was that same techniques apply to photo/image editing and real time graphics :)

    ReplyDelete
  10. Thanks, I was trying to get a shader like this for a while. But I could only tweak one color. However, I tried this but the effect I got wasn't the desired one.

    In orange&teal, I want highlights and shadows to show teal while skin(midtones?) tones showing orange exclusively. How should I go about that?

    ReplyDelete