Skip to main content
Auric Artisan · Documentation

Standard Illuminants Developer Reference

Architecture and maintenance notes for the standalone Standard Illuminants tool, including the HTML shell, state model, standard illuminant registry, SPD synthesis, CIE colorimetry integration, CRI and metamerism approximations, chromatic adaptation, exports, URL state, public API, and Library binding.

Published: May 24, 2026 Updated: May 24, 2026 Category: Reference Author: Chirag Bansal
Back to Documentation Auric Artisan Home

Overview

Standard Illuminants is implemented as a self-contained browser IIFE in js/tool/illuminants.js. The page shell provides the controls, canvases, actions, and the Reference tab's standards, formulas, citations, and research notes. The JS module owns the 380-780 nm spectral grid, standard illuminant data, blackbody and daylight synthesis, CIE XYZ integration, CRI approximation, surface Delta E output, metamerism comparison, chromatic adaptation preview, exports, URL restore, and window.AAIlluminants integration surface.

Table of contents

  1. 1. File map
  2. 2. Page shell and UI contract
  3. 3. State model
  4. 4. Illuminant registry and SPD generation
  5. 5. Colorimetry pipeline
  6. 6. Rendering, surfaces, and adaptation
  7. 7. Exports, share URL, and events
  8. 8. Public API and library binding
  9. 9. Extension checklist
  10. 10. Testing and risk notes

1. File map

+
  • Tool shell: tool/general/colorimetry/illuminants/index.html contains metadata, hero content, provenance note, tab navigation, controls, canvases, action buttons, the Reference tab's standards, formulas, citations, and research notes, and fullscreen chart overlay.
  • Tool engine: js/tool/illuminants.js contains the standalone IIFE that implements state, spectral data, colorimetry math, rendering, exports, URL restore, and the public API.
  • Colorimetric core and views: js/tool/illuminants/il-tables.js, il-core.js, il-data.js, and il-uncertainty.js load first and expose window.AAIlluminantTables, AAIlluminantCore, AAIlluminantData, and AAIlluminantUncertainty; js/tool/illuminants-views.js builds the Chromaticity, Uncertainty, Methods, Console, Data, and Reference views from them.
  • Library integration: js/library/tool-bindings.js registers the illuminants tool path and also includes runtime state capture/restore hooks for window.AAIlluminants.
  • Generated inline helpers: the page loads generated inline scripts for shared shell behavior, canvas accessibility, and unified interactions.
  • Discovery metadata: documentation pages are indexed from data/documentation.json and then generated into RSS, sitemaps, PWA cache manifest, and search index outputs.

2. Page shell and UI contract

+
  • App root: #il-app wraps the Standard Illuminants application.
  • Tabs: buttons use data-il-tab; panels use p-il-lab, p-il-chroma, p-il-uncert, p-il-methods, p-il-console, p-il-data, p-il-actions (Export), and p-il-reference.
  • Source controls: radio inputs named il-mode select standard or blackbody; il-illum-select stores the selected standard illuminant.
  • CCT controls: il-cct, il-cct-input, il-cct-val, and il-link-cct manage custom CCT and standard-source metadata linking.
  • Comparison controls: il-compare-toggle and il-compare-illum drive the blue SPD overlay and comparison metrics.
  • Surface controls: il-surfaces-toggles stores checkboxes for white, gray, red, green, blue, skin, yellow, and cyan.
  • Adaptation controls: il-adapt-from, il-adapt-to, il-swap-adapt, and radio inputs named il-adapt-model manage Bradford, CAT16, CAT02, Sharp, XYZ scaling, Von Kries, and no adaptation (none).
  • Primary outputs: il-info-panel, il-spd-canvas, il-spd-probe, il-cri-canvas, il-surfaces-output, il-adapt-output, il-matrix-output, and il-compare-output.
  • Action outputs: il-share-url and il-multi-output hold generated share URLs and all-illuminant comparison tables.

3. State model

+

The module-level state object is the single runtime source of truth. Event handlers update state, call syncUI() where controls need to be refreshed, and call refresh() or a focused renderer for outputs.

  • Defaults: mode standard, illuminant D65, CCT 6500, linked CCT enabled, adaptation D65 to D50, model bradford, surfaces white, gray, red, green, and skin, comparison illuminant A, comparison hidden.
  • Mode behavior: changing the CCT slider or number input sets state.mode to blackbody.
  • Illuminant behavior: changing the standard illuminant can update state.cct when state.linkCCT is true and the metadata has a CCT.
  • Surface behavior: the surface checkbox group rebuilds state.surfaceKeys and re-renders only the surface section.
  • Share state: URL restore reads only mode, selected illuminant, CCT, adaptation source, adaptation destination, and adaptation model.
  • API restore: restoreState(saved) merges the saved object into state, syncs UI, and performs a full refresh.

