κ converts ray mass into optical depth: every geometry family now builds
τ = κ · rayMass, where rayMass is the SAME quantity that family's
additive branch emits (points/lines alpha, gsplats intensity). Because
that quantity is a peak-screen-alpha-normalised number rather than a
world-space length, κ is comparable across points, lines and gsplats and
across scene scales — κ = 1 means "peak rendered alpha ≈ the authored
per-element alpha" for all three. One fixed track therefore serves every
scene.
HISTORY (do not reintroduce): this module used to DERIVE a per-layer upper
bound as ABSORPTION_TAU_TARGET / (thickness · chord) from max_width /
max_radius, because the point and line shaders multiplied τ by a world
thickness (the former point chord factor) that the gsplat shader had no
counterpart for. That made κ a per-unit-length coefficient for two families
and dimensionless for the third, so the stretch was a units conversion, not
a UX affordance — and it could never serve a MIXED subtree (a
lift_points_to_gsplats LOD ladder composes ONE κ over both families, and
gsplats returned no stat at all). The shaders now share one convention, so
the conversion is gone along with the chord constants.
What remains here is the log-track mechanics: a fixed nominal span, widened
only when an AUTHORED κ falls outside it so the thumb can always represent
the live value.
Range for the volumetric absorption (κ) slider.
κ converts ray mass into optical depth: every geometry family now builds
τ = κ · rayMass, whererayMassis the SAME quantity that family's additive branch emits (points/linesalpha, gsplatsintensity). Because that quantity is a peak-screen-alpha-normalised number rather than a world-space length, κ is comparable across points, lines and gsplats and across scene scales — κ = 1 means "peak rendered alpha ≈ the authored per-element alpha" for all three. One fixed track therefore serves every scene.HISTORY (do not reintroduce): this module used to DERIVE a per-layer upper bound as
ABSORPTION_TAU_TARGET / (thickness · chord)frommax_width/max_radius, because the point and line shaders multiplied τ by a world thickness (the former point chord factor) that the gsplat shader had no counterpart for. That made κ a per-unit-length coefficient for two families and dimensionless for the third, so the stretch was a units conversion, not a UX affordance — and it could never serve a MIXED subtree (alift_points_to_gsplatsLOD ladder composes ONE κ over both families, and gsplats returned no stat at all). The shaders now share one convention, so the conversion is gone along with the chord constants.What remains here is the log-track mechanics: a fixed nominal span, widened only when an AUTHORED κ falls outside it so the thumb can always represent the live value.