Skip to main content
ColorGrading is used to transform (either to modify or correct) the colors of the HDR buffer rendered by Filament. Color grading transforms are applied after lighting, and after any lens effects (bloom for instance), and include tone mapping.

Overview

The ColorGrading object provides comprehensive control over the appearance of rendered images through a series of color transformations applied in a specific order. These transformations range from basic exposure adjustments to advanced controls like ASC CDL color grading.

Creation and Usage

A ColorGrading object is created using the ColorGrading::Builder and destroyed by calling Engine::destroy(const ColorGrading*). A ColorGrading object is meant to be set on a View.
filament::Engine* engine = filament::Engine::create();

filament::ColorGrading* colorGrading = filament::ColorGrading::Builder()
    .toneMapping(filament::ColorGrading::ToneMapping::ACES)
    .exposure(1.0f)
    .contrast(1.2f)
    .build(*engine);

myView->setColorGrading(colorGrading);

engine->destroy(colorGrading);

Transform Order

The various transforms held by ColorGrading are applied in the following order:
  1. Exposure
  2. Night adaptation
  3. White balance
  4. Channel mixer
  5. Shadows/mid-tones/highlights
  6. Slope/offset/power (CDL)
  7. Contrast
  8. Vibrance
  9. Saturation
  10. Curves
  11. Tone mapping
  12. Luminance scaling
  13. Gamut mapping

Quality Levels

QualityLevel

When color grading is implemented using a 3D LUT, the quality level impacts the resolution and bit depth:
  • LOW - 16x16x16 10-bit LUT
  • MEDIUM - 32x32x32 10-bit LUT (default)
  • HIGH - 32x32x32 16-bit LUT
  • ULTRA - 64x64x64 16-bit LUT

LutFormat

  • INTEGER - 10 bits per component (default)
  • FLOAT - 16 bits per component (10 bits mantissa precision)

Builder Methods

Quality and Format

quality()

Builder& quality(QualityLevel qualityLevel) noexcept;
Sets the quality level of the color grading. This overrides the values set by format() and dimensions().

format()

Builder& format(LutFormat format) noexcept;
Sets the texture format of the 3D LUT. This overrides the value set by quality().

dimensions()

Builder& dimensions(uint8_t dim) noexcept;
Sets the dimension of the LUT. The value must be between 16 and 64.

Tone Mapping

toneMapper()

Builder& toneMapper(ToneMapper const* toneMapper) noexcept;
Selects the tone mapping operator to apply to the HDR color buffer. The default is ACESLegacyToneMapper.

luminanceScaling()

Builder& luminanceScaling(bool luminanceScaling) noexcept;
Enables or disables the luminance scaling component (LICH) from the exposure value invariant luminance system (EVILS). When enabled, pixels with high chromatic values will roll-off to white for a more natural rendering.

gamutMapping()

Builder& gamutMapping(bool gamutMapping) noexcept;
Enables or disables gamut mapping to the destination color space’s gamut. When enabled, out-of-gamut colors are brought back in gamut while preserving perceived chroma and lightness.

Basic Adjustments

exposure()

Builder& exposure(float exposure) noexcept;
Adjusts the exposure in EV stops. Each stop brightens (positive) or darkens (negative) the image by a factor of 2. Parameters:
  • exposure - Value in EV stops. Can be negative, 0, or positive.

nightAdaptation()

Builder& nightAdaptation(float adaptation) noexcept;
Controls the amount of night adaptation to replicate low-light conditions as perceived by human vision. In low-light, peak luminance sensitivity shifts toward blue, darker tones appear brighter, and colors are blue-shifted. Parameters:
  • adaptation - Amount of adaptation, between 0 (no adaptation) and 1 (full adaptation).

whiteBalance()

Builder& whiteBalance(float temperature, float tint) noexcept;
Adjusts the white balance to remove color casts or alter chromaticity. Parameters:
  • temperature - Modification on the blue/yellow axis. Range: -1.0 to +1.0 (where -1.0 = 50,000K, +1.0 = 2,000K)
  • tint - Modification on the green/magenta axis. Range: -1.0 (green) to +1.0 (magenta)

Advanced Color Controls

channelMixer()

