code wiki / (root) / nx_henyey_greenstein.nx

nx_henyey_greenstein.nx

buildroot/runtime/nx_henyey_greenstein.nx

13356 B265 linesdepth 2pulls 2 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_henyey_greenstein.nx -- anisotropic single-scatter phase function in Q10. Epoch 2 FIRMAMENT primitive per nxc2/docs/NISHI_GAME_ENGINE_ROADMAP.md. The Henyey-Greenstein phase function approximates light scattering off small particles (atmospheric aerosols, water droplets, fog, pigment). Published in Henyey & Greenstein 1941 "Diffuse Radiation in the Galaxy" (Astrophysical Journal 93, 70-83) -- pre-1970 astrophysics, public-domain math. Formula: P(cos θ, g) = (1 - g^2) / (4π · (1 + g^2 - 2g·cos θ)^1.5) where: cos θ in [-1, 1]: scattering angle cosine (1 = forward, -1 = backward) g in [-1, 1]: asymmetry parameter g > 0 = forward-scattering (atmospheric haze ~ 0.8) g = 0 = isotropic g < 0 = backward-scattering (some pigments) Output: probability density. Normalized so ∫P dΩ = 1 over sphere. Range can exceed 1.0 when |g| near 1 and cos θ near sign(g) (forward/backward peaking). Capped at NX_HG_SATURATED to keep downstream arithmetic well-behaved. Fixed-point strategy: keep numerator and denominator in raw integer space and defer all divisions to a single final step. Avoids the Q10 precision starvation that would otherwise hit the (1 + g^2 - 2gc) term as it approaches 0. Loss audit: the only information-discarding ops are (a) integer sqrt (_isqrt) which truncates the fractional part, introducing ~1% error at typical g values; (b) clamp at |g| >= NX_HG_G_MAX to avoid singularity; (c) final integer division. All three are inherent to fixed-point evaluation of a singular function and are named here per cardinal rule 25. genealogy_id: henyey_greenstein_1941_phase lineage_id: nx_henyey_greenstein_q10

dependencies 2 imports · 0 importers

nx_syscalls.nx nx_tier.nx nx_henyey_greenstein.nx

imports: nx_syscalls.nxnx_tier.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main _isqrt nx_henyey_greenstein_phase _isqrt ↻ nx_henyey_greenstein_class nx_henyey_greenstein_band_

structs

none

consts

49const NX_MAGIC_1048576: i64 = 1048576
50const NX_MAGIC_1024: i64 = 1024
51const NX_MAGIC_1300: i64 = 1300
52const NX_MAGIC_1700: i64 = 1700
53const NX_MAGIC_9999: i64 = 9999
57const NX_HG_Q: nx_int = 1024
61const NX_HG_FOUR_PI_Q10: nx_int = 12868
68const NX_HG_G_MAX: nx_int = 1023
74const NX_HG_SATURATED: nx_int = 100000
81const NX_HG_BAND_STRONG_BACKWARD: nx_int = 0 // g <= -700
82const NX_HG_BAND_MODERATE_BACKWARD: nx_int = 1 // -700 < g <= -300
83const NX_HG_BAND_WEAK_BACKWARD: nx_int = 2 // -300 < g <= -50
84const NX_HG_BAND_ISOTROPIC: nx_int = 3 // -50 < g < 50
85const NX_HG_BAND_WEAK_FORWARD: nx_int = 4 // 50 <= g < 300
86const NX_HG_BAND_MODERATE_FORWARD: nx_int = 5 // 300 <= g < 700
87const NX_HG_BAND_STRONG_FORWARD: nx_int = 6 // g >= 700
89const NX_HG_THRESH_STRONG_BACK: nx_int = -700
90const NX_HG_THRESH_MOD_BACK: nx_int = -300
91const NX_HG_THRESH_WEAK_BACK: nx_int = -50
92const NX_HG_THRESH_WEAK_FWD: nx_int = 50
93const NX_HG_THRESH_MOD_FWD: nx_int = 300
94const NX_HG_THRESH_STRONG_FWD: nx_int = 700

functions

97func nx_henyey_greenstein_band_is_valid(b: nx_int) -> nx_int
called by 1: main
109func nx_henyey_greenstein_classify(g_q10: nx_int) -> nx_int
called by 1: main
124func _isqrt(n: nx_int) -> nx_int
160func nx_henyey_greenstein_phase(cos_theta_q10: nx_int, g_q10: nx_int) -> nx_int
called by 1: main calls 1: _isqrt
195func main() -> i64