lux-rs
Pure Rust lighting and color science library for spectral, photometric, and colorimetric workflows.
Overview
lux-rs provides a native Rust API for core lighting and color science calculations without requiring Python at runtime.
The crate currently includes:
P0base spectral kernel: completedP1reference-source and CCT path: completedP1.5first standard-illuminant registry: completedP2status: color transforms,deltaE, and CAT utilities completedP3status: first CAM / CAM-UCS forward and inverse paths completedP3status: first CRI path completed forCIE Ra,CIE Rf / Rg, andTM-30result objectsP4status: first detector spectral mismatch utilities completed forf1′and correction factorsP4status: firstindvcmfslice completed for deterministic Asano-style individual observer CMFs without peak-shift support- next priority: move into photobiological metrics
Design Goals
- spectral foundations: wavelength grids, spacing helpers, interpolation, normalization, and unified single/batch
Spectrumworkflows - observers and photometry: embedded standard observers, tristimulus integration, radiometric / photometric / quantal power, and mesopic support
- illuminants and reference sources: blackbody, daylight family, CRI reference sources, and a registry for common CIE illuminants and LED series
- color kernels: CCT, common XYZ-derived transforms, color difference, and chromatic adaptation including viewing-condition and compiled-adapter workflows
- appearance models: first-pass
CIECAM02,CAM16,CAM02-UCS, andCAM16-UCSforward / inverse paths plus wrapper APIs on top of the color data models - color quality metrics:
CIE Ra,CIE Rf / Rg, and structuredTM-30result objects for single and batch spectral workflows - advanced detector utilities: first-pass spectral mismatch (
f1′) and correction-factor workflows on top ofSpectrum - advanced observer utilities: first-pass
indvcmfdeterministic LMS / XYZ CMF generation for one observer profile
Why This Repo Exists
This repository is not a Rust binding around Python. It is a direct Rust implementation route for the parts of luxpy that matter most to numerical core workflows:
- predictable native deployment
- easier integration into Rust systems
- clearer data ownership and API design
- parity testing against an existing scientific reference implementation
Verification
The crate is validated with Rust tests and parity checks against luxpy. Covered paths include:
- spectral grid helpers
- interpolation and normalization
- observer and CMF access
spd_to_power,spd_to_ler,spd_to_xyzblackbody,daylightphase,cri_refxyz_to_cct,cct_to_xyz- standard illuminants
- one-step and two-step
CAT CIECAM02,CAM16,CAM02-UCS, andCAM16-UCSCIE RaCIE Rf / RgTM-30result objects
Install
Quick Example
use ;
For color calculations, use Tristimulus as the primary batch API (1 row represents a single XYZ-like sample).
For spectral calculations, use Spectrum as the primary API (1 row represents a single SPD).
API Shape Conventions
Phase 1 convergence keeps the current numerical behavior, but makes the intended public API shape explicit:
- use
Spectrumfor both one SPD and aligned multi-SPD workflows; represent a single SPD as a one-row batch - use
Tristimulusfor aligned XYZ-like color workflows; represent a single item as a one-row batch - keep scalar and batch paths numerically aligned, for example free
spd_to_*helpers and row-wiseSpectrum::spd_to_*batch methods - prefer constructors that keep row alignment explicit (
Spectrum::new(...)andTristimulus::new(...)), withTristimulus::from_single(...)as convenience for one item - fixed-size leaf kernels may still use raw
[f64; 3]values internally, but public wrappers should preferTristimuluswhen they represent semantic color results - wrapper APIs should stay thin: the single-item and batch forms should share one core implementation rather than fork behavior
Roadmap
Near-term work, following TODO_REFACTOR.md:
- finish illuminant naming cleanup and alias normalization
- start
photobiochembase metrics - return to broader observer coverage and remaining result-layer polish
Longer-term items such as broader CAM families, TM-30 graphics, photobiological metrics, individual observers, and hyperspectral tooling remain intentionally deferred until the current core stays stable.
Relationship To LuxPy
luxpy is a comprehensive Python toolbox for lighting and color science. lux-rs is not a binding layer around Python; it is a native Rust implementation that draws on the same problem domain and uses LuxPy for parity-oriented validation during development.
Scope difference, in short:
luxpy: broad toolbox including CAM, CAT, CRI/TM-30, photobiology, hyperspectral imaging, instrument/toolbox integrations, and morelux-rs: focused on spectral kernels, observers, integration, reference illuminants, photometry, CCT, color transforms, CAM, and CRI/TM-30 core workflows
That means lux-rs is narrower in scope than luxpy, while still being suitable for a meaningful subset of core numerical workflows.
Citing LuxPy
If this repository or its design work benefits from luxpy, please cite the original luxpy project and tutorial paper.
Recommended citation from the upstream luxpy README:
Smet, K. A. G. (2020). Tutorial: The LuxPy Python Toolbox for Lighting and Color Science. LEUKOS, 1-23. https://doi.org/10.1080/15502724.2018.1518717
Useful upstream references:
- LuxPy repository: https://github.com/ksmet1977/luxpy
- LuxPy tutorial paper: https://www.tandfonline.com/doi/full/10.1080/15502724.2018.1518717
- LuxPy Zenodo DOI: https://doi.org/10.5281/zenodo.1298963
License
This crate is licensed under GPL-3.0-only. See Cargo.toml and the repository license terms for details.