Color Grading

Within the Unreal engine, the term Color Grading covers the Tone Mapping function (HDR to LDR transformation) and the further Color Correction (LDR color to screen color transformation).

Tone Mapping

The purpose of the Tone Mapping function is to map the wide range of HDR (high dynamic range) colors into the small LDR (low dynamic range) so a monitor can display the color. This is done after normal rendering during post processing. A global tone mapper is a function with three inputs (RGB) and three outputs (RGB). A local tone mapper also takes into account the neighborhood of the pixel but is much more computationally intensive (means slower). A good tone mapper function tries to preserve the color of a pixel even if the color is very bright.

The following graph shows how each channel in the range from 0 to 5 is mapped to the new range of 0 to 1:

Tone Mapping Graphs

This is the used function:

GammaColor = LinearColor / (LinearColor + 0.187) * 1.035;

Note that bright colors become gradually brighter but much less than dark ones. Black remains black and there is a mostly linear part of the curve that is a bit steeper than the non tone-mapped curve would be. That results in some contrast enhancing. While it is normal to get a different look when using a tone mapper, in order to get good results the source image needs to have a higher dynamic range. This can pay off in a more realistic film like look.

The presented tone mapper formula already has two editable constants and while more math would allow further tweaking, finding a good function is not easy as quality, flexibility, and performance need to be considered. We decided to stick to a simple formula and modify the resulting LDR color with a simple color lookup. As we already mapped the HDR color into a limited range, we get several expressions of dark colors and still can modify the bright colors. This method is simple to understand and offers a lot of flexibility with local control and consistent performance.

Property Description
Scene Color Tint A color that is a filter color (multiply) that is applied to the HDR scene color.

Scene Color Tint - (1.0, 1.0, 1.0)

Scene Color Tint - (0.25, 0.25, 0.25)

Tonemapper Toe Factor Allows the dark colors in the tonemapper to be tweaked. Value is in the range [0.0, 1.0].

Toe Factor - 0

Toe Factor - 1

Color Correction

Color correction is implemented through lookup tables (LUTs). Instead of using three 1d lookup tables, a single 3d lookup table is used as this offers more sophisticated color transformations (e.g. desaturation). The following image shows the 16x16x16 color neutral LUT unwrapped to a 256x16 texture (how it is currently visible in the texture browser):

Neutral LUT

You can use the RGBTable16x1.png image from this page, but do not copy and paste as the image displayed on the monitor is not necessarily representative of the source.

A modified texture might look like this one:

Sepia Tone LUT

To make use of a LUT, you need to assign the LUT texture in the post process volume you want to use it.

Property Description
Color Grading Intensity A scaling factor that controls the effect of the color correction.
Color Grading LUT The LUT texture to use as a lookup table for color correction.
Natural Scene Greenish Scene Reddish Scene
Neutral LUT Greenish LUT Reddish LUT

LUT Texture Creation

The procedure:

  1. Make representative screen shots of the scenes you want to adjust and put them in one Photoshop document.

  2. Load a neutral 256x16 LUT into Photoshop.

    You can use the RGBTable16x1.png image from this page, but do not copy and paste as the image displayed on the monitor is not necessarily representative of the source.

  3. Insert the LUT into the Photoshop document with the screenshots (Select All in the LUT document, copy, switch to screenshot document, paste).

  4. Apply color manipulations (best by adding adjustment layers, otherwise you need to flatten everything before and cutting out the 256x16 later gets more tricky).

  5. Select the 256x16 LUT (Select the LUT layer in the layer panel, Menu: Select/Load Selection, Ok).

  6. Copy merged the content of the LUT (Menu: Edit/Copy Merged).

  7. Paste and save the 256x16 texture in some uncompressed format that the engine can read (Menu: File/New, Menu: Edit/Paste, Menu: File/Save As).

  8. Import the texture in the editor and specify the ColorLookupTable Texture Group.

Various color corrections are possible. Here are a few examples:

  • Brightness

  • Saturation

  • Simple contrast (linear with clamping)

  • Higher quality contrast (e.g. curves with a steeper linear part in the middle)

  • Selective changes to the darks, midtones, and bright areas of an image (e.g. curves)

  • Selective changes to specific colors (best expressed in some color space where the brightness is in a separate channel e.g. LAB)

  • Adjustments can even be done in a different color space (e.g. LAB keeps brightness and color independent which can be very useful)