4. Illuminant registry and SPD generation

+
  • Wavelength grid: LAMBDA spans 380 nm through 780 nm in 5 nm increments, producing NL = 81 samples.
  • Standard data object: SPD_DATA stores A, D50, D55, D65, D75, E, and F1-F12 spectra.
  • Illuminant A: generated as a Planckian radiator at 2848 K with the 1931 value of c2 (its CCT is 2856 K), normalized to 100 at 560 nm.
  • Blackbody mode: planck(w, T) and blackbodySPD(T) generate custom CCT spectra and normalize to the spectrum peak.
  • Daylight mode: daylightSPD(T) computes CIE daylight chromaticity, derives M1 and M2, combines S0/S1/S2 basis vectors resampled from their 10 nm table by il-core.js, and normalizes to 100 at 560 nm.
  • Equal-energy source: E is a constant 100 relative power across the wavelength grid.
  • Fluorescent approximations: F1-F12 use fluorGauss(peaks) with Gaussian emission peaks. These are practical approximations for the browser tool, not official normative tables.
  • Metadata: ILLUM_META stores label, type, and CCT for the 18 standard illuminants; ILLUM_KEYS drives the all-illuminant comparison table.
  • Lookup: getSPD(name) returns the named standard spectrum or falls back to D65.

5. Colorimetry pipeline

+
  • Observer data: CMF_X, CMF_Y_CORRECT, and CMF_Z provide CIE 1931 2-degree color matching functions on the same 5 nm grid.
  • SPD to XYZ: spdToXYZ(spd) integrates spectral power against the CMFs and normalizes Y to 100.
  • Chromaticity: xyzToXy(X, Y, Z) derives CIE x and y from XYZ, with D65 fallback for zero sums.
  • CCT: cctFromXy(x, y) uses Ohno's 2014 method from il-core.js (cctDuv()) for correlated color temperature; the old McCamy approximation survives only as legacyCctFromXy() for the Methods tab.
  • Duv: duvFromXy(x, y) returns the signed Duv from the same Ohno solution, measured in CIE 1960 UCS coordinates against a Planckian locus computed from Planck's law.
  • Lab: xyzToLab() uses a D65 reference white and supports surface, CRI, and metamerism differences.
  • Delta E: deltaE00() implements CIEDE2000 and is reused by CRI approximation, surface output, and metamerism comparison.
  • sRGB preview: xyzToSrgb() and rgbToHex() convert normalized XYZ values into clipped display HEX swatches for UI feedback.
  • White points: WHITE_XY stores named CIE white chromaticities for A, B, C, D50, D55, D65, D75, and E. whiteXYZ(name) converts them to Y = 100 XYZ or falls back to SPD integration.

6. Rendering, surfaces, and adaptation

+
  • Refresh: refresh() calls renderInfoPanel(), renderSPDChart(), renderCRIChart(), renderSurfaces(), renderAdaptation(), renderMatrixPanel(), and renderComparison().
  • Canvas setup: setupCanvas(id) sizes canvas buffers for the current device pixel ratio and scales the drawing context.
  • SPD chart: renderSPDChart() draws grid lines, axes, rainbow fill, gold primary trace, optional blue comparison trace, and legend.
  • CRI chart: renderCRIChart() computes CRI for the active source and draws R1-R14 bars with Ra label.
  • CRI computation: computeCRI(spd) estimates reference SPD from CCT, multiplies 14 Gaussian TCS reflectance approximations by test and reference spectra, adapts by simple per-channel scaling, converts to Lab, and derives R values from Delta E.
  • Surfaces: SURFACES stores eight educational reflectance presets. renderSurfaces() multiplies selected surface curves by the active SPD and D65 SPD, adapts to D65, converts to sRGB, and reports Delta E 2000.
  • Comparison: renderComparison() computes CCT, xy, CRI, and average Delta E 2000 metamerism across the 14 TCS approximations when comparison mode is enabled.
  • Adaptation: adaptXYZ() supports Bradford, CAT16, CAT02, Sharp, XYZ scaling, and Von Kries through il-core.js, and none for no adaptation. renderAdaptation() adapts a 24-patch sRGB set from source white to destination white.
  • Matrix output: renderMatrixPanel() prints the active CAT matrix, source and destination LMS values, and destination/source LMS scale factors.
  • Probe: clicking il-spd-canvas maps x-position to wavelength index and writes wavelength, relative power, and visible color chip into il-spd-probe.

7. Exports, share URL, and events

