Spectral Rendering in a Non-Spectral Renderer:
How Can we Author and Render Fluorescence in RGB?
Laurent Belcour

Alban Fichet

Pascal Barla

More Fluorescence

A Fluorescent Material Model for Non-Spectral Editing & Rendering
Thursday 9am - 10:30am
West Building, Rooms 301-305

Fluorescence

https://revealnature.co.uk/2025/02/15/biofluorescence-in-mammals-green-platypuses-pink-hedgehogs/
Under daylight - image from Reveal Nature
https://www.photonews.ca/exploring-fluorescent-nature/
Under spot light - image from Don Komarechka
https://nightsea.com/nature/minerals/sodalite-fluorescence/
Under white light - image from nightsea.com
https://www.leica-microsystems.com/science-lab/life-science/multicolor-microscopy-the-importance-of-multiplexing/
All bands - image from Leica Microsystems
image from Tough Duck

Physics of Fluorescence

  • Absorption and re-emission of light by atoms/molecules

Physics of Fluorescence

  • A common description: the re-radiation matrix
$$ \mathcal{R}(\lambda_i, \lambda_o) = $$
$\lambda_i$
$\lambda_o$

Physically based Fluorescence

  • Re-radiation has two components
    • Diagonal: traditional albedo
    • Off-Diagonal: fluorescence

  • Cannot re-radiate at smaller wavelengths
    • Photon energy inversely proportional to wavelength

  • Energy conservation
$$ \mathcal{R} = $$
Cannot re-radiation $\Delta E > S_2-S_0$
$\rightarrow {\color{orange}\lambda_o} \geq {\color{purple}\lambda_i}$
$$\int \mathcal{R}(\lambda_i, \lambda_o) \mbox{d}\lambda_o \leq 1$$
$$\lambda_i$$

Spectral Rendering with Fluorescence

  • Requires an additional sampling step

					Spectrum Li(Ray ray, Sampler sampler)
					{
						/* Intersect scene with ray and obtain surface BSDF */
						BSDF bsdf;

						/* Only highlighting BSDF sampling strategy */
						[...]
						
						// Sample the outgoing direction
						ray.wo = bsdf.sample(ray.wo, sampler);

						// Sample the outgoing wavelength
						// Consumes one random number
						ray.wavelength = bsdf.rerad.sample(ray.wavelength, sampler);

						return Li(ray, sampler)
					}					
					
[Mojzik et al. 2018]

RGB Rendering with Fluorescence

reduced matrix
light source
material
color matching functions

Spectral Reduction of Fluorescence

  • Analytic if up and down are linear operators
    • We can use the XYZ CMFs ${\color{green} s_i}$ and their duals ${\color{blue}\tilde s_i}$ as a basis

  • Baked prior to rendering
    • For measured data, simple a two matrix products
$$ F_{kl} = \iint {\color{green} s_k(\lambda_o)} \; \mathcal{F}(\lambda_i, \lambda_o) \; {\color{blue} \tilde{s}_l(\lambda_o)} \; \mbox{d}\lambda_i \, \, \mbox{d} \, \lambda_o $$

								def ReduceRerad(R: np.array):
									S  = CMF('XYZ_CIE_2006.csv')      													# (N,3)
									Sb = np.linalg.pinv(S @ S.T) @ S  													# (N,3)
									
									r = S.T @ R @ Sb                  													# (3,3)
									return r
							

Spectral Reduction of Fluorescence

  • Analytic if up and down are linear operators
    • We can use the XYZ CMFs $s_i$ and its dual $\tilde s_i$ as a basis

  • Baked prior to rendering
    • For measured data, simple a two matrix products
    • Parametric models are better with analytical integration

Spectral Reduction: Example on Measured Data

  • First: Upscale data to the CMFs density
    • Scaling must preserve energy!
    • Different interpolation weights between $\lambda_i$ and $\lambda_o$

HERPICER
10 nm per band

Interpolated data
1 nm per band

Reduced matrix $R$

