code wiki / (root) / nx_world_shader_sky_private_20260910.nx

nx_world_shader_sky_private_20260910.nx

buildroot/runtime/nx_world_shader_sky_private_20260910.nx

112994 B1009 linesdepth 3pulls 3 transitivereach 1 importersview sourcekind librarytopic world
docsdependenciesstructsconstsfunctions

about

nx_world_shader_src.nx -- THE WORLD SHADER, WRITTEN ONCE (gameengine GE44 R-G, 2026-09-04). The voxel world pass that nx_game_page_emit ships hand-written twice (a GLSL FSH for the WebGL2 door and a WGSL module for the WebGPU door) is authored here ONCE as shader-IR builder calls and emitted to BOTH dialects by nx_wgsl. Every function below is the hand WGSL, statement for statement (vx, h21, h31, pal9, sky, struct Hit, march, shade, the fragment entry); the vertex entry is the backend's own fullscreen triangle (shsrc_fullscreen_tri). Deliberate deltas from the hand text, all semantic no-ops: compound assignments are spelled x=(x+y); unsigned constants are casts (u32(0) / uint(0)) because the GLSL backend spells a u32 literal without its suffix and a bare 0 beside a uint is a GLSL type error; the WebGPU top-left fragment origin is carried as the uniform `yflip` (1 on the WebGPU door, 0 on WebGL2) instead of a per-dialect edit, so ONE source serves both doors. The uniform block is declared ONCE here (ws_world_uniforms) and `nx_wgsl layout` derives its memory layout from it. GE55 (2026-09-05): the world module now takes the sim's RAW state words as its uniform block (ws_world_uniforms_raw, the same 40-word table as nx_wasm_craft UR_*) and derives every float in upk() into module-scope private state, so the page packs nothing and computes nothing; ws_world_uniforms (the f32 block) stays as the R-F layout ruler fixture. license_tier: ORIGINAL

dependencies 1 imports · 1 importers

nx_shader_ir.nx nx_world_shader_sky_private_20 nx_wgsl_sky_private_20260910.nx

imports: nx_shader_ir.nx

imported by: nx_wgsl_sky_private_20260910.nx

structs

none

consts

247const CB_BASE: *u8 = "56.0" // the incumbent sheet's height in blocks, now the slab base
248const CB_TOP: *u8 = "96.0"
249const CB_RLO: *u8 = "6.0" // density ramps in over this many blocks above the base
250const CB_RHI: *u8 = "16.0" // and out over this many below the top
251const CB_CELL: *u8 = "96.0" // one noise cell in blocks, horizontal
252const CB_CELLY: *u8 = "40.0" // and vertical (flatter cells read as stratus)
253const CB_DRIFT_X: *u8 = "240.0" // the incumbent sheet's drift divisors, kept so the motion does not change
254const CB_DRIFT_Z: *u8 = "540.0"
255const CB_THR0: *u8 = "0.78" // coverage threshold at cld=0
256const CB_THRK: *u8 = "0.30" // and how far cld=1 lowers it
257const CB_GAIN: *u8 = "4.0"
258const CB_STEPS: *u8 = "24"
259const CB_STEPS_F: *u8 = "24.0"
260const CB_SIGMA: *u8 = "0.09" // extinction per block of unit density
261const CB_LIT0: *u8 = "0.70" // ambient at the base
262const CB_LIT1: *u8 = "0.30" // brighter toward the top
263const CB_SUNK: *u8 = "0.15" // silver toward the sun
267const CB_EROSION: *u8 = "0.22"
268const CB_SUN_Y_MIN: *u8 = "0.01"
269const CB_LIGHT_DISTANCE: *u8 = "160.0"
270const CB_LIGHT_STEPS: *u8 = "6"
271const CB_LIGHT_STEPS_F: *u8 = "6.0"
272const CB_VIEW_DISTANCE: *u8 = "1400.0"
273const CB_PHASE_G: *u8 = "0.35"
274const CB_AMBIENT: *u8 = "0.28"
275const CB_DIRECT: *u8 = "0.72"
625const SD_GRAIN_PER_BLOCK: *u8 = "32.0" // facets per block edge: 3 cm at a 1 m block, coarse beach sand
626const SD_GRAIN_SLOPE: *u8 = "1.2" // facet steepness as a normal slope
627const SD_RIPPLE_PER_BLOCK: *u8 = "9.0" // wind ripples per block: an 11 cm wavelength at a 1 m block
628const SD_RIPPLE_SLOPE: *u8 = "0.45" // crest slope
629const SD_RIPPLE_DX: *u8 = "0.8" // ripple normal heading (unit): the wind heading, a data hook
630const SD_RIPPLE_DZ: *u8 = "0.6"
631const SD_PATCH: *u8 = "0.25" // ripple phase jitter per 4-block patch so the field is not one sine
632const SD_TAU: *u8 = "6.2831853"
633const SD_QUARTER_TURN: *u8 = "1.5707963"
634const SD_EIGHTH_TURN: *u8 = "0.7853982"
635const SD_RING_DIRS: *u8 = "8"
636const SD_RING_STEPS: *u8 = "24" // SD_RING_DIRS x SD_WET_R
637const SD_WET_R: *u8 = "3.0" // wet band reach in cells
638const SD_WET_DRY: *u8 = "4.0" // SD_WET_R + 1: no water within reach
639const SD_WET_DARK: *u8 = "0.55" // wet albedo multiplier
640const SD_FILM_POW: *u8 = "48.0"
641const SD_FILM_GAIN: *u8 = "0.55"
642const SD_SHEEN_GAIN: *u8 = "0.10"
643const SD_GLINT_POW: *u8 = "96.0"
644const SD_GLINT_GAIN: *u8 = "0.35"
645const SD_GLINT_FRAC: *u8 = "0.9" // facets whose hash exceeds this are quartz glints
646const SD_NDV_FLOOR: *u8 = "0.15" // the footprint stretch floor at grazing angles
647const SD_SHADOW_SPEC: *u8 = "0.2" // in a block shadow the film keeps its sky sheen and loses the sun
648const SD_TWO: *u8 = "2.0"
649const SD_HALF: *u8 = "0.5"

