Color Management in VFX — LUT

Cheng Jian Yu
6 min readApr 30, 2021

If you are an artist you probably already hear this thing a lot. Your lead just send you a .cube file and tell you to view your image with this LUT. But really, do you know what is LUT? Do you have to know what the LUT is?

Well, you don’t have to. But once you understand how it works, it will definitely help you build the correct color.

The other reason I want to talk about LUT is because it will be much easier when we go into different sections like ACES or view transformation after you have the rough understanding of this.

WHAT IS LUT?

This is the short definition from Sony.

A LUT (Look-Up-Table) is simply a table of fixed numerical values that can be applied to video to alter its look. It can change an image’s contrast or colour or both. -Sony

Think like this way: a box has a formula inside that it can take whatever you give to it and spit out through the formula. And thanks to this magical box, then we are able to represent the color that we want to describe.

We can simply distinguish LUT into two category — Technical LUT and Creative LUT.

  • Technical LUT, or Neutral LUT, that is used to convert the camera native space to specific display space, like LogC to Rec.709, or REDlogFilm to DCI-P3. These LUTs are usually provided by the camera manufactures.
  • Creative LUT, which is more artistic to create a visual look or style.

To understand how color flow in different colorspaces and the relationships with displays, we will only discuss the technical LUT in this article.

To dive deeper in this, there two types of technical LUT: 1D LUT and 3D LUT.

1D LUT

1D LUT is an invertible color transformation which only affects individual red, green and blue channel which is one dimension of a 3D color cube. It can adjust contrast, brightness, black/white level, pretty much like what you can do in photoshop with “black/white”, “levels”, “curves” and “exposure”.

It can be used in gamma correction when linearizing the transfer function, or bring the linear values into the range 0–1 that the image is able to apply 3D LUT, we will talk about this later.

This is the example of how a 1D LUT looks like:

Version 1
From 0 1
Length 4096
Components 1
{
0.0000000000e+00
1.0989011498e-03
2.1978022996e-03
3.2967033330e-03
4.3956045993e-03
5.4945056327e-03
6.5934066661e-03
7.6923076995e-03
8.7912091985e-03
9.8901102319e-03
1.0989011265e-02
1.2087912299e-02
...

This is a linear to Rec.709 1D LUT from OCIO configuration. You can see it in the example, now it only shows 17 points though, is indicating to a certain output value by the given input value. The length 4096 means it is a 2¹² = 12-bit LUT, has 4096 indices for all 3 channels that contains 4096³ = 68.7 billion colors.

3D LUT

3D LUT, as its name, is a 3 dimensional LUT that describes the color transformation more precisely. It can do color transformation more complicated than 1D LUT such as hue and saturation, because when one channel is modified then the rest channels will also be affected relatively.

That said, if there is a 100% accurate 3D LUT, it should have 256 indices for each dimension to transform 16.7 million colors, one input only for one output. Unfortunately, this LUT file will become super heavy and it’s difficult for computer to handle.

In order to make the process easier and faster, the table has to be downscaled. The most commonly used are 17x17x17 and 33x33x33 calibrated color data point, up to 65x65x65. The higher the color data points, the more accurate the interpolated point between the adjacent calibrated points, but that also increases the memory storage.

Let’s take a look at a 3D LUT from Alexa LogC to Rec.709.

# Alexa conversion LUT, logc2video, itu709. Full in/full out.
# created by alexalutconv (2.09)

LUT_3D_SIZE 65
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.002121 0.000000 0.000015
0.013123 0.000000 0.000095
0.024927 0.000000 0.000181
0.037641 0.000000 0.000273
0.051407 0.000000 0.000373
0.066735 0.000000 0.000489
0.082548 0.000000 0.000629
0.098897 0.000000 0.000797
0.115951 0.000000 0.001000
...

The size 65 means it is a 65x65x65 3D LUT contains 35,937 points. Most of 3D LUTs expect the input value in the range 0–1 domain and the output value will also be in the range 0–1. It’s noticeable there is no way we can know which colorspace that this 3D LUT covert from and to, therefore it is important to name the file clearly.

SHAPER LUT (PRELUT)

Because 3D LUT only take the value in the range 0–1 that will cause clamping for the linear images. A smaller LUT, which is a 1D LUT only affects one dimension without changing hue or saturation, maps the high dynamic value to the display range 0–1 before applying 3D LUT.

It is used for the applications are not floating point supported.

CSPLUTV100
3D

BEGIN METADATA
END METADATA

4096
0.001186 0.001189 0.001193 0.001196 0.001200 0.001203 0.001207 ...
0.000000 0.000244 0.000488 0.000733 0.000977 0.001221 0.001465 ...
4096
0.001186 0.001189 0.001193 0.001196 0.001200 0.001203 0.001207 ...
0.000000 0.000244 0.000488 0.000733 0.000977 0.001221 0.001465 ...
4096
0.001186 0.001189 0.001193 0.001196 0.001200 0.001203 0.001207 ...
0.000000 0.000244 0.000488 0.000733 0.000977 0.001221 0.001465 ...

65 65 65
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.003420 0.000000 0.000000
0.011150 0.000000 0.000000
0.020507 0.000000 0.000000
0.029807 0.000000 0.000000
0.038688 0.000000 0.000000
0.046986 0.000000 0.000000
0.054977 0.000000 0.000000
0.063405 0.000000 0.000000
0.072741 0.000000 0.000000
0.083196 0.000000 0.000000
0.094621 0.000000 0.000000
...

The example is OCIO ACEScg to Rec.709 LUT for Maya. It’s usually bind with a 3D LUT as you can see above, a 12-bit 1D shaper LUT is listed ahead of a 65x65x65 3D LUT which maps a 0–1 range to Rec.709 space.

The different format of LUT has their own header. In this case the header is written as “CSPLUTV100”.

One last thing, many people actually don’t know what is the correct color even after applying LUT. Always check the input colorspace to see if it is exactly the same as the colorspace that LUT tells you to convert from.

Let me take the LogC to Rec.709 as an example again, the result color should be identical as the color shows on-set. In some applications such as Nuke, the operation for applying LUT sometime converts the colorspace back to linear space and that will not show the color correctly. Make sure the input colorspace stay at the Alexa wide gamut with LogC transfer function, then apply the LUT.

--

--