Everything we do at Color.io and VisionColor is in one way or another related to the art and science of Color Lookup Tables. We've been building LUTs for the past 10 or so years and have created some of the most popular LUTs in the world. In this post we'll go over the pros and cons of using LUTs, show you the difference between a good and a bad lookup table and walk you through different ways of rolling your own. So without further ado, let's get the basics out of the way:
What the LUT?
3D LUTs are small files that can express a large variety of color transforms and effects. They can be loaded into almost all photo and video editing applications and work across all platforms - mobile, desktop, Mac and PC.
- LUTs make it easy to apply a wide variety of non-local color effects. These are all effects that don't target image regions based on pixel location (such as vignetting, embossing, cropping, sharpening etc) but instead all regions based on color (such as exposure, curves, HSL controls etc)
- They can save you a lot of time. Because they let you apply the same exact transform to multiple shots with just one click instead of having to manually adjust the transform for each individual image or video clip.
- They allow you to create incredibly detailed analog film emulations and other data-driven color grading transforms that are insanely hard or impossible to achieve with UI based tools.
LUTs can be created in a number of different ways. It doesn't have to be complicated and there are some tools that make the process easier than others.
The two most popular methods are using software like Adobe Photoshop that have a LUT export feature or using dedicated LUT creators like Photon. We'll look at both methods in detail in a moment. But first, I'd like to tell you a little more about what it is that makes LUTs so powerful and useful.
- LUTs are platform and software independent. You can create a LUT from a color grade in Photoshop and apply it in Adobe Premiere, Davinci Resolve or even Lightroom - and vice versa.
- LUTs do not have to be generated with user interface driven software like Photoshop or Photon. Real Film Emulation LUTs (the good ones) are created programmatically from data samples. These LUTs can contain incredibly detailed color transformations that are impossible or very hard to achieve with user-interface driven software.
Lookup Tables store all of their color transforms as numerical data points. These points are arranged in an array of numbers. The number of points in the array is referred to as the point-density of the LUT. The more points the larger the LUT file. More points doesn't necessarily mean higher quality though as more data points can lead to signal noise when the LUT has not been created with great care.
Great LUTs will usually give very smooth and predictable color changes whereas LUTs with a low signal-to-noise ratio (like many LUTs you'll find on the internet) will usually display much more "jittery" color changes. A properly created LUT is able to bend colors with accuracy and precision while retaining color smoothness all the way through the gamut.
So how do you create a LUT? There are a few different ways depending on what kind of LUT you are trying to create. We'll cover some of them here. First, we are going to create a simple RGB LUT using some adjustment layers in Adobe Photoshop.
How to create a LUT
To create a LUT in Adobe Photoshop we first want to open an image that we use as a reference for our color changes. I am using this Photo by Jessica Favaro on Unsplash. I think it's a great shot but there's room for improvement on the color grade.
Next, we are going to add three separate adjustment layers: Curves, Hue and Saturation and Color Lookup. The purpose of these layers is to make multiple adjustments to our preview image that we are going to bake into a single LUT later. We will then be able to use these effects in any other software that can load our LUT.
Here are the settings I apply:
With these changes applied our image now looks a little punchier. The "Crisp Warm" LUT I applied from the default stock selection also warms the image a little bit.
Now that I'm pretty happy with the result we can go to File -> Export -> Color Lookup Table.
In the popup window we can dial in some technical properties for the LUT we want to export. I'll choose 32 as the size for our LUT as that is more than enough for the simple adjustments we made.
Remember that LUTs are data cubes so size 32 means that our LUT will have 32x32x32 points. That's 32.768 RGB tuples or 98.304 individual RGB values with floating point precision. That's more than enough for this simple grade. We can now apply this exact look to a video in Adobe Premiere, Final Cut Pro or import it to color grade a game environment in Unreal Engine thanks to the generic cube format of our LUT.
While the generic cube format allows us to use our LUT pretty much anywhere and render our grade in real-time, the flipside of the coin is that we can't just open it back up in Photoshop and change our settings. Our LUT no longer has any reference to the software or effects that created the color transforms it contains. We can still make changes to our LUT though, we just need a different approach.
How to edit LUTs manually
LUTs work like any other image processing effect in that they take an input and produce an output. The LUT itself describes how the input colors are transformed to produce a specific output. So if we have an existing LUT that we want to modify we have a couple of options. Let's start by repeating something we already did when we created our basic LUT in Photoshop above. One of the adjustment layers we used to create our LUT was - a Color Lookup! By combining this Color Lookup adjustment with our Curves and HSL adjustments we essentially "edited" an existing LUT and exported it as our own. Now if we wanted to make adjustments to our custom LUT we could approach it very similarly.
Theoretically we could re-open our preview image in Photoshop. We'd use the same ungraded image from before. Next, we would add a Color Lookup adjustment and import our custom LUT. Now if we wanted to edit this LUT we would just add additional adjustment layers below or above it to change the signal going into the LUT (adjustment layer below) or coming out of the LUT (adjustment layer above).
Now here's a really important thing you should understand about LUTs and image processing in general. The way layers (and nodes for the Resolve crowd) work is that they take an input image and transform that input to produce a different output. That's why adding adjustments before and after the LUT will produce different results. Adjustments before the LUT will change the input image that goes into the LUT while adjustments after the LUT will change whatever the LUT outputs.
In this case I want to make three adjustments to our LUT:
- Make it a little brighter
- Decrease the saturation of bright colors
- Increase the saturation of unsaturated colors
The first step could easily be done in Photoshop. We could add an Exposure adjustment layer and increase the brightness a little bit.
Now, Steps 2 and 3 are a little more involved as Photoshop doesn't give us a simple way to target saturation relative to brightness or to itself. Photoshop is primarily an image editing software. When it comes to LUTs, instead of thinking about our adjustments as "image adjustments" we should learn to think about them as "data adjustments". In other words: We need to adjust the color transform data instead of the image data. And there are tools much better suited for this kind of work that will make our lives much easier.
The better way to create and edit LUTs
Here we can see all of the data points in our LUT distributed nicely in 3D space. The interface is layed out such that dark colors are at the bottom, bright colors at the top, grey axis in the center and saturated colors on the outside. It's basically our color cube but arranged into a drop-shaped geometry that helps a great deal with color smoothness.
So to make our LUT brighter we select the "Lightness and Saturation" tool at the top left of the 3D color model. Then we can simply click and drag upwards to make the LUT brighter. Easy peasy.
Next we want to target bright colors only and decrease their saturation. We'll do this with the Saturation Mode by selecting the ring icon at the bottom of the 3D color model. With Saturation Mode selected we click on the upper end of the color model and drag inwards. Remember the center of the model is the grey axis so the closer colors are to the center the less saturated they become.
Now we simply click and drag on the upper end of the model so we are affecting bright colors more than dark colors. That gives us exactly what we want. We can see in our preview image that our whites are nice and clean now.
Now for step 3 where we want to increase saturation of unsaturated colors, we simply place our cursor in the center of the color model and drag outwards, away from the grey axis.
Other types of LUTs
So far we've looked at manual, user-interface driven ways to create LUTs. While it's great that we can use LUTs to share adjustments between different applications, UI created LUTs are also bound to the limitations of the user interfaces of the software that we use to create them. That's not a bad thing per se. It just is what it is. But because LUTs are just storage containers for data points, they can do more than just express baked color grades.
Film Emulation LUTs
You've probably heard of or even used LUTs that emulate (or claim to emulate) analog film. Film is an interesting medium that is physically completely different from digital and thus has an inherently distinct response to light. It's impossible to accurately model a film color response with the tools in most image editing or color grading applications. These tools are designed for great user experience of high level image adjustments. Film emulation usually involves the scanning and sampling of a large amount of individual colors (up to 30.000 for VisionColor ImpulZ) of a specific film stock.
Every reference color is printed to the film negative and then read back to determine how that particular stock renders that specific color. The results are stored in color lookup tables that emulate the color response of the film stock with a very high degree of accuracy. The entire process is a little more involved but that's the gist.
AI Generated LUTs
Another application where LUTs can be used to store data that makes little to no sense in a user interface context is what we're doing with Match. Match can estimate color grades including film-like non-linear gamut pathways by segmenting and understanding the color composition of natural images.
Under the hood Match computes image statistics in different color spaces, uses unsupervised machine learning to derive transform weights and plot splines through the color gamut and ultimately generates 3D LUTs from the best match candidates. This is another great use case for LUTs that store color transform information that can not be 1:1 represented by traditional interface tools.
And that wraps up this post. We'll cover more use cases of LUTs in the future. I really want to talk about the importance of interpolation and data smoothness and look at different ways to visualize LUTs but also address practical use cases like "How do I install LUTs on my camera?" or "How to work with LUTs in Unreal Engine". Until then - happy color grading!