code wiki / (root) / nx_worley_noise.nx

nx_worley_noise.nx

buildroot/runtime/nx_worley_noise.nx

12997 B268 linesdepth 2pulls 4 transitivereach 0 importersview sourcekind orphan library
docsdependenciesstructsconstsfunctions

about

nx_worley_noise.nx -- Worley cellular noise (F1 distance) in Q10. Cross-cutting Substrate A primitive per nxc2/docs/NISHI_GAME_ENGINE_ROADMAP.md. Worley 1996 "A Cellular Texture Basis Function" (SIGGRAPH '96). Divide the plane into uniform cells; place one feature point per cell at a hash-determined position; the noise value at any query point is the distance to the nearest feature point (F1). Produces natural-looking cobblestone, rock, dried-mud, water-cell, and lizard- scale textures that Perlin FBM cannot. Algorithm: 1. Cell index (cx, cy) = floor(x / Q), floor(y / Q). 2. Local position within cell (fx, fy) = x - cx*Q, y - cy*Q. 3. For each neighbor cell (cx+dx, cy+dy) with dx, dy in {-1, 0, 1}: a. Hash (ncx, ncy, seed) to a feature-point offset in [0, Q). b. Feature absolute (relative to current cell origin): (dx*Q + ox, dy*Q + oy). c. Squared distance from local query point to feature point. 4. F1 = sqrt(min of those 9 squared distances). 3x3 neighborhood guarantees correctness because the feature point closest to (fx, fy) cannot live more than 1 cell away in any axis when feature points are confined to [0, Q) per cell. Determinism: hash is pure LCG over (cx, cy, seed). Same query + seed -> byte-equal output everywhere. Fixed-point strategy: distances kept in Q20 (Q^2) until the final integer-sqrt converts to Q10. Avoids the precision loss that would hit a per-step Q10 divide. Loss audit: only information-discarding op is the integer sqrt (truncates fractional bit; ~1% error worst case). All other ops exact in i64. genealogy_id: worley_1996_cellular lineage_id: nx_worley_noise_q10_f1

dependencies 3 imports · 0 importers

nx_syscalls.nx nx_tier.nx nx_vecmath.nx nx_worley_noise.nx

imports: nx_syscalls.nxnx_tier.nxnx_vecmath.nx

imported by: nobody (leaf or entry point)

structs

none

consts

60const NX_MAGIC_1024: i64 = 1024
61const NX_MAGIC_16777216: i64 = 16777216
62const NX_MAGIC_1500: i64 = 1500
63const NX_MAGIC_12345: i64 = 12345
64const NX_MAGIC_1448: i64 = 1448
67const NX_WORLEY_Q: nx_int = 1024
71const NX_WORLEY_LCG_A: nx_int = 48271
72const NX_WORLEY_LCG_M: nx_int = 2147483647
77const NX_WORLEY_HASH_CX: nx_int = 2654435761
78const NX_WORLEY_HASH_CY: nx_int = 1597334677
84const NX_WORLEY_BAND_AT_FEATURE: nx_int = 0 // F1 < 64 (~0.06)
85const NX_WORLEY_BAND_NEAR: nx_int = 1 // 64..255
86const NX_WORLEY_BAND_MID: nx_int = 2 // 256..639
87const NX_WORLEY_BAND_FAR: nx_int = 3 // 640..1023
88const NX_WORLEY_BAND_CORNER: nx_int = 4 // >= 1024 (cell-corner range)
90const NX_WORLEY_THRESH_AT: nx_int = 64
91const NX_WORLEY_THRESH_NEAR: nx_int = 256
92const NX_WORLEY_THRESH_MID: nx_int = 640
93const NX_WORLEY_THRESH_FAR: nx_int = 1024

functions

96func nx_worley_noise_band_is_valid(b: nx_int) -> nx_int
106func nx_worley_noise_classify(value_q10: nx_int) -> nx_int
119func _isqrt(n: nx_int) -> nx_int { return vm_isqrt(n) }
126func _hash_cell(cx: nx_int, cy: nx_int, seed: nx_int) -> nx_int
141func _hash_to_x_offset(h: nx_int) -> nx_int
145func _hash_to_y_offset(h: nx_int) -> nx_int
151func _floor_div_q(n: nx_int) -> nx_int
161func nx_worley_noise(x_q10: nx_int, y_q10: nx_int, seed: nx_int) -> nx_int
199func main() -> i64