Builder& channelMixer(
    math::float3 outRed, 
    math::float3 outGreen, 
    math::float3 outBlue) noexcept;
Modifies each output color channel using the specified mix of source channels. Parameters:
  • outRed - Mix of source RGB for output red channel (range: -2.0 to +2.0)
  • outGreen - Mix of source RGB for output green channel (range: -2.0 to +2.0)
  • outBlue - Mix of source RGB for output blue channel (range: -2.0 to +2.0)
Example - Sepia tone:
.channelMixer(
    {0.255f, 0.858f, 0.087f},  // outRed
    {0.213f, 0.715f, 0.072f},  // outGreen
    {0.170f, 0.572f, 0.058f}   // outBlue
)

shadowsMidtonesHighlights()

Builder& shadowsMidtonesHighlights(
    math::float4 shadows, 
    math::float4 midtones, 
    math::float4 highlights,
    math::float4 ranges) noexcept;
Adjusts colors separately in three distinct tonal zones with smooth transitions. Parameters:
  • shadows - Linear RGB color (.rgb) and weight (.w) for shadows
  • midtones - Linear RGB color (.rgb) and weight (.w) for mid-tones
  • highlights - Linear RGB color (.rgb) and weight (.w) for highlights
  • ranges - Defines zone transitions (.xy = shadows to mid-tones, .zw = mid-tones to highlights)

slopeOffsetPower()

Builder& slopeOffsetPower(
    math::float3 slope, 
    math::float3 offset, 
    math::float3 power) noexcept;
Applies ASC CDL (American Society of Cinematographers Color Decision List) controls. Similar to lift/gamma/gain controls. Parameters:
  • slope - Multiplier of input color (must be > 0, equivalent to gain)
  • offset - Added to input color (can be negative or positive, equivalent to lift)
  • power - Power exponent of input color (must be > 0, equivalent to gamma)
Performed in log space.

contrast()

Builder& contrast(float contrast) noexcept;
Adjusts image contrast. Lower values decrease contrast (narrow tonal range), higher values increase it (widen tonal range). Parameters:
  • contrast - Range: 0.0 to 2.0. A value of 1.0 has no effect.
Performed in log space.

vibrance()

Builder& vibrance(float vibrance) noexcept;
Adjusts saturation based on input color’s saturation level. High saturation colors are less affected than low saturation colors. Parameters:
  • vibrance - Range: 0.0 to 2.0. A value of 1.0 has no effect.
Performed in linear space.

saturation()

Builder& saturation(float saturation) noexcept;
Adjusts color intensity uniformly. Parameters:
  • saturation - Range: 0.0 to 2.0. A value of 1.0 has no effect.
Performed in linear space.

curves()

Builder& curves(
    math::float3 shadowGamma, 
    math::float3 midPoint, 
    math::float3 highlightScale) noexcept;
Applies a curve to each RGB channel. Parameters:
  • shadowGamma - Power value for shadows (must be > 0)
  • midPoint - Where shadows stop and highlights start (must be > 0)
  • highlightScale - Scale factor for highlights (any value)
Performed in linear space.

outputColorSpace()

Builder& outputColorSpace(const color::ColorSpace& colorSpace) noexcept;
Sets the output color space. Currently must be one of:
  • Rec709-sRGB-D65
  • Rec709-Linear-D65
Only the transfer function is taken into account.

Default Values

  • Exposure: 0.0
  • Night adaptation: 0.0
  • White balance: temperature 0, tint 0
  • Channel mixer: red , green , blue
  • Shadows/mid-tones/highlights: shadows , mid-tones , highlights , ranges
  • Slope/offset/power: slope 1.0, offset 0.0, power 1.0
  • Contrast: 1.0
  • Vibrance: 1.0
  • Saturation: 1.0
  • Curves: gamma , midPoint , scale
  • Tone mapping: ACESLegacyToneMapper
  • Luminance scaling: false
  • Gamut mapping: false
  • Output color space: Rec709-sRGB-D65

Performance Considerations

Creating a new ColorGrading object may be more expensive than other Filament objects as a LUT may need to be generated. The generation of this LUT, if necessary, may happen on the CPU.

See Also

  • ToneMapper - Tone mapping operators
  • View - Apply color grading to a view

Build docs developers (and LLMs) love