Spectral Rendering (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.


Enable
| Console variable | Default | Values |
|---|---|---|
x.Spectra | 0 | 0 off, 1 noise-free (preintegrated), 2 sampled (4 wavelengths per pixel) |
x.Spectra.GamutClamp | 1 | Maps out-of-gamut (negative) colours from narrowband lights back into the working gamut at constant luminance; also feeds the GT7 tonemapper |
x.Spectra.ExactLuma | 1 | Mode 2: noise-free luminance, so wavelength noise is chroma only and luma-based AA (SMAA, TSAA) ignores it |
x.Spectra.Debug | 0 | 1 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
-
Import the light data from
XData/as Data Tables, each with its matching row struct:CSV Row struct XDT_SpectralLightLibrary.csv(CIE 015:2018 lamps, CIE daylights)XSpectraLightSpectrumRowXDT_SpectralApproximateLightLibrary.csvXSpectraApproximateLightSpectrumRow -
On a light component, Spectrum category, pick a row in Spectral Lamp or Spectral Approximation.
-
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.
| Source | Spectrum | Temperature | Light Color |
|---|---|---|---|
| Spectral Lamp | Measured, fixed by the row | Ignored (the row's Temperature is a label only) | Filters the spectrum |
| Spectral Approximation | The row's model: blackbody, daylight, reflected sunlight or RGB LED bands | The light's Temperature with Use Temperature on, otherwise the row's DefaultTemperature | Filters the spectrum |
| Neither | Planck, or D65 with Use Temperature off | The light's Temperature | Filters the spectrum |
Keep Light Color white to see a lamp's measured spectrum as it is. Light tint multiplies to it.
How it works
| Step | Implementation | Reference |
|---|---|---|
| Observer | CIE 1931 2° via the multi-lobe analytic fit, converted to linear Rec.709 and white balanced to D65, then to the working color space | Wyman, Sloan and Shirley, JCGT 2013 |
| Reflectance upsampling | Three bounded basis spectra (sum to one, each in [0, 1]); RGB round-trips exactly under D65 | Mallett 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 moments | Peters 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 phase | Peters 2025, part 2; Jimenez, SIGGRAPH 2014 |
| BRDF | Diffuse, GGX specular with Fresnel and energy terms and transmission evaluated per wavelength | Peters 2025, part 2 |
| Gamut | Narrowband lights leave the working gamut; colours are desaturated toward grey at constant luminance after integration | Peters 2025, parts 1 and 3 |
Compared with the reference overview
Checked against Christoph Peters' Spectral rendering overview:
| Topic | Peters 2025 | Unreal Engine X |
|---|---|---|
| Illuminant spectra | Measured lamps (LSPDD, energy labels) | CIE 015:2018 lamp library, approximate families, Planck, D65 |
| Reflectance upsampling | Fourier sRGB (bounded, wider gamut), textures converted offline | Mallett-Yuksel 3-basis (bounded, linear, no texture conversion) |
| Wavelength sampling | 4 wavelengths, importance sampled for one scene illuminant | 4 wavelengths, importance sampled per light |
| BRDF | Lambert + Frostbite, spectral | UE Default Lit / Two Sided Foliage BxDF, spectral |
| Global illumination | Spectral path tracing | Missing: skylight, GI and emissive stay RGB |
| Gamut and tonemapping | Gamut compression, tonemapping | Constant-luminance gamut clamp; GT7 tonemapper input/output mapping |
Still missing, in order of impact:
- Spectral indirect light. Skylight, reflection captures, GI (DFGI Lite) and emissive are RGB.
- 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.
- Translucency and forward lights. Only the deferred light loop is spectral.
- 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).