The LUTs are built with Hillaire's ILLUMINANCE_IS_ONE convention (globalL = 1), so they store sky response per unit sun illuminance; SkyAtmosphereMesh.luminanceScale (default 40, exposed as Sky({ exposure })) multiplies at composite time. The 40 is currently tuned by eye (CLAUDE.md notes this as a known open task).
Deriving it from a physical sun-illuminance constant (~120,000 lux at the top of atmosphere; SebH's full demo parameterizes illuminance in physical units) would:
- make
exposure mean something in physical units (and interact predictably with toneMappingExposure),
- keep the sun disc / sky / haze / DirectionalLight intensities consistent by construction instead of by four separately-tuned numbers (sky exposure 40, SkySun intensity 4, toneMappingExposure 0.5, sunDiscIntensity),
- give presets (mars, titan) a principled brightness relationship to earth.
Scope: a constants module + a documented mapping, defaults preserved (the eye-tuned 40 becomes the derived value or stays as a compat default behind a flag).
🤖 Generated with Claude Code
The LUTs are built with Hillaire's
ILLUMINANCE_IS_ONEconvention (globalL = 1), so they store sky response per unit sun illuminance;SkyAtmosphereMesh.luminanceScale(default 40, exposed asSky({ exposure })) multiplies at composite time. The 40 is currently tuned by eye (CLAUDE.md notes this as a known open task).Deriving it from a physical sun-illuminance constant (~120,000 lux at the top of atmosphere; SebH's full demo parameterizes illuminance in physical units) would:
exposuremean something in physical units (and interact predictably withtoneMappingExposure),Scope: a constants module + a documented mapping, defaults preserved (the eye-tuned 40 becomes the derived value or stays as a compat default behind a flag).
🤖 Generated with Claude Code