Spectral Reduction: Example on Measured Data

  • First: Upscale data to the CMFs density
    • Scaling must preserve energy!
    • Different upscale between $\lambda_i$ and $\lambda_o$

  • Second: direct illumination computation
    • Multiply matrix with light triplet: $\mathbf{c} = R \times \mathbf{l}$


						Color DirectLi(Ray ray, Sampler sampler)
						{
							/* Intersect scene with ray and obtain surface BSDF */
							BSDF bsdf;

							/* Direct illumination only samples the light */
							Color l = sample_light(ray.wo, ray.p, sampler);

							/* Matrix multiplication using HLSL syntax */
							Color li = mul(bsdf.rerad, l);
							return li;
						}					
						
RGB Rendering - Reduced
Spectral Rendering

Spectral Reduction: Basis

  • Using more than three channels for UVs


350nm emission

RGB Rendering - Reduced
Spectral Rendering
RGBU Rendering - Reduced with UV
no overlap

Reduction and Light Transport

  • How to use reduced matrices in path tracing?


$T = \begin{bmatrix}1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}$
$T_1 = T \times R$
$\mathbf{c} = T_n \times \mathbf{l}$

Reduction and Light Transport

  • How to use reduced matrices in path tracing?

  • Change ray payload to store matrices
RGB Rendering - Reduced
Spectral Rendering
RGBU Rendering - Reduced

Authoring Assets

  • What workflow to texture fluorescence?
    • Can't paint with reduced matrices
    • Not one workflow, depends on usage

Authoring Assets: Black Light

  • Requires an RGBU rendering pipe

  • Model the re-radiation as a separable function
$$ = $$
$$ \times $$
Reradiation
Absorption
Emission
$$ \mathcal{R}(\lambda_i, \lambda_o) = \mathcal{A}(\lambda_i) \times \mathcal{E}(\lambda_o) $$

Authoring Assets: Black Light

  • Requires an RGBU rendering pipe

  • Model the re-radiation as a separable function
$$ \mathcal{R}(\lambda_i, \lambda_o) = \mathcal{A}(\lambda_i) \times \mathcal{E}(\lambda_o) $$
$$ R_{jk} = \int \mathcal{A}(\lambda_i) \tilde{s}_{j}(\lambda_i) \mbox{d}\lambda_i \times \int \mathcal{E}(\lambda_o) s_{k}(\lambda_o) \mbox{d}\lambda_o $$
$$ R =\mathbf{a} \times \mathbf{e}^T $$

Authoring Assets: Black Light

  • Requires an RGBU rendering pipe

  • Model the re-radiation as a separable function
    • Reduction is split


Albedo: #ffffff
UV Fluo: #000000
UV
E

Authoring Assets: Parametric Model

  • Using a palette interface
    • Exposes the parametric model's parameters
Reradiation
Palette - illuminant E
Rendering
Fluo strength
Albedo

Authoring Assets: Parametric Model

  • Expose the parameters directly
    • Pros: easy to map textures
    • Cons: unintuitive editing mode
illuminant E
illuminant UV

Authoring Assets: Optimization Based

  • Provide a target appearance
    • Per pixel optimization to obtain parameters
    • Starting point: albedo, no fluorescence
3D model
target appearance for D65
target appearance for 450nm
Fluorescence strength
Albedo
Rendering
artist painted
per-pixel optimized

Storing & Filtering Fluorescence

  • Storing fluorescence
    • Reduced RGB matrices → 9 floating point values
    • Alternative: store and manipulate RGB triplets / parametric space

  • Filtering or interpolating fluorescence
    • Use the reduced matrix for interpolation and filtering

Beyond Fluorescence

  • Reduction is a framework for converting spectral appearances
    • Spectral reflectances, iridescence, ...
    • Appearance models are most of the time linear operators

Example: Albedo Matrices

  • What if we reduce spectral reflectances?
$$ R_{kl} = \iint {\color{green} s_k(\lambda_i)} \; {\color{orange} \rho(\lambda_i) \delta(\lambda_i-\lambda_o) } \; {\color{green} \tilde{s}_l(\lambda_i)} \; \mbox{d}\lambda_i\; \mbox{d}\lambda_o $$
$$ R_{kl} = \int {\color{green} s_k(\lambda_i)} \; {\color{orange} \rho(\lambda_i) } \; {\color{green} \tilde{s}_l(\lambda_i)} \; \mbox{d}\lambda_i $$
$${\color{orange} \rho(\lambda) }$$
$$\mathcal{R}(\lambda_i, \lambda_o) = {\color{orange} \rho(\lambda_i) \delta(\lambda_i-\lambda_o) }$$
diagonal only

