Film Lab ProTry it free

Open Data · v2.1

No gatekeeping.

Every number our emulation uses — characteristic curves, dye matrices, crosstalk, grain granularity, halation — published in full, with the manufacturer datasheets they came from and an honest account of every approximation we make.

Primary sources

All curve points and measurements are digitized from these manufacturer technical publications:

  • Kodak E-4050 (Portra 400/800)
  • Kodak H-1-40295 (Ektar 100)
  • Kodak F-4017 (Gold 200)
  • Kodak E-4046 (Vision3 500T/250D)
  • Fuji AF3-0221E2 (Velvia/Provia)
  • Fuji AF3-0076E5 (Provia 100F)
  • Fuji AF3-058E3 (Superia 400)
  • Agfa Vista spec sheets / Fujicolor C200 AF3-044E2
  • Ilford HP5+ data sheet 2019
  • Kodak T-Max 3200 H&D curves

density: D (dimensionless)

log_e: log10(lux·seconds)

rms_granularity: sigma_D × 1000 at D=1.0 through 48µm aperture

size_microns: mean crystal diameter

How the emulation works

The complete processing chain, in order, exactly as it runs in your browser. No secret sauce — every step below is traceable to the datasheet numbers published on this page.

1 · Scene-linear decode

Every input is converted to scene-linear light before anything touches it (sRGB gamma removed; RAW and HDR sources stay linear). Film responds to photons, not gamma-encoded pixel values — all physics below happens in linear light.

2 · White balance as optical gains

Temperature and tint are applied as multiplicative per-channel gains BEFORE the characteristic curve — exactly like a color-correction filter on the lens. They are never post-curve additive shifts for measured stocks.

3 · Exposure in the logE domain

The exposure control premultiplies scene light so it moves you along the film’s actual log-exposure axis. Over-bright values are soft-knee compressed into the LUT domain so the shoulder — not a hard clip — rolls off highlights.

4 · Halation before the curve

Bright light scatters through the film base and re-exposes the red-sensitive backing layer. We threshold the highlights in linear light, scatter them with a Gaussian profile (approximating Beer–Lambert diffusion through the gelatin base), and add the energy BEFORE the curve so the toe and shoulder shape the glow realistically. For speed, the scatter field is computed once at 1/6 resolution — one GPU texture fetch per pixel.

5 · Per-channel H&D curves

Each dye layer gets its own 1024-entry lookup table built directly from the published density-vs-logE points, with per-layer speed shifts and toe/shoulder gammas. Middle gray (0.18 scene linear) is pinned per channel — accounting for WB channel multipliers — so brightness stays consistent across stocks.

6 · Orange coupler mask

Color negatives have an integral orange mask (unequal Dmin per channel — e.g. Portra ≈ R 0.20 / G 0.26 / B 0.42 in raw scan space). We embed it as per-channel Dmin offsets before the print stage, producing the characteristic shadow warmth.

7 · The print stage

For negatives, we model the full two-stage photochemical chain: scene logE → negative density → print exposure (printer light K minus density) → print density via the Kodak 2383/2393 curve → transmittance → display. Reversal films skip this — the film IS the final image.

8 · Density-weighted dye crosstalk

Real dyes have unwanted absorptions that scale with the amount of dye formed. A 3×3 crosstalk matrix is applied weighted by local density — stronger in shadows, weaker in highlights — on top of a light (0.18) color-matrix blend.

9 · Metamerism failures

Kodachrome’s K-14 cyan dye absorbs anomalously near 700nm; Velvia has a milder version. We model it as a density-gated hue rotation along the red–cyan axis (quadratic falloff below the density threshold) — the famous warm-shadow shift.

10 · Grain from Selwyn’s law

Grain amplitude comes from the published RMS granularity (σD×1000 at D=1.0, 48µm aperture), rescaled to pixel pitch via Selwyn’s law (σ²×A = constant) and grown with √density around the measurement point. It modulates transmittance in density space — multiplicative, never additive RGB noise — using a pre-computed Poisson crystal field.

Honest approximations

Where we deviate from pure physics — and why. No gatekeeping means admitting the tuning constants too:

  • ·Curve interpolation between datasheet points is cosine-smoothed, not a fitted photochemical model.
  • ·Per-layer toe/shoulder gamma deltas are clamped to 35% strength — full published asymmetry double-compresses after display normalization.
  • ·The orange mask contributes at 40% strength to keep normalization anchors stable.
  • ·The color matrix blends at 0.18 weight since the per-channel LUTs already encode most color character.
  • ·Display normalization anchors the scene working range (logE −2.5 to +1.8) to 0–1, not the full physical Dmin–Dmax.
  • ·Spectral sensitivity is currently reduced to 3-channel luminance weights per stock, not full 31-band spectra — that upgrade is on the roadmap.

Spectral pipeline — 31 bands

Film doesn't see RGB. Each emulsion layer integrates the scene's full spectrum against its own sensitivity curve — so we model color the same way: 31 wavelength bands from 400 to 700nm, under CIE D65.

01

RGB → 31-band metamer

Scene-linear RGB is uplifted to a full reflectance spectrum (400–700nm, 10nm steps): a smooth partition-of-unity seed basis, corrected so the reconstructed spectrum — integrated through the CIE 1931 standard observer under D65 — round-trips exactly to the input color. The film sees a physically consistent metamer, not an arbitrary spectrum.

02

Weight by illuminant

Each band is weighted by the CIE D65 daylight spectral power distribution — the light the emulsion actually integrates, not an abstract RGB triplet.

03

Integrate per emulsion layer

The spectrum is integrated against each dye-forming layer’s spectral sensitivity curve, fitted as Gaussian lobes to the manufacturer’s published spectrograms. B&W stocks use one panchromatic curve — so colored subjects render through the film’s true gray mapping.

04

Collapse to an exact 3×3

Every step is linear, so the whole chain reduces — without approximation — to a per-stock 3×3 spectral exposure matrix applied before the characteristic curves. Full 31-band fidelity at zero per-pixel cost. Rows are normalized so neutral stays neutral; only the cross-channel shape survives.

Spectral sensitivity — Kodak Portra 400

400nm700nm

Per-layer curves (normalized): blue-, green- and red-sensitive dye-forming layers, incl. residual cross-band lobes.

Resulting spectral exposure matrix (row-normalized):

0.9084
0.0731
0.0185
0.0931
0.7976
0.1093
-0.0011
0.2481
0.7530

Diagonal = each layer's response to its own primary; off-diagonals = real spectral overlap between layers.

Print film curves

Negatives are rendered through a real print stock — the second stage of the photochemical chain. Both cinema print curves we support:

Kodak 2383

γ = 2.8 · Dmin 0.06 · Dmax 2.55

-3-11.5log E (lux·s)00.651.31.952.6

Kodak 2393

γ = 3.1 · Dmin 0.05 · Dmax 2.68

-3-11.5log E (lux·s)00.71.42.12.8

The stocks — every measurement

21 measured emulsions. Expand any stock for its full dossier: the H&D curve we digitized, per-layer parameters, matrices, mask, grain, and halation data.

See the data in action

Or verify it yourself — run the live ΔE validation suite on your own device.