Skip to main content

Spectral Rendering (Experimental)

Experimental

x.Spectra is off by default. It changes direct lighting of deferred lights only; skylight, GI, emissive and translucency stay RGB.

Unreal Engine X can light the scene spectrally. Every deferred light carries a real emission spectrum (a measured lamp, an approximate lamp family, a Planck blackbody at the light's Temperature, or CIE D65). Surfaces stay RGB in the GBuffer and are upsampled to spectra with a bounded basis that reproduces sRGB exactly under D65, so daylight looks like stock Unreal while sodium, fluorescent or LED lamps shift saturated colours the way real lamps do.

Spectra off
Off (RGB)
Spectra on, D50
On: D50 (horizon daylight, 5000K)

Enable​

Console variableDefaultValues
x.Spectra00 off, 1 noise-free (preintegrated), 2 sampled (4 wavelengths per pixel)
x.Spectra.GamutClamp1Maps out-of-gamut (negative) colours from narrowband lights back into the working gamut at constant luminance; also feeds the GT7 tonemapper
x.Spectra.ExactLuma1Mode 2: noise-free luminance, so wavelength noise is chroma only and luma-based AA (SMAA, TSAA) ignores it
x.Spectra.Debug01 light classification, 2 spectral vs RGB difference, 3 sampling noise, 4 gamut clamp, 5 hero wavelength, 6 RGB reference (A/B)

The developer menu section Unreal Engine X > Spectral Rendering (Experimental) exposes the same settings plus a light inspector: emission plot, sampled-wavelength histogram, a runtime lamp picker and RGB vs spectral swatches for test surfaces.

Authoring lights​

  1. Import the light data from XData/ as Data Tables, each with its matching row struct:

    CSVRow struct
    XDT_SpectralLightLibrary.csv (CIE 015:2018 lamps, CIE daylights)XSpectraLightSpectrumRow
    XDT_SpectralApproximateLightLibrary.csvXSpectraApproximateLightSpectrumRow
  2. On a light component, Spectrum category, pick a row in Spectral Lamp or Spectral Approximation.

  3. Set Intensity as usual. The spectrum is normalised to unit luminance, so Intensity keeps its meaning.

What drives the light​

The rule: Spectral Lamp, then Spectral Approximation, then the fallback.

SourceSpectrumTemperatureLight Color
Spectral LampMeasured, fixed by the rowIgnored (the row's Temperature is a label only)Filters the spectrum
Spectral ApproximationThe row's model: blackbody, daylight, reflected sunlight or RGB LED bandsThe light's Temperature with Use Temperature on, otherwise the row's DefaultTemperatureFilters the spectrum
NeitherPlanck, or D65 with Use Temperature offThe light's TemperatureFilters the spectrum
tip

Keep Light Color white to see a lamp's measured spectrum as it is. Light tint multiplies to it.

How it works​

StepImplementationReference
ObserverCIE 1931 2° via the multi-lobe analytic fit, converted to linear Rec.709 and white balanced to D65, then to the working color spaceWyman, Sloan and Shirley, JCGT 2013
Reflectance upsamplingThree bounded basis spectra (sum to one, each in [0, 1]); RGB round-trips exactly under D65Mallett and Yuksel, EGSR 2019
Noise-free mode (1)Because the upsampling is linear, reflectance x light filter x spectrum collapses to a 3x3x3 tensor per light; BRDF products use preintegrated basis momentsPeters 2025, part 2; spectral primaries
Sampled mode (2)4 stratified wavelengths per pixel, importance sampled by (|r| + |g| + |b|) x spectrum per light, offset per pixel by interleaved gradient noise and per temporal AA phasePeters 2025, part 2; Jimenez, SIGGRAPH 2014
BRDFDiffuse, GGX specular with Fresnel and energy terms and transmission evaluated per wavelengthPeters 2025, part 2
GamutNarrowband lights leave the working gamut; colours are desaturated toward grey at constant luminance after integrationPeters 2025, parts 1 and 3

Compared with the reference overview​

Checked against Christoph Peters' Spectral rendering overview:

TopicPeters 2025Unreal Engine X
Illuminant spectraMeasured lamps (LSPDD, energy labels)CIE 015:2018 lamp library, approximate families, Planck, D65
Reflectance upsamplingFourier sRGB (bounded, wider gamut), textures converted offlineMallett-Yuksel 3-basis (bounded, linear, no texture conversion)
Wavelength sampling4 wavelengths, importance sampled for one scene illuminant4 wavelengths, importance sampled per light
BRDFLambert + Frostbite, spectralUE Default Lit / Two Sided Foliage BxDF, spectral
Global illuminationSpectral path tracingMissing: skylight, GI and emissive stay RGB
Gamut and tonemappingGamut compression, tonemappingConstant-luminance gamut clamp; GT7 tonemapper input/output mapping

Still missing, in order of impact:

  1. Spectral indirect light. Skylight, reflection captures, GI (DFGI Lite) and emissive are RGB.
  2. Fourier sRGB upsampling. The 3-basis upsampling is exact under D65 but its spectra are smooth; saturated colours under narrowband lamps change less than with Fourier sRGB.
  3. Translucency and forward lights. Only the deferred light loop is spectral.
  4. Larger measured lamp library (LSPDD).

References​

  • C. Peters, Spectral rendering, parts 1-3, 2025.
  • I. Mallett and C. Yuksel, "Spectral Primary Decomposition for Rendering with sRGB Reflectance", EGSR 2019.
  • C. Wyman, P.-P. Sloan and P. Shirley, "Simple Analytic Approximations to the CIE XYZ Color Matching Functions", JCGT 2013.
  • CIE 015:2018, Colorimetry, 4th edition (illuminants and lamp spectra).
  • J. Jimenez, "Next Generation Post Processing in Call of Duty: Advanced Warfare", SIGGRAPH 2014 (interleaved gradient noise).
  • Spectral primaries (preintegrated basis products).