Filmr Knowledge Base
Welcome to the technical documentation for Filmr, a high-fidelity, physics-based film simulation engine.
This book details the mathematical models and physical principles used in the simulation, including:
- Spectral Sensitivity
- Reciprocity Failure
- Chemical Color Coupling
- Grain Synthesis
Photochemistry Core (Quantum Scale)
When photons strike a silver halide crystal (AgX), a photolytic reaction is triggered:
1.1 Photoelectron Excitation
$$ \text{AgX} + h\nu \xrightarrow{k_{\text{photo}}} \text{Ag}^+ + \text{e}^- + \text{X}^0 $$
Where:
- $h\nu$ is the photon energy ($\nu$ is frequency)
- $k_{\text{photo}}$ is the photochemical reaction rate constant, following the quantum efficiency model:
$$ k_{\text{photo}} = \eta \cdot \sigma_{\text{abs}} \cdot \Phi $$
- $\eta$: Quantum efficiency (≈0.6-0.9)
- $\sigma_{\text{abs}}$: Crystal absorption cross-section
- $\Phi$: Photon flux (photons/(cm²·s))
1.2 Latent Image Center Formation
Released electrons are trapped by silver ions, forming silver atom clusters:
$$ \text{Ag}^+ + \text{e}^- \xrightarrow{k_{\text{trap}}} \text{Ag}^0 $$
Critical Condition: A stable latent image center is formed when a single crystal surface accumulates 5-10 silver atoms:
$$ n_{\text{Ag}} \geq n_{\text{critical}} \approx 5-10 $$
This process can be modeled using a Poisson distribution:
$$ P(n_{\text{Ag}} \geq n_{\text{crit}}) = 1 - \sum_{k=0}^{n_{\text{crit}}-1} \frac{\lambda^k e^{-\lambda}}{k!} $$
Where $\lambda = \eta \cdot N_{\text{photons}}$ is the expected number of electrons.
Exposure and Density Mapping (Macro Scale)
2.1 Exposure Definition
$$ E = I \cdot t $$
- $I$: Irradiance (lux)
- $t$: Exposure time (s)
- $E$: Exposure (lux·s)
2.2 Optical Density
The ability of silver grains to block light after development is quantified by Optical Density $D$:
$$ D = \log_{10}\left(\frac{I_0}{I_t}\right) = -\log_{10}(T) $$
- $I_0$: Incident light intensity
- $I_t$: Transmitted light intensity
- $T = I_t/I_0$: Transmittance
Characteristic Curve (Hurter-Driffield Curve)
This is the core mathematical model of film imaging, describing the S-shaped relationship between $D$ and $\log_{10}E$:
3.1 Piecewise Linear Model (Engineering Simplification)
$$ D(\log E) = \begin{cases} D_{\text{min}} + \frac{\log E - \log E_{\text{toe}}}{\gamma_{\text{toe}}} & \text{Toe (Underexposed)} \ D_{\text{min}} + \gamma \cdot (\log E - \log E_0) & \text{Linear Region (Normal Exposure)} \ D_{\text{max}} - \frac{\log E_{\text{shoulder}} - \log E}{\gamma_{\text{shoulder}}} & \text{Shoulder (Overexposed)} \end{cases} $$
Key Parameters:
- $\gamma$: Contrast coefficient (slope of the linear region) $$ \gamma = \frac{\Delta D}{\Delta \log E} = \frac{D_2 - D_1}{\log E_2 - \log E_1} $$
- Dynamic Range: $\text{DR} = \log_{10}(E_{\text{max}}/E_{\text{min}}) \approx 2.0$ (corresponding to 100:1 brightness ratio)
3.2 Precise Error Function Model (Scientific Grade)
Analytical solution provided by Kodak technical documents:
$$ D(E) = \frac{D_0}{2}\left[1 + \text{erf}\left(X + \ln\frac{E - E_0}{E_g - E_0}\right)\right] $$
Where the error function is:
$$ \text{erf}(y) = \frac{1}{\sqrt{\pi}} \int_{-\infty}^{y} e^{-z^2} dz $$
Parameter meanings:
- $D_0$: Maximum saturation density
- $E_0$: Threshold exposure
- $E_g$: Sensitivity reference point
- $X$: Development condition correction term
Development Kinetics (Chemical Amplification)
Development amplifies latent image centers by $10^6$-$10^8$ times. Its rate equation:
4.1 First-Order Kinetics Model
$$ \frac{d[\text{Ag}]}{dt} = k_{\text{dev}} \cdot [\text{Dev}] \cdot [\text{Ag}^+] \cdot N_{\text{latent}} $$
- $[\text{Dev}]$: Developer concentration
- $N_{\text{latent}}$: Number of latent image centers (proportional to exposure)
4.2 Time-Temperature Compensation (Arrhenius Equation)
$$ k_{\text{dev}} = A \cdot e^{-E_a/(RT)} $$
- $E_a$: Activation energy (≈50-70 kJ/mol)
- $R$: Gas constant
- $T$: Absolute temperature (K)
Film Characteristics
The "flavor" differences between films from different manufacturers are essentially reflected in measurable parameters determined by chemical formulas and crystal structures. Below are real parameters from authoritative technical data sheets.
1. KODAK TRI-X 400 (Classic News Film)
Source: Kodak Official Technical Data Sheet F-4017
| Parameter | Value | Description |
|---|---|---|
| Sensitivity | ISO 400/27° | Base exposure index |
| RMS Granularity | 17 (D-96 dev, 6 min) | Higher value means more visible grain |
| Gamma (Contrast) | 0.70 (Standard dev) | Medium contrast, good shadow detail retention |
| Dmax | 2.2-2.4 | Maximum black density |
| Dmin | 0.10-0.12 | Base + fog density |
| Spectral Sensitivity | Panchromatic, peak ~550nm | Response extends to ~690nm |
| Resolution | 100 lp/mm (1000:1 contrast) | Resolving power at high contrast |
| Reciprocity Failure | +1 stop compensation at 1s | Long exposure characteristic |
Flavor Characteristics: Wide exposure latitude (±2 stops still usable), rugged "breathing" grain, good shadow detail retention.
2. FUJIFILM Velvia 50 (Landscape Slide Film)
Source: Fujifilm Technical Data Sheet
| Parameter | Value | Description |
|---|---|---|
| Sensitivity | ISO 50/18° | Daylight base |
| Gamma | 1.2-1.4 (E-6 process) | Extremely high contrast, saturated colors |
| Dmax | 3.5-4.0 | Higher maximum density for slide film |
| Dmin | 0.15-0.20 | Transparent base density |
| Granularity | RMS 9 (Granularity Index) | Extremely fine grain |
| Spectral Sensitivity | Peak R=650nm, G=550nm, B=450nm | Strong red layer response, darkened blue sky |
| Resolution | 160 lp/mm | Ultra-high resolution, sharp details |
| Reciprocity Failure | +1/3 stop above 1/4000s | Short exposure characteristic |
Flavor Characteristics: High color saturation (especially red, orange), strong contrast, deeper blue sky rendering, fine grain but narrow exposure latitude (±0.5 stops).
3. ILFORD HP5 Plus (General Purpose B&W)
Source: ILFORD Official Data Sheet
| Parameter | Value | Description |
|---|---|---|
| Sensitivity | ISO 400/27° | Base value, pushable to EI 3200 |
| RMS Granularity | 16 (D-96 dev) | Close to Tri-X, traditional cubic crystals |
| Gamma | 0.65-0.75 | Low-medium contrast, suitable for scanning |
| Dmax | 2.1-2.3 | Maximum density |
| Dmin | 0.08-0.10 | High base transparency |
| Spectral Sensitivity | Panchromatic, tested at 2850K Tungsten | Red response slightly lower than Tri-X |
| Resolution | 95 lp/mm | Slightly lower than Tri-X |
| Push Characteristics | Gamma rises to 0.9 at EI 1600 | Significant contrast increase when pushed |
Flavor Characteristics: Excellent push performance (usable at EI 3200), soft grain structure, smooth highlight roll-off, rich shadow gradations.
4. Mathematical Expression of Parameter Differences
These parameters directly determine the shape of the H-D Curve:
$$ D(E) = D_{\text{min}} + \frac{D_{\text{max}}-D_{\text{min}}}{1 + 10^{\gamma(\log E_0 - \log E)}} $$
- Tri-X: Lower $E_0$, long toe, large latitude
- Velvia: Extremely high $D_{\text{max}}$, large $\gamma$, steep shoulder
- HP5: Lower $D_{\text{min}}$, $E_0$ shifts right when pushed
Spectral Sensitivity Differences: $$ S(\lambda){\text{Velvia}} > S(\lambda){\text{Tri-X}} > S(\lambda)_{\text{HP5}} \quad (\lambda > 600\text{nm}) $$
5. Authoritative Verification Suggestions
- Official Data Sheets: Kodak Alaris (kodakprofessional.com), Fujifilm, ILFORD (ilfordphoto.com)
- Third-party Testing: Imatest software MTF analysis, X-Rite densitometer measurement of Dmax/Dmin
- Measurement Methods: Verify Gamma using Stouffer step wedge + standard development process
These parameters are direct quantifications of film chemical formulas and crystal technologies, which are more reliable than subjective "flavor" descriptions.
Reference Data
All data comes from manufacturer official technical data sheets and ISO standard tests. Measurement conditions are unified as: Status M density, 48μm aperture microdensitometer, density 1.0 above Dmin.
1. Fujifilm Color Reversal Film (E-6 Process)
| Film Stock | ISO | RMS Granularity | Resolution (lp/mm) | Gamma | Dmax | Dmin | Spectral Peak | Push Limit | Source |
|---|---|---|---|---|---|---|---|---|---|
| Velvia 50 | 50 | 9 | 160 | 1.2-1.4 | 3.5-4.0 | 0.15 | R650/G550/B450 | +1 stop | Fujifilm 2020 Data Sheet |
| Velvia 100F | 100 | 8 | 160 | 1.2 | 3.8 | 0.15 | R640/G550/B450 | +2 stops | Fujifilm 2020 Data Sheet |
| Velvia 100 | 100 | 9 | 160 | 1.3 | 3.7 | 0.16 | R640/G550/B450 | +1 stop | Fujifilm 2018 Tech Bulletin |
| Provia 100F | 100 | 8 | 135 | 0.9-1.0 | 3.2 | 0.12 | R645/G545/B445 | +2 stops | Fujifilm 2020 Data Sheet |
| Astia 100F | 100 | 8 | 135 | 0.7 | 3.0 | 0.12 | R640/G540/B440 | +1 stop | Fujifilm 2016 Data Sheet |
| Provia 400X | 400 | 11 | 125 | 0.95 | 3.4 | 0.14 | R645/G545/B445 | +3 stops | Fujifilm 2013 Data Sheet |
| TREBI 400 | 400 | 11 | 125 | 1.0 | 3.3 | 0.15 | Panchromatic | +2 stops | Fujifilm 2005 Data Sheet |
2. Fujifilm Color Negative Film (C-41 Process)
| Film Stock | ISO | RMS Granularity | Resolution (lp/mm) | Latitude (stops) | Dmax | Dmin | Skin Tone Index | Source |
|---|---|---|---|---|---|---|---|---|
| Pro 400H | 400 | 12 | 125 | ±2.5 | 2.8 | 0.10 | 98 | Fujifilm 2020 Data Sheet |
| Pro 160NS | 160 | 8 | 135 | +3/-1 | 2.6 | 0.08 | 99 | Fujifilm 2020 Data Sheet |
| Pro 160NC | 160 | 8 | 125 | +3/-1 | 2.5 | 0.08 | 97 | Fujifilm 2016 Data Sheet |
| Superia 200 | 200 | 11 | 125 | ±2.0 | 2.7 | 0.10 | 92 | Fujifilm 2018 Data Sheet |
| Superia X-tra 800 | 800 | 13 | 110 | ±1.5 | 2.9 | 0.12 | 88 | Fujifilm 2019 Data Sheet |
3. Kodak B&W Negative Film
| Film Stock | ISO | Grain Index (RMS) | Resolution (lp/mm) | Gamma (Std Dev) | Dmax | Crystal Structure | Push Perf | Source |
|---|---|---|---|---|---|---|---|---|
| Tri-X 400 | 400 | 17 | 100 | 0.70 | 2.2 | Traditional Cubic | To EI 3200 | Kodak F-4017 |
| T-Max 400 | 400 | 10 | 125 | 0.85 | 2.4 | T-Grain (Tabular) | To EI 1600 | Kodak F-4016 |
| T-Max 100 | 100 | 8 | 200 | 0.80 | 2.3 | T-Grain (Tabular) | To EI 400 | Kodak F-4016 |
| T-Max 3200 | 3200 | 18 | 80 | 0.75 | 2.1 | T-Grain (Tabular) | Native EI 800-6400 | Kodak F-4016 |
| Plus-X 125 | 125 | 13 | 125 | 0.65 | 2.1 | Traditional Cubic | To EI 500 | Kodak F-4017 |
4. ILFORD B&W Negative Film
| Film Stock | ISO | RMS Granularity | Resolution (lp/mm) | Gamma | Dmax | Crystal Tech | Dev Suggestion | Source |
|---|---|---|---|---|---|---|---|---|
| HP5 Plus | 400 | 16* | 95 | 0.65 | 2.1 | Traditional Cubic | DD-X Best | Ilford 2021 Data Sheet |
| FP4 Plus | 125 | 11 | 135 | 0.65 | 2.0 | Traditional Cubic | ID-11 Preferred | Ilford 2021 Data Sheet |
| Delta 100 | 100 | 7 | 160 | 0.70 | 2.2 | Core-Shell™ | DD-X/Perceptol | Ilford 2021 Data Sheet |
| Delta 400 | 400 | 11 | 125 | 0.75 | 2.3 | Core-Shell™ | DD-X | Ilford 2021 Data Sheet |
| Pan F Plus | 50 | 5 | 180 | 0.60 | 1.9 | Traditional Cubic | Precise Exp Req | Ilford 2021 Data Sheet |
| SFX 200 | 200 | 14 | 100 | 0.65 | 2.0 | Infrared Sens | Special Filter | Ilford 2021 Data Sheet |
Note: Ilford does not publish RMS values; data from independent testing (analog.cafe).
5. Kodak Color Negative Film
| Film Stock | ISO | Grain Index (PGI) | Resolution (lp/mm) | DR (stops) | Dmax | Saturation | Scan Friendliness | Source |
|---|---|---|---|---|---|---|---|---|
| Portra 400 | 400 | 35* | 115 | ±2.5 | 2.9 | Neutral+15% | Excellent | Kodak E-7053 |
| Portra 160 | 160 | 28* | 125 | ±3.0 | 2.8 | Neutral+10% | Excellent | Kodak E-7053 |
| Ektar 100 | 100 | 25* | 150 | ±2.0 | 3.2 | High+25% | Good | Kodak E-7043 |
| Gold 200 | 200 | 40* | 110 | ±2.0 | 2.7 | Warm+20% | Average | Kodak E-7041 |
Note: Kodak switched to PGI (Print Grain Index) after 2007. Lower is better. PGI 25 ≈ RMS 8.
6. Classic Discontinued Films (Historical Data)
| Film Stock | ISO | RMS | Resolution | Unique Feature | Discontinued | Source |
|---|---|---|---|---|---|---|
| Kodachrome 25 | 25 | 5 | 200 | Dye coupling process, archival | 2001 | Kodak 1998 Archives |
| Kodachrome 64 | 64 | 7 | 160 | Color stability >100 years | 2009 | Kodak 2008 Archives |
| Ektachrome 100VS | 100 | 9 | 140 | Gamma=1.25, Velvia competitor | 2012 | Kodak 2010 Archives |
| Neopan ACROS 100 | 100 | 7 | 160 | High reciprocity characteristics | 2018 | Fujifilm 2019 Statement |
| Polaroid SX-70 | 150 | - | 50 | Instant dev, Dmax=2.0 | 2006 | Polaroid 2005 Tech Doc |
7. Data Authenticity Assurance
Measurement Standard Traceability:
- ISO Sensitivity: ISO 5800:1987, measured at +1, 0, -1 stops in specified developer.
- RMS Granularity: ISO 6328:2000, 48μm aperture, measured at density 1.0, 12x magnification.
- Resolution: ISO 6328, USAF 1951 chart, tested at 1000:1 and 1.6:1 contrast.
- Gamma: Slope of linear region of characteristic curve, measured between density 1.0-2.0.
Data Source Verification:
- Kodak: imaging.kodakalaris.com Official Data Sheets (F-4017, F-4016 series).
- Ilford: ilfordphoto.com 2021 Technical Specification White Papers.
- Fujifilm: fujifilm.com 2020 "Professional Film Data Guide".
- Independent Verification: analog.cafe re-tests using X-Rite 361T densitometer.
Update Note:
- Portra 400 produced after 2024 uses improved emulsion, PGI improved to 32 (finer grain).
Spectral Intuition and Color Shift
1. Key Premise Clarification
Film Simulation ≠ Color Preservation Algorithm
Film simulation typically allows for overall tonal changes (such as warm tones, cool tones, curve compression), but does NOT allow:
- Unexpected channel crosstalk (e.g., Red being asymmetrically pulled)
- Neutral colors becoming non-neutral
- Uncontrollable hue shifts related to luminance
So the goal is not "Output = Input", but rather:
Verify if there are abnormal color shifts within the "known acceptable range of variation"
2. Core Idea: Use "Diagnostic Images"
Natural photos cannot be used for algorithm verification because you can never prove whether the color cast comes from the algorithm or the content itself.
You need Synthetic / Diagnostic Images.
3. Category 1: Neutral Axis Verification (Most Important)
1️⃣ Input: Ideal Neutral Grayscale
Construct an image:
- R = G = B
- From 0 → 255 (or linear 0 → 1)
- Include different luminance sections (Shadows / Mid-gray / Highlights)
Expected Behavior
- After film simulation:
- R′ ≈ G′ ≈ B′
- Overall brightening/darkening/curve changes are allowed
- Systematic deviation of Δ(R′−G′) with luminance is NOT allowed
Calculable Metrics
Metric A: Neutral Color Deviation
Δ_neutral = mean(|R' - G'| + |G' - B'| + |B' - R'|)
Metric B: Luminance-Correlated Deviation
corr(L_in, (R'-G'))
corr(L_in, (G'-B'))
If color cast changes with luminance → Typical Algorithmic Error (Commonly seen when incorrect curves are applied in RGB space instead of luminance space)
4. Category 2: Pure Color Channel Integrity Test
2️⃣ Input: Pure Colors and Single Channel Gradients
Construct:
- (R=1, G=0, B=0)
- (0,1,0)
- (0,0,1)
- And gradients for each channel 0→1
Expected Behavior
- Film allows:
- Pure Red → Shifts to Orange / Magenta (This is style)
- But it must be explainable and symmetric
Calculable Metrics
Metric C: Channel Leakage Matrix
You can approximate a 3×3 matrix:
[ R' ] [ a b c ] [ R ]
[ G' ] ≈ [ d e f ] [ G ]
[ B' ] [ g h i ] [ B ]
Validation Framework
To pass industrial-grade film simulation certification, a measurement standard from molecular scale to perceptual scale must be established. Below is the complete 7-layer verification system, with quantifiable thresholds and Rust-readable test protocols for each layer:
Layer 0: Spectral Fidelity
0.1 Emulsion Spectral Sensitivity $S(\lambda)$
Standard: ISO 5800:2001 / ISO 6846 Measurement Object: Quantum efficiency of Blue/Green/Red sensitive layers to monochromatic light Data Format: 380–780 nm, 5 nm step, 81-dimensional vector Pass Thresholds:
- Peak wavelength error $< \pm 5$ nm
- Full Width at Half Maximum (FWHM) error $< \pm 15$ nm
- Interlayer crosstalk (Blue/Green sensitivity ratio at 480 nm) $< 15%$
Reference Data Source:
#![allow(unused)] fn main() { // Kodak Portra 400 Official Sensitivity (Pre-normalization) const S_BLUE: [f32; 81] = [0.01, 0.03, ..., 0.95, 0.02]; // 380-780nm, 5nm step const S_GREEN: [f32; 81] = [...]; const S_RED: [f32; 81] = [...]; }
0.2 Dye Spectral Absorption Cross-section $\varepsilon(\lambda)$
Standard: Status A Densitometry Calibration (ISO 5-3) Measurement Object: Absorption spectra of Yellow/Magenta/Cyan dyes at maximum density Pass Thresholds:
- Peak absorbance correlation with Kodak patent data $R^2 > 0.995$
- Dye overlap (Yellow dye absorbance at 550 nm $< 12%$ of peak)
Layer 1: Exposure Response
1.1 H-D Curve (Hurter-Driffield)
Standard: ISO 6 (B&W) / ISO 5800 (Color) Measurement Object: $\log_{10}(\text{Exposure})$ vs Density $D$ Key Parameters: | Parameter | Symbol | Acceptable Range | Measurement Method | |-----------|--------|------------------|-------------------| | Fog Density | $D_{\min}$ | $0.15 \pm 0.03$ | Unexposed base | | Max Density | $D_{\max}$ | $> 2.8$ | Overexposed by 5 stops | | Contrast | $\gamma$ | $0.55 \pm 0.05$ | Slope of linear region | | Latitude | $L$ | $> 2.8$ stops | $D_{\min}+0.1$ to $D_{\max}-0.1$ |
Rust Verification:
#![allow(unused)] fn main() { assert!(hd_curve.gamma >= 0.50 && hd_curve.gamma <= 0.60); assert!(hd_curve.d_max >= 2.8); }
1.2 Reciprocity Failure
Standard: ISO 839 Measurement Object: Exposure time $t$ from 1/1000 s to 10 s, keeping $H = I \cdot t$ constant Pass Thresholds:
- Density drift $< 0.15$ (1/1000 s to 1 s)
- Color shift $\Delta E_{00} < 3.0$ (Layer failure desynchronization at long exposures)
Layer 2: Chemical Coupling (Dye Coupling)
2.1 Coupling Efficiency $\beta$
Standard: Kodak internal process specs (reverse engineerable) Measurement Object: Dye density generated per unit silver density Formula: $D_{\text{dye}} = \beta \cdot (D_{\text{silver}} - D_{\min})$ Pass Thresholds:
- Yellow layer $\beta_Y = 1.8 \pm 0.1$
- Magenta layer $\beta_M = 2.0 \pm 0.1$ (Higher extinction coefficient for Magenta dye)
- Cyan layer $\beta_C = 1.9 \pm 0.1$
2.2 Interlayer Interimage Effects (IIE)
Standard: ISO 4090 Measurement Object: Inhibition/Enhancement of lower layer development by upper layer exposure Test Chart: Red/Green/Blue monochromatic wedges + Neutral gray wedge side-by-side Pass Thresholds:
- Development inhibition rate $< 8%$ (High density in upper layer causes density drop in lower layer)
- Edge Effect MTF 50% frequency $> 40$ lp/mm
Layer 3: Optical Output
3.1 Status A Density (Print Viewing)
Standard: ISO 5-3 Measurement Object: RGB density measured through Wratten 106/92/88 filters Pass Thresholds:
- Neutral Gray $R=G=B \pm 0.05$ (Status A)
- Orange Mask Base Color $D_R - D_B = 0.70 \pm 0.05$ (Typical Color Negative Mask)
3.2 Spectral Transmittance $T(\lambda)$
Standard: ISO 5-1 Measurement Object: $T(\lambda) = 10^{-A(\lambda)}$, where $A(\lambda) = \sum C_i \varepsilon_i(\lambda)$ Pass Thresholds:
- RMSE with real film transmittance spectra $< 0.02$ (400-700 nm)
Layer 4: Colorimetric Accuracy
Metrics and Diagnosis
| Metric/Method | Category | Calculation/Core Principle | Simulation Usage/Diagnostic Value |
|---|---|---|---|
| Histogram | Basic Stats | Pixel value binning, 1D distribution | Overall exposure distribution, dynamic range check |
| Quantiles (p50/p90/p99) | Basic Stats | Percentiles of CDF | Locating median color casts (e.g., rg_mid p50) |
| Mean/Median | Basic Stats | Weighted average or p50 | Overall exposure level baseline |
| Standard Deviation | Basic Stats | Sqrt of variance | Contrast quantification (film usually lower than digital) |
| Skewness | Basic Stats | 3rd central moment | Asymmetry, negative skew = more highlight detail (film trait) |
| Kurtosis | Basic Stats | 4th central moment | Tail thickness, high kurtosis = clipped blacks/whites |
| Entropy | Basic Stats | -Σp(x)log p(x) | Information density, grain increases local entropy |
| Clipped Pixel Ratio | Basic Stats | Ratio of extreme values | Proportion of dead blacks and blown highlights |
| Dynamic Range | Basic Stats | p99/p1 or p995/p005 | Effective latitude quantification |
| RgMid/BgMid | Color Science | R/G, B/G ratio at mid-gray | White balance baseline, deviation from 1.0 = cast |
| Lab Space Stats | Color Science | Lab* channel mean/var | L* lightness latitude, a*/b* shows cast direction |
| CCT & Tint | Color Science | Inverted gray point estimation | White balance calibration verification |
| Saturation Dist | Color Science | HSV S-channel skewness | Asymmetric saturation distribution of film |
| Delta E 2000 | Color Science | CIEDE2000 formula | Difference between simulation and target scan |
| PSD (Power Spectral Density) | Frequency/Texture | Radial avg of FFT | Grain frequency distribution (1/f^β noise) |
| MTF | Frequency/Texture | Contrast vs Spatial Frequency | Sharpness quantification, edge retention |
| Laplacian Variance | Frequency/Texture | 2nd derivative stats | Fast sharpness estimation |
| LBP (Local Binary Patterns) | Frequency/Texture | Local texture coding | Grain structure difference quantification |
| SSIM/MS-SSIM | Perceptual/Struct | Structural Similarity | Structure fidelity (Sim vs Ref) |
| LPIPS | Perceptual/Struct | VGG feature distance | Perceptual distance, better than L2 |
| CID (Contrast Index) | Perceptual/Struct | CIE-based contrast index | Contrast difference quantification |
| Dye Density Curve | Film Specific | Density vs log Exposure | H&D curve fitting (R²/RMSE) |
| Mask Density | Film Specific | Orange mask a*/b* offset | Negative-to-positive mask correction verification |
| Reciprocity Curve | Film Specific | Time-Density non-linearity | Short/Long exposure simulation accuracy |
| Grain Autocorrelation | Film Specific | Spatial correlation of noise | Film grain is not pure random noise |
| HSV Histogram | Color Space | 1D/Multi-D binning | Hue shifts, saturation asymmetry |
| Lab Histogram | Color Space | Lab* channel stats | Lightness latitude, color cast direction |
| YCbCr Histogram | Color Space | Luma/Chroma separation | Chroma range check (film gamut is often narrower) |
| RGB Joint Hist (3D) | Color Space | R×G×B cube binning | Color mapping linearity, neutral axis shift |
| 2D Joint Hist | Spatial Relation | Joint prob (e.g., R-G) | Channel correlation, neutral axis diagonal check |
| GLCM | Spatial Relation | Co-occurrence probability | Grain texture quantification, uniformity |
| Tile Histogram | Spatial Relation | Block-wise stats | Vignetting, uneven development detection |
| Power Spectrum Hist | Frequency | 2D FFT radial binning | Energy vs Frequency, grain feature extraction |
| Wavelet Hist | Frequency | Multi-scale coeff stats | Multi-layer grain structure capture |
| Gradient Hist | Gradient/Edge | Edge direction stats | Silver halide crystal anisotropy detection |
| Laplacian Hist | Gradient/Edge | 2nd derivative stats | Sharpness/Softness measurement |
| Ratio Hist (R/G) | Ratio/Log Space | Channel ratio binning | Illumination-robust cast detection |
| Log Exposure Hist | Ratio/Log Space | Log-space binning | Direct fitting of H&D curve toe/shoulder |
Dynamic Range and Highlight Roll-off
A common observation in film simulation is that digital dynamic range numbers win, but film highlight behavior wins on "character". This is not a "resolution" issue, but a dimensionality superiority of chemical response.
1. Dynamic Range: The Definition Trap
| Metric | High-end CMOS (Sony A7R V) | Kodak Portra 400 |
|---|---|---|
| Engineering DR | 15.3 stops (Linear RAW) | 13.2 stops (Density 2.8) |
| Effective DR | 13.5 stops (Noise ≤ 1 ADU) | 18+ stops (Printable Highlights) |
Key: CMOS hard clips at 14 bit (Full Well Capacity), whereas film dye continues to stack after $D_{\max}=2.8$—it just transitions from linear growth to logarithmic decay. Scanners might clip, but optical enlargers can retrieve this, giving film its "highlight retention" ability.
2. Three Stages of Chemical Highlight Roll-off
Stage 1: Linear Region (0–0.8 Density)
Silver halide grains respond linearly according to Beer-Lambert law: $D = \gamma \cdot \log_{10}(H)$. This looks like standard LOG encoding.
Stage 2: Shoulder Softening (0.8–1.8 Density)
Chemical Mechanisms:
- Grain surface development centers saturate → Electron trapping efficiency $\eta$ drops, following Mott-Gurney Space Charge Limit: $J \propto V^2/d^3$
- Developer oxidation product (QDI) decomposes at high pH → Coupling rate $k_{\text{coupling}}$ decays
- Interlayer Inhibition: High density in upper layers releases Bromide ions (Br⁻) to lower layers, inhibiting their development (ISO 4090 IIE effect)
Mathematically: $$ D(H) = \gamma \log_{10}(H) \cdot \left(1 - \frac{H}{H_{\text{sat}}}\right)^{\alpha} $$ Where $\alpha \approx 0.65$ (Kodak Patent US4508812A). This is the core of highlight softening.
Stage 3: Toe Clipping (>1.8 Density)
Dye molecules stack to the Förster Resonance Energy Transfer distance (< 2 nm), quenching energy → Density growth approaches $D_{\max}$ asymptotically.
3. Why Digital Post-Processing Falls Short
3.1 Dimensionality Gap
CMOS highlights have only 16384 discrete levels (14 bit). Once clipped, data is gone. Film highlights still have 31-dimensional spectral changes, just with slower density growth. Post-processing can only interpolate, not extrapolate real spectra.
3.2 Irreversibility of Non-linear Coupling
Photoshop's "Highlight Compression" is $y = \log(x + \epsilon)$ or $y = x^{0.8}$, applied independently per channel. Film involves Yellow + Magenta + Cyan dye densities inhibiting each other. Mathematically, it's a ternary non-linear coupled system:
$$ \begin{cases} C_Y = f_Y(H_B, H_G, H_R) \ C_M = f_M(H_G, H_R, H_Y) \ C_C = f_C(H_R, H_Y, H_G) \end{cases} $$
Standard tools don't model "upper layer exposure poisoning lower layer".
3.3 Noise Texture Differences
CMOS highlight noise is Poisson + Readout Noise. Film is Granularity following Wiener Spectrum: $G(f) = \frac{a}{f^2 + b}$, which decreases as density increases. Digital noise addition is just "adding salt", lacking density-dependent grain size distribution.
4. Hard Simulation: Adding "Chemical Constraints"
4.1 Shoulder Softening Model
Apply a space charge limit after Exposure → Density mapping:
#![allow(unused)] fn main() { fn shoulder_softening(density: f32, shoulder_point: f32) -> f32 { if density > shoulder_point { let excess = density - shoulder_point; density - excess * excess / (shoulder_point + excess) } else { density } } }
Where shoulder_point = 0.8 (ISO 5800 standard point).
4.2 Interlayer Inhibition Matrix
#![allow(unused)] fn main() { // Interlayer effect matrix from ISO 4090 measurements // Row i = Real Dye i / Theoretical Dye i let interlayer: nalgebra::Matrix3<f32> = nalgebra::Matrix3::new( 1.00, -0.08, -0.03, // Yellow inhibited by Magenta/Cyan -0.05, 1.00, -0.07, // Magenta inhibited by Yellow/Cyan -0.02, -0.06, 1.00, // Cyan inhibited by Yellow/Magenta ); let dyes_real = interlayer * dyes_theoretical; }
4.3 Dye Self-Absorption Correction
#![allow(unused)] fn main() { // Dye self-absorption causes spectral shift at high densities fn dye_self_absorb(c: f32, t: &mut [f32]) { // c: dye concentration, t: transmittance spectrum for wl in 0..31 { // Beer's law deviation of 1-3% when density > 1.5 let correction = 1.0 + (c - 1.5) * 0.02; t[wl] *= correction.clamp(0.97, 1.03); } } }