Clone wiki

ART / Luts


Working with LUTs

ART has inherited from RawTherapee the support for creative 3D LUTs in the form of Hald CLUTS, available in the Film Simulation tool. Starting from version 1.16, however, the support for LUTs has been significantly enhanced, thanks to the use of OpenColorIO v2 (OCIO for short). In particular, now ART supports also ACES CLF LUTs, which can be used to encode various powerful and flexible pixel-level operations. Specifically, by enabling OCIO (setting ENABLE_OCIO to True in CMake), CLF LUTs can be used not only in the "film simulation" module, but also in the the "color/tone corrections" module.


Despite the name, CLF LUTs are not simply look-up tables, but can encode a sequence of different pixel-level operations, including matrix multiplications, ASC CDL operations, and per-channel transfer functions. What this means is that they are well suited to be applied in a scene-referred workflow, e.g. to implement "look transforms" or also "output transforms" (i.e. tone mapping operations from scene to display/output). For example, now it is possible to apply ACES output transforms directly in ART, or even color grade pictures using look+output LUTs developed for high-end professional cinema cameras.

The only thing needed is to convert such LUTs to CLF and combine them with the appropriate color space conversions to/from ACES 2065-1 (which is the color space used by ART to apply CLF LUTs), all of which can be done with OCIO tools and a little bit of scripting.

Generating ART-compatible CLF LUTs

The OCIO distribution comes with ociomakeclf, a command-line tool to convert many LUT formats to CLF. Conveniently, ociomakeclf can also perform color space conversions from the space required by the LUT to ACES 2065-1, which is what ART assumes, via the --csc parameter.

For many "creative-type" LUTs, which do not change the color space of the input image, invoking ociomakeclf with the appropriate value for --csc is all that is needed. For example, converting one of the ARRI Look LUTs in LogC3 space to CLF in ACES 2065-1 can be done by using --csc ARRI_ALEXA-LOGC-EI800-AWG, whereas for RED Creative LUTs, instead, --csc RED_LOG3G10-RWG should be used.

The process is a bit more involved for LUTs that also perform color space conversions of their inputs, such as the LUTs used to implement output transforms in various scene-referred pipelines typically used in video editing such as ACES. In this case, the steps needed are as follows:

  1. Generate a CLF LUT for converting from ACES 2065-1 to the input format expected by the LUT;
  2. Convert the LUT to CLF via ociomakeclf, but without any color space conversion;
  3. Generate a CLF LUT for converting from the output format produced by the LUT;
  4. Combine the three LUTs above into a single one.

For example, the current output transform candidates for ACESv2 take as input an image with ACES AP0 primaries, but logarithmically encoded values using the ACEScct formula. Therefore, in step 1. we need to convert from linear ACES AP0 (i.e. ACES 2065-1) to ACEScct with AP0 primaries, which can be done with the following CLF LUT (let's call it ACES-2065-1_to_ACEScct-AP0.clf):

<?xml version="1.0" encoding="UTF-8"?>
<ProcessList compCLFversion="3" id="1">
  <!-- convert from linear AP0 to ACEScct with AP0 primaries -->
  <Log inBitDepth="32f" outBitDepth="32f" style="cameraLinToLog">
    <LogParams base="2" linSideSlope="1" linSideOffset="0" logSideSlope="0.0570776255707763" logSideOffset="0.554794520547945" linSideBreak="0.0078125" />

For step 3, assuming we want to use the "Rec.709" version of the output transforms (which is suitable for a standard SDR display), we can use the following CLF to convert from Rec.709 with a 2.4 gamma to ACES 2065-1 (let's call it Rec709_to_ACES-2065-1.clf):

<?xml version="1.0" encoding="UTF-8"?>
<ProcessList compCLFversion="3" id="3">
    <Exponent inBitDepth="32f" outBitDepth="32f" style="basicFwd">
      <!-- rec1886 EOTF -->
      <ExponentParams exponent="2.4"/>
    <Matrix inBitDepth="32f" outBitDepth="32f" >
      <!-- Linear Rec.709 to ACES AP0-->
      <Array dim="3 3">
        0.43392843 0.3762503  0.18982151
        0.088802   0.81526168 0.09593625
        0.01775005 0.10944762 0.87280228

Finally, for step 4, we can use this simple Python script to obtain our final result (RESULT.clf):

  $ python ACES-2065-1_to_ACEScct-AP0.clf LUT.clf Rec709_to_ACES-2065-1.clf -o RESULT.clf

If you want to save space, you can also compress RESULT.clf using gzip, and then rename the file to RESULT.clfz:

  $ gzip RESULT.clf && mv RESULT.clf.gz RESULT.clfz

Alternatively, you can also pass the -c flag to to generate a compressed LUT directly. Note though that supporting gzip compression is an ART extension, so the compressed LUTs will probably not work with other OCIO-based apps.


Here are links to some useful tools for working with CLF LUTs.