nx_kubelka_lib.nx
buildroot/runtime/nx_kubelka_lib.nx
about
nx_kubelka_lib.nx -- KUBELKA-MUNK TWO-FLUX REFLECTANCE, THE CHROMOPHORE SUBSTRATE (2026-09-03)
WHY. Skin albedo in this estate is a COLOUR (nx_skin_ita derives an sRGB from the genome; nx_arousal_skin
carries melanin and perfusion permil). A colour can be painted but it cannot be RELIT, and it cannot be
EDITED physically -- and every late-stage goal on the biotwin board (a predicted scar, its erythema decaying
over months, pigmentation returning) is an edit to the ABSORBERS underneath, not to the pixel on top.
Kubelka-Munk is the bridge: it turns "how much melanin and how much haemoglobin" into "what reflectance",
and -- because it inverts in closed form -- it turns a measured reflectance back into K/S. That inverse is
what lets a captured photograph become chromophore ground truth instead of a baked texture.
MEASURED ABSENT before building: nx_absent kubelka -> ABSENT-PROVEN, coverage_complete=1 corpus_complete=1.
SINGLE-CONSTANT KUBELKA-MUNK, the form the field actually uses for an optically thick layer:
R_inf = 1 + K/S - sqrt((K/S)^2 + 2(K/S)) forward
K/S = (1 - R)^2 / (2R) inverse (exact, and the round trip proves both)
K is absorption, S is scattering. Absorption is ADDITIVE over chromophores, which is the whole reason this
parameterisation relights and edits: K = K_base + c_mel*K_mel + c_hem*K_hem.
THE COEFFICIENTS ARE NOT IN THIS FILE, DELIBERATELY. K_mel and K_hem are MEASURED spectra and belong in
pinned reference data, not typed into a lib by an author who did not measure them. Every function here
takes them as arguments, so this file carries physics and never fabricates a constant.
PROVEN 10/10 GREEN on the laptop build farm 2026-09-03 (NAS build lane was wedged): K/S=0.25 -> R=0.500000
exactly, K/S=1 -> R=0.267949 (2-sqrt3), round trip 9/9 rungs with a worst error of 1e-6.
All arithmetic is nx_fixq30_lib Q30. license_tier: ORIGINAL No hw writes (Rule 26). LIB (no main).
dependencies 2 imports · 4 importers
imports: nx_syscalls.nxnx_fixq30_lib.nx
imported by: nx_follicle_gate.nxnx_kubelka_gate.nxnx_skinfit_lib.nxnx_vasc_gate.nx
structs
| none |
consts
| 30 | const KM_REFUSED: i64 = 0 - 1 |
| 31 | const KM_TWO: i64 = 2 |
functions
| 34 | func km_r_from_ks(ks: i64) -> i64 |
| 48 | func km_ks_from_r(r: i64) -> i64 |
| 60 | func km_ks_mix(k_base: i64, k_mel: i64, c_mel: i64, k_hem: i64, c_hem: i64, s: i64) -> i64 |
| 70 | func km_r_of_mix(k_base: i64, k_mel: i64, c_mel: i64, k_hem: i64, c_hem: i64, s: i64) -> i64 |