# Manuka: Weta Digital's Spectral Renderer

Johannes Hanika, Weta Digital

## Metameric spectra for the XYZ CMF observer

photographed by different cameras

 spectrum XYZ c00 c01 c02 c03 c04 c05 c06 c07 c08 c09 c10 c11

## Metameric spectra for the XYZ CMF observer

photographed by different cameras

 spectrum XYZ c00 c01 c02 c03 c04 c05 c06 c07 c08 c09 c10 c11

## Metameric spectra for the XYZ CMF observer

photographed by different cameras

 spectrum XYZ c00 c01 c02 c03 c04 c05 c06 c07 c08 c09 c10 c11

## Indirect lighting in a renderer

• for a simple single-bounce path $I_r = \int_\mathcal{P} h_p(\mathbf{X}) \int_\Lambda \bar{r}(\lambda) \cdot L_e(\lambda) \cdot G \cdot f_r(\lambda) \cdot G \cdot W(\lambda) \cdot d\lambda d\mathbf{X}$
• we can swap the integrals
• first convert to RGB and then accumulate in an RGB frame buffer
• but RGB rendering: $\underbrace{\int_\Lambda \bar{r}(\lambda) \cdot L_e(\lambda) \cdot f_r(\lambda) d\lambda}_{\scriptsize{\mathsf{\mbox{reflected light in RGB}}}} \neq \underbrace{\int_\Lambda \bar{r}(\lambda) \cdot L_e(\lambda) d\lambda}_{\scriptsize{\mathsf{\mbox{light in RGB}}}} \cdot \underbrace{\int_\Lambda \bar{r}(\lambda) \cdot f_r(\lambda) d\lambda}_{\scriptsize{\mathsf{\mbox{Bsdf in RGB}}}}$
• Ouch!

## Indirect lighting, reflectance in rec709 (1.00, 0.95, 0.90)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES Adobe RGB rec709 spectral
illuminant E white
(whitepoint does not match rec709)

## Indirect lighting, reflectance in rec709 (1.00, 0.95, 0.90)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACEScg Adobe RGB rec709 spectral
illuminant E white
(whitepoint does not match rec709)

## Indirect lighting, reflectance in rec709 (0.97, 0.01, 0.00)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACEScg Adobe RGB rec709 spectral
most saturated red
(gamut mapped to valid reflectance)

## Indirect lighting, reflectance in rec709 (0.96, 0.00, 0.72)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACEScg Adobe RGB rec709 spectral
magenta
(not saturated)

# Thank you for listening!

thanks to the wikihuman project for the digital emily asset used in the skin renders

## Indirect lighting, reflectance in rec709 (1.00, 0.95, 0.90)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
illuminant E white
(whitepoint does not match rec709)

## Indirect lighting, reflectance in rec709 (0.97, 0.01, 0.00)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
most saturated red
(gamut mapped to valid reflectance)

## Indirect lighting, reflectance in rec709 (0.00, 0.86, 0.00)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
saturated green
(gamut mapped to valid reflectance)

## Indirect lighting, reflectance in rec709 (0.00, 0.00, 0.68)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
most saturated blue
(gamut mapped to valid reflectance)

## Indirect lighting, reflectance in rec709 (0.11, 0.09, 0.85)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
softer blue to reduce peaks

## Indirect lighting, reflectance in rec709 (0.00, 0.81, 0.78)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
cyan

## Indirect lighting, reflectance in rec709 (1.00, 0.00, 0.74)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
magenta

## Indirect lighting, reflectance in rec709 (0.96, 0.00, 0.72)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
magenta
(not saturated)

## Indirect lighting, reflectance in rec709 (1.00, 0.89, 0.00)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
yellow

## Indirect lighting, reflectance in rec709 (0.93, 0.06, 0.00)

 #bounces 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 XYZ ACES ACEScg Adobe RGB rec709 spectral
measured spectrum