Example: Albedo Matrices

  • What if we reduce spectral reflectances?

  • What do we gain compared to vector albedo?
    • Way to acheive metamerism without spectral

$light$ $[1,1,1]$ $[0.4,0.5,1]$

Example: Albedo Matrices

  • What if we reduce spectral reflectances?

  • What do we gain compared to vector albedo?
    • Way to acheive metamerism without spectral
    • Avoids locus degeneration for multiple scattering

spectral reference
vector albedo
albedo matrix

RGB Workflow for Spectral Effects

  • Can we author albedo matrices in RGB?
    • Upscale an albedo vector with the dual basis
    • Reduce to a 3D tensor product
    • Re-align data with respect to the white point!

$${\color{orange} \rho(\lambda) }$$
$$ \sum_k {\color{red}\rho_k } \, {s}_k(\lambda)$$
$$ R_{i,j} = \int {\color{green} s_i(\lambda)} \; {\color{orange} \rho(\lambda) } \; {\color{green} \tilde{s}_j(\lambda)} \; \mbox{d}\lambda $$
?
$$ R_{i,j} =\int {\color{green} s_i(\lambda)} \; {\color{red} \left[ \sum_k\rho_k \; {s}_k(\lambda)\right] } \; {\color{green} \tilde{s}_j(\lambda) } \; \mbox{d}\lambda $$
upscale
$$ R_{i,j} = {\color{red} \sum_k\rho_k }\int {\color{green} s_i(\lambda)} \; {\color{red} {s}_k(\lambda) } \; {\color{green} \tilde{s}_j(\lambda)} \; \mbox{d}\lambda $$
$$ R_{i,j} = \sum_k {\color{red} \rho_k} \; { \color{orange} S_{i,j,k} } $$

						def MatrixFromVector(r : Vector):
						# Build a 3D tensor from a triplet basis (3 x 3 x 3)
						R = np.concatenate([
										(S.T @ np.diag(S[:,0]) @ Sb)[..., None],
										(S.T @ np.diag(S[:,1]) @ Sb)[..., None],
										(S.T @ np.diag(S[:,2]) @ Sb)[..., None]
							], axis=-1)
						return R @ r
						

RGB Workflow for Spectral Effects

  • Can we author albedo matrices in RGB?
    • Upscale an albedo vector with the dual basis
    • Reduce to a 3D tensor product
    • Re-align data with respect to the white point!

  • This upsampling avoids chroma locus

  • No metamerism yet!
vector -  
spectral -  
matrix -  

vector -  
spectral -  
matrix -  

vector -  
spectral -  
matrix -  
saturate to wrong color

darken fast

Design Metamers in RGB+UV

  • Metameric blacks [Wyszecki 1958] of reduced matrices
    • Spectra/Matrices as a sum
    • with non-contributing components
$$ \times\; \mathbf{l} $$
$$ = $$
$$ \times\; \mathbf{l} $$
$$ + $$
$$ \times\; \mathbf{l} $$

if $R \times \mathbf{l} = [0, 0, 0]$
$R$ is a metameric black

Design Metamers in RGB+UV

  • Metameric blacks [Wyszecki 1958] of reduced matrices
    • Spectra/Matrices as a sum
    • with non-contributing components

  • How can we generate metameric black matrices?
    • Vectors of $R_b$ are orthogonal to $\mathbf{l}$
$$ R_b \times \mathbf{l} = \mathbf{0} \rightarrow R_b^k \cdot \mathbf{l} = 0 \; \forall k$$

Design Metamers in RGB+UV

$+$
$light$ $[1,1,1]$ $[0.4,0.5,1]$

Design Metamers in RGB+UV

  • Metameric blacks [Wyszecki 1958] of reduced matrices
    • Spectra/Matrices as a sum
    • with non-contributing components

  • How can we generate metameric black matrices?
    • Vectors of $R_b$ are orthogonal to $\mathbf{l}$

  • Still some open research problems
    • How to control this space?
    • What are the associated metameric black spectra?

Summary

  • Fluorescence is a new tool for shading design
    • Enables new appearances
    • Works with both RGB and spectral render pipelines
    • Now with tools for authoring workflows

  • Reduced matrices improve legacy RGB
    • Bring spectral effects in (metamerism, multiple scattering, ...)

  • Goal: create a continuum between render pipelines

Thank You!