functions

18func ws_f(m: *i64, s: *u8) -> i64 { return sir_lit(m, s, T_F32) }
19func ws_i(m: *i64, s: *u8) -> i64 { return sir_lit(m, s, T_I32) }
21func ws_u(m: *i64, s: *u8) -> i64 { return sir_cast(m, sir_lit(m, s, T_I32), T_U32) }
22func ws_id(m: *i64, n: *u8, ty: i64) -> i64 { return sir_ident(m, n, ty) }
23func ws_bin(m: *i64, op: *u8, a: i64, b: i64, ty: i64) -> i64 { return sir_bin(m, op, a, b, ty) }
24func ws_cmp(m: *i64, op: *u8, a: i64, b: i64) -> i64 { return sir_bin(m, op, a, b, T_BOOL) }
25func ws_and(m: *i64, a: i64, b: i64) -> i64 { return sir_bin(m, "&&" as *u8, a, b, T_BOOL) }
26func ws_or(m: *i64, a: i64, b: i64) -> i64 { return sir_bin(m, "||" as *u8, a, b, T_BOOL) }
27func ws_sw(m: *i64, a: i64, sel: *u8, ty: i64) -> i64 { return sir_swz(m, a, sel, ty) }
29func ws_sx(m: *i64, n: *u8, nty: i64, sel: *u8, ty: i64) -> i64 { return sir_swz(m, sir_ident(m, n, nty), sel, ty) }
30func ws_mem(m: *i64, a: i64, name: *u8, ty: i64) -> i64 { return sir_member_of(m, a, name, ty) }
31func ws_c1(m: *i64, name: *u8, a: i64, ty: i64) -> i64 { let c: i64 = sir_call(m, name, ty); sir_arg(m, c, a); return c }
32func ws_c2(m: *i64, name: *u8, a: i64, b: i64, ty: i64) -> i64 { let c: i64 = sir_call(m, name, ty); sir_arg(m, c, a); sir_arg(m, c, b); return c }
33func ws_c3(m: *i64, name: *u8, a: i64, b: i64, c3: i64, ty: i64) -> i64 { let c: i64 = sir_call(m, name, ty); sir_arg(m, c, a); sir_arg(m, c, b); sir_arg(m, c, c3); return c }
34func ws_c4(m: *i64, name: *u8, a: i64, b: i64, c3: i64, d: i64, ty: i64) -> i64 { let c: i64 = sir_call(m, name, ty); sir_arg(m, c, a); sir_arg(m, c, b); sir_arg(m, c, c3); sir_arg(m, c, d); return c }
35func ws_c5(m: *i64, name: *u8, a: i64, b: i64, c3: i64, d: i64, e: i64, ty: i64) -> i64 { let c: i64 = sir_call(m, name, ty); sir_arg(m, c, a); sir_arg(m, c, b); sir_arg(m, c, c3); sir_arg(m, c, d); sir_arg(m, c, e); return c }
36func ws_c6(m: *i64, name: *u8, a: i64, b: i64, c3: i64, d: i64, e: i64, g: i64, ty: i64) -> i64 { let c: i64 = sir_call(m, name, ty); sir_arg(m, c, a); sir_arg(m, c, b); sir_arg(m, c, c3); sir_arg(m, c, d); sir_arg(m, c, e); sir_arg(m, c, g); return c }
37func ws_v1(m: *i64, ty: i64, a: i64) -> i64 { let c: i64 = sir_ctor(m, ty); sir_arg(m, c, a); return c }
38func ws_vt2(m: *i64, ty: i64, a: i64, b: i64) -> i64 { let c: i64 = sir_ctor(m, ty); sir_arg(m, c, a); sir_arg(m, c, b); return c }
39func ws_vt3(m: *i64, ty: i64, a: i64, b: i64, c3: i64) -> i64 { let c: i64 = sir_ctor(m, ty); sir_arg(m, c, a); sir_arg(m, c, b); sir_arg(m, c, c3); return c }
40func ws_v2(m: *i64, a: i64, b: i64) -> i64 { return ws_vt2(m, T_V2F, a, b) }
41func ws_v3(m: *i64, a: i64, b: i64, c3: i64) -> i64 { return ws_vt3(m, T_V3F, a, b, c3) }
42func ws_v3i(m: *i64, a: i64, b: i64, c3: i64) -> i64 { return ws_vt3(m, T_V3I, a, b, c3) }
43func ws_v4(m: *i64, a: i64, b: i64, c3: i64, d: i64) -> i64 { let c: i64 = sir_ctor(m, T_V4F); sir_arg(m, c, a); sir_arg(m, c, b); sir_arg(m, c, c3); sir_arg(m, c, d); return c }
45func ws_v2f(m: *i64, a: *u8, b: *u8) -> i64 { return ws_v2(m, ws_f(m, a), ws_f(m, b)) }
46func ws_v3f(m: *i64, a: *u8, b: *u8, c3: *u8) -> i64 { return ws_v3(m, ws_f(m, a), ws_f(m, b), ws_f(m, c3)) }
47func ws_q2(m: *i64, a: i64, b: i64) -> i64 { return sir_seq(m, a, b) }
48func ws_q3(m: *i64, a: i64, b: i64, c: i64) -> i64 { return sir_seq(m, sir_seq(m, a, b), c) }
49func ws_q4(m: *i64, a: i64, b: i64, c: i64, d: i64) -> i64 { return sir_seq(m, ws_q3(m, a, b, c), d) }
50func ws_q5(m: *i64, a: i64, b: i64, c: i64, d: i64, e: i64) -> i64 { return sir_seq(m, ws_q4(m, a, b, c, d), e) }
51func ws_set(m: *i64, lhs: i64, rhs: i64) -> i64 { return sir_assign(m, lhs, rhs) }
53func ws_op(m: *i64, name: *u8, ty: i64, op: *u8, rhs: i64) -> i64 { return sir_assign(m, sir_ident(m, name, ty), sir_bin(m, op, sir_ident(m, name, ty), rhs, ty)) }
55func ws_opx(m: *i64, name: *u8, nty: i64, sel: *u8, ty: i64, op: *u8, rhs: i64) -> i64 { return sir_assign(m, ws_sx(m, name, nty, sel, ty), sir_bin(m, op, ws_sx(m, name, nty, sel, ty), rhs, ty)) }
56func ws_if(m: *i64, c: i64, t: i64, e: i64) -> i64 { return sir_if(m, c, t, e) }
57func ws_ret(m: *i64, e: i64) -> i64 { return sir_return(m, e) }
58func ws_st(m: *i64, f: i64, s: i64) -> i64 { return sir_stmt(m, f, s) }
62func ws_world_uniforms(m: *i64) -> i64
92func ws_ru(m: *i64, n: *u8, ty: i64) -> i64 { return sir_uniform(m, n, ty, 0) }
93func ws_world_uniforms_raw(m: *i64) -> i64
109func ws_world_privates(m: *i64) -> i64
119func ws_fi(m: *i64, n: *u8) -> i64 { return sir_cast(m, sir_ident(m, n, T_I32), T_F32) }
121func ws_fn_rgb9(m: *i64) -> i64
131func ws_pal(m: *i64, f: i64, arr: *u8, k: *u8, rn: *u8) -> i64
139func ws_fn_upk(m: *i64) -> i64
177func ws_fn_vx(m: *i64) -> i64
195func ws_fn_h21(m: *i64) -> i64
204func ws_fn_h31(m: *i64) -> i64
213func ws_fn_pal9(m: *i64) -> i64
227func ws_noise2(m: *i64, iname: *u8, fname: *u8) -> i64
276func ws_h31o(m: *i64, a: *u8, b: *u8, c: *u8) -> i64
279func ws_fx(m: *i64, sel: *u8) -> i64 { return ws_sx(m, "f" as *u8, T_V3F, sel, T_F32) }
280func ws_py(m: *i64) -> i64 { return ws_sx(m, "p" as *u8, T_V3F, "y" as *u8, T_F32) }
282func ws_fn_vn3(m: *i64) -> i64
302func ws_fn_cvol(m: *i64) -> i64
318func ws_fn_csun(m: *i64) -> i64
331func ws_fn_cld3(m: *i64) -> i64
361func ws_fn_sky(m: *i64) -> i64
381func ws_struct_hit(m: *i64) -> i64
391func ws_dda_step(m: *i64, ax: *u8, fneg: *u8, fpos: *u8) -> i64
402func ws_fn_hq(m: *i64) -> i64
418func ws_fn_surf(m: *i64) -> i64
440func ws_fn_terrain(m: *i64) -> i64
452func ws_fn_smarch(m: *i64) -> i64
489func ws_fn_gnd(m: *i64) -> i64
513func ws_fn_march(m: *i64, hty: i64) -> i64
570func ws_face(m: *i64, sw: *u8, ax: *u8, op: *u8, nx: *u8, ny: *u8, nz: *u8) -> i64
577func ws_li(m: *i64, k: *u8) -> i64 { return ws_op(m, "li" as *u8, T_F32, "*" as *u8, ws_f(m, k)) }
579func ws_fce(m: *i64, k: *u8) -> i64 { return ws_cmp(m, "==" as *u8, ws_id(m, "fce" as *u8, T_I32), ws_i(m, k)) }
581func ws_beq(m: *i64, k: *u8) -> i64 { return ws_cmp(m, "==" as *u8, ws_id(m, "b" as *u8, T_U32), ws_u(m, k)) }
583func ws_ao(m: *i64, fa: *u8, cmp: *u8, edge: *u8, nudge: i64, gain: i64) -> i64
590func ws_nb(m: *i64, ax: *u8, op: *u8) -> i64 { return ws_opx(m, "nb" as *u8, T_V3I, ax, T_I32, op, ws_i(m, "1" as *u8)) }
592func ws_topbot(m: *i64) -> i64 { return ws_or(m, ws_fce(m, "3" as *u8), ws_fce(m, "4" as *u8)) }
597func ws_smooth(m: *i64) -> i64
602func ws_cont_water(m: *i64) -> i64
605func ws_cont_surface(m: *i64) -> i64 { return ws_or(m, ws_smooth(m), ws_cont_water(m)) }
607func ws_step_down(m: *i64) -> i64
651func ws_sd_pxz(m: *i64) -> i64 { return ws_sx(m, "hp" as *u8, T_V3F, "xz" as *u8, T_V2F) }
652func ws_sd_f(m: *i64, n: *u8) -> i64 { return ws_id(m, n, T_F32) }
653func ws_sd_v3(m: *i64, n: *u8) -> i64 { return ws_id(m, n, T_V3F) }
655func ws_sd_surf(m: *i64, op: *u8, dx: *u8, dz: *u8) -> i64 { return ws_c1(m, "surf" as *u8, ws_bin(m, op, ws_sd_pxz(m), ws_v2f(m, dx, dz), T_V2F), T_F32) }
657func ws_sd_g(m: *i64, dx: *u8, dz: *u8) -> i64 { return ws_c1(m, "h21" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "gc" as *u8, T_V2F), ws_v2f(m, dx, dz), T_V2F), T_F32) }
658func ws_sd_lt0(m: *i64, n: *u8) -> i64 { return ws_cmp(m, "<" as *u8, ws_id(m, n, T_F32), ws_f(m, "0.0" as *u8)) }
659func ws_sd_dk(m: *i64, n: *u8) -> i64 { return ws_bin(m, "*" as *u8, ws_id(m, n, T_I32), ws_id(m, "k" as *u8, T_I32), T_I32) }
661func ws_sd_wat(m: *i64, y: *u8) -> i64 { return ws_cmp(m, "==" as *u8, ws_c1(m, "vx" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "c" as *u8, T_V3I), ws_vt3(m, T_V3I, ws_sd_dk(m, "dx" as *u8), ws_i(m, y), ws_sd_dk(m, "dz" as *u8)), T_V3I), T_U32), ws_u(m, "4" as *u8)) }
663func ws_sd_dir(m: *i64, shift: *u8) -> i64 { return sir_cast(m, ws_c1(m, "floor" as *u8, ws_bin(m, "+" as *u8, ws_c1(m, "sin" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "a" as *u8, T_F32), ws_f(m, shift), T_F32), T_F32), ws_f(m, SD_HALF), T_F32), T_F32), T_I32) }
665func ws_sd_fade(m: *i64, freq: *u8) -> i64 { return ws_c3(m, "clamp" as *u8, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_f(m, SD_TWO), ws_sd_f(m, "fp" as *u8), T_F32), ws_f(m, freq), T_F32), T_F32), ws_f(m, "0.0" as *u8), ws_f(m, "1.0" as *u8), T_F32) }
667func ws_sd_dslope(m: *i64, a: *u8, b: *u8, k: *u8) -> i64 { return ws_bin(m, "*" as *u8, ws_bin(m, "-" as *u8, ws_sd_f(m, a), ws_sd_f(m, b), T_F32), ws_f(m, k), T_F32) }
669func ws_sd_tilt(m: *i64, s: *u8, g: *u8, rdk: *u8) -> i64
676func ws_sandcls(m: *i64) -> i64 { return ws_or(m, ws_or(m, ws_beq(m, "1" as *u8), ws_beq(m, "2" as *u8)), ws_beq(m, "5" as *u8)) }
677func ws_sandy(m: *i64) -> i64 { return ws_and(m, ws_smooth(m), ws_sandcls(m)) }
679func ws_shd(m: *i64) -> i64 { return ws_q2(m, ws_li(m, "0.55" as *u8), ws_op(m, "sp" as *u8, T_F32, "*" as *u8, ws_f(m, SD_SHADOW_SPEC))) }
680func ws_fn_sand(m: *i64) -> i64
748func ws_fn_shade(m: *i64, hty: i64) -> i64
846func ws_bt(m: *i64, k: *u8, v: *u8, els: i64) -> i64
850func ws_pxo(m: *i64, a: *u8, op: *u8, e: i64) -> i64 { return ws_cmp(m, op, ws_sx(m, "px" as *u8, T_V2F, a, T_F32), ws_bin(m, "+" as *u8, ws_sx(m, "o" as *u8, T_V2F, a, T_F32), e, T_F32)) }
856func ws_fn_water_hit(m: *i64, hty: i64) -> i64
881func ws_fn_scene_hit(m: *i64, hty: i64) -> i64
913func ws_fn_fs(m: *i64, hty: i64) -> i64
982func shsrc_world(m: *i64) -> i64