+
  • CSV export: exportCSV() writes wavelength and relative power rows for the active source and downloads *-spd.csv.
  • JSON export: exportJSON() writes active label, CCT, xy, XYZ, CRI, and SPD array.
  • PNG export: exportPNG() uses HTMLCanvasElement.toBlob() on il-spd-canvas.
  • Clipboard: copyWhiteCSS() writes the active white HEX via navigator.clipboard.writeText(). Share URL copy uses the same clipboard API.
  • Share URL builder: buildShareURL() encodes mode, illum or cct, af, at, and am.
  • URL restore: restoreURL() reads those query parameters before the first syncUI() and refresh().
  • Multi comparison: renderMultiCompare() iterates ILLUM_KEYS and writes table rows for CCT, x, y, CRI Ra, and swatch.
  • Keyboard shortcuts: the page documents S for swap, R for reset, C for compare, and E for export CSV. When extending shortcuts, keep input focus behavior in mind.
  • Toast: toast(msg) targets il-toast if present, so missing toast markup is tolerated.

8. Public API and library binding

+
  • Namespace: the tool exposes window.AAIlluminants after boot().
  • getState: returns a JSON-cloned copy of the internal state object.
  • restoreState: validates an object, merges it into state, syncs UI, refreshes outputs, and returns true when applied.
  • Generic binding: js/library/tool-bindings.js has an illuminants path matcher for /tool/general/colorimetry/illuminants/ with id illuminants, name Standard Illuminants, href /tool/general/colorimetry/illuminants/, category Colorimetry, and asset type spectral.
  • Runtime capture: shared Library state capture includes illuminants: window.AAIlluminants?.getState.
  • Runtime restore: shared Library restore routes include ["illuminants", window.AAIlluminants?.restoreState].
  • Compatibility fallback: the simple binding checks legacy ids ill-select and illuminant-select, then snapshots form inputs. The current page uses il-illum-select, so prefer the runtime API for exact state.
  • Integration note: if the Library binding is modernized, update the simple capture ids to il-illum-select, il-compare-illum, il-adapt-from, and related controls or delegate directly to window.AAIlluminants.getState().

9. Extension checklist

+
  1. Add new standard sources to SPD_DATA on the 380-780 nm, 5 nm grid.
  2. Add matching metadata to ILLUM_META so labels, type, CCT, linked CCT, and comparison tables remain consistent.
  3. Update the standard illuminant dropdown and comparison dropdown HTML when new user-visible sources are added.
  4. Keep all spectrum arrays the same length as LAMBDA, or add validation before colorimetry functions consume them.
  5. When replacing fluorescent approximations with official tables, document the table source, interval, interpolation rule, and normalization policy.
  6. When adding a new CAT method, add matrices, update adaptXYZ(), UI radio inputs, matrix output, share URL handling, docs, and tests.
  7. When adding custom uploaded SPD or reflectance data, define parsing, normalization, wavelength interpolation, export behavior, URL behavior, and Library save behavior before shipping.
  8. Update JSON export and share URL behavior whenever the persistent state surface changes.
  9. Regenerate docs discovery outputs after any documentation addition: scripts/generate-discovery.mjs, scripts/generate-pwa-cache-manifest.mjs, and search/client/build-index.js.
  10. Keep the Data tab and the research notes explicit when a method is approximate and not a replacement for official CIE or IES compliance software.

10. Testing and risk notes

+
  • Boot: the page loads, the provenance note appears, Lab tab is active, summary populates, SPD canvas renders, CRI canvas renders, surface rows appear, and adaptation patches appear.
  • Controls: test standard illuminant changes, blackbody CCT slider, CCT input, Link to select, reset, comparison toggle, comparison source changes, surface toggles, adaptation pair, adaptation model, and swap.
  • Actions: test CSV, JSON, PNG, copy white HEX, generate share URL, copy share URL, and multi-illuminant table generation after multiple state changes.
  • URL restore: smoke test standard mode URLs with illum, blackbody URLs with cct, and adaptation params af, at, and am.
  • Library: save and restore through runtime state when available, and confirm the fallback form capture does not break older saved presets.
  • Numerical risk: changes to CMFs, normalization, daylight basis vectors, fluorescent approximations, Lab reference white, or Delta E implementation will shift visible charts, exports, CRI values, metamerism index, and saved expectations.
  • Performance risk: CRI, surface, and comparison calculations repeatedly iterate over 81 wavelength samples and 14 TCS approximations. Larger future sample sets should be measured on mobile before release.
  • Compliance risk: current fluorescent spectra, TCS reflectances, CRI, and metamerism calculations are educational approximations, and TM-30 is not computed because its CES data is absent. Avoid labeling generated output as certified CIE or IES data unless the engine is replaced with normative tables and validated algorithms.