nx_world_shader_cumulus_canonical_t156.nx source
↩ module page · 1074 lines · 120726 B
1// nx_world_shader_src.nx -- THE WORLD SHADER, WRITTEN ONCE (gameengine GE44 R-G, 2026-09-04).
2// The voxel world pass that nx_game_page_emit ships hand-written twice (a GLSL FSH for the WebGL2 door and a WGSL
3// module for the WebGPU door) is authored here ONCE as shader-IR builder calls and emitted to BOTH dialects by
4// nx_wgsl. Every function below is the hand WGSL, statement for statement (vx, h21, h31, pal9, sky, struct Hit,
5// march, shade, the fragment entry); the vertex entry is the backend's own fullscreen triangle (shsrc_fullscreen_tri).
6// Deliberate deltas from the hand text, all semantic no-ops: compound assignments are spelled x=(x+y); unsigned
7// constants are casts (u32(0) / uint(0)) because the GLSL backend spells a u32 literal without its suffix and a bare 0
8// beside a uint is a GLSL type error; the WebGPU top-left fragment origin is carried as the uniform `yflip` (1 on the
9// WebGPU door, 0 on WebGL2) instead of a per-dialect edit, so ONE source serves both doors. The uniform block is
10// declared ONCE here (ws_world_uniforms) and `nx_wgsl layout` derives its memory layout from it.
11// GE55 (2026-09-05): the world module now takes the sim's RAW state words as its uniform block (ws_world_uniforms_raw,
12// the same 40-word table as nx_wasm_craft UR_*) and derives every float in upk() into module-scope private state, so
13// the page packs nothing and computes nothing; ws_world_uniforms (the f32 block) stays as the R-F layout ruler fixture.
14// license_tier: ORIGINAL
15import "nx_shader_ir.nx"
16
17// ---- builder shorthands (one IR node per call; a node is never reused as two children) ----------------------
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) }
20// an unsigned constant as a cast of an int literal: `u32(0)` / `uint(0)`, the one spelling valid in both dialects
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) }
28// swizzle of a FRESH identifier (the common `name.x` read)
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 }
44// vec2f(x,y) / vec3f(x,y,z) of three f32 literals
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) }
52// x = (x op y) -- the spelling of every compound assignment in the hand text
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)) }
54// name.sel = (name.sel op y)
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) }
59
60// ---- the uniform block, declared ONCE (its layout is derived by `nx_wgsl layout`) ------------------------------
61// p0 of the hand packer is `yflip` here: the WebGPU door packs 1 (top-left origin), the WebGL2 door 0 (see fs).
62func ws_world_uniforms(m: *i64) -> i64 {
63 sir_uniform(m, "cam" as *u8, T_V3F, 0)
64 sir_uniform(m, "t" as *u8, T_F32, 0)
65 sir_uniform(m, "yp" as *u8, T_V4F, 0)
66 sir_uniform(m, "sund" as *u8, T_V3F, 0)
67 sir_uniform(m, "rain" as *u8, T_F32, 0)
68 sir_uniform(m, "skt" as *u8, T_V3F, 0)
69 sir_uniform(m, "sun" as *u8, T_F32, 0)
70 sir_uniform(m, "skh" as *u8, T_V3F, 0)
71 sir_uniform(m, "cld" as *u8, T_F32, 0)
72 sir_uniform(m, "res" as *u8, T_V2F, 0)
73 sir_uniform(m, "wmax" as *u8, T_F32, 0)
74 sir_uniform(m, "selb" as *u8, T_F32, 0)
75 sir_uniform(m, "hok" as *u8, T_F32, 0)
76 sir_uniform(m, "npct" as *u8, T_F32, 0)
77 sir_uniform(m, "yflip" as *u8, T_F32, 0)
78 sir_uniform(m, "p1" as *u8, T_F32, 0)
79 sir_uniform(m, "pal" as *u8, T_V4F, 12)
80 sir_uniform(m, "palf" as *u8, T_V4F, 5)
81 return 0
82}
83
84// ---- GE55 (2026-09-05): THE RAW UNIFORM BLOCK -- the sim's own state words, verbatim (nx_wasm_craft pack_uniforms) ----
85// 40 little-endian 32-bit words, 160 B; word index = byte offset / 4, the SAME table as UR_* in nx_wasm_craft.nx, and
86// `nx_wgsl layout` on this module is the one ruler both sides are pinned to. Signed state is i32, packed RGB words and
87// flags are u32. NOTHING here is a float: the wasm lane carries no f32 lowering, so every float the world pass needs is
88// derived in upk() below from these words -- the page packs no uniform and computes no arithmetic (the bridge is one
89// writeBuffer from the sim's memory). The derived values live in MODULE-SCOPE PRIVATE STATE (K_PRIVATE) under the
90// names every function body already reads (cam, t, yp, sund, rain, skt, sun, skh, cld, res, wmax, selb, hok, npct,
91// yflip, pal[12], palf[5]), so every function below stays byte-identical to the hand text it was proven against.
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 {
94 ws_ru(m, "r_camx" as *u8, T_I32); ws_ru(m, "r_camy" as *u8, T_I32); ws_ru(m, "r_camz" as *u8, T_I32); ws_ru(m, "r_tnow" as *u8, T_I32)
95 ws_ru(m, "r_yaw" as *u8, T_I32); ws_ru(m, "r_pitch" as *u8, T_I32); ws_ru(m, "r_sunel" as *u8, T_I32); ws_ru(m, "r_dayt" as *u8, T_I32)
96 ws_ru(m, "r_dlen" as *u8, T_I32); ws_ru(m, "r_rain" as *u8, T_I32); ws_ru(m, "r_skt" as *u8, T_U32); ws_ru(m, "r_skh" as *u8, T_U32)
97 ws_ru(m, "r_sun" as *u8, T_I32); ws_ru(m, "r_cld" as *u8, T_I32); ws_ru(m, "r_wmax" as *u8, T_I32); ws_ru(m, "r_selb" as *u8, T_I32)
98 ws_ru(m, "r_hok" as *u8, T_I32); ws_ru(m, "r_npct" as *u8, T_I32); ws_ru(m, "r_broken" as *u8, T_I32); ws_ru(m, "r_placed" as *u8, T_I32)
99 ws_ru(m, "r_pal0" as *u8, T_U32); ws_ru(m, "r_pal1" as *u8, T_U32); ws_ru(m, "r_pal2" as *u8, T_U32); ws_ru(m, "r_pal3" as *u8, T_U32)
100 ws_ru(m, "r_pal4" as *u8, T_U32); ws_ru(m, "r_pal5" as *u8, T_U32); ws_ru(m, "r_pal6" as *u8, T_U32); ws_ru(m, "r_pal7" as *u8, T_U32)
101 ws_ru(m, "r_pal8" as *u8, T_U32); ws_ru(m, "r_pal9" as *u8, T_U32); ws_ru(m, "r_pal10" as *u8, T_U32); ws_ru(m, "r_pal11" as *u8, T_U32)
102 ws_ru(m, "r_palf0" as *u8, T_U32); ws_ru(m, "r_palf1" as *u8, T_U32); ws_ru(m, "r_palf2" as *u8, T_U32); ws_ru(m, "r_palf3" as *u8, T_U32)
103 ws_ru(m, "r_palf4" as *u8, T_U32); ws_ru(m, "r_resw" as *u8, T_I32); ws_ru(m, "r_resh" as *u8, T_I32); ws_ru(m, "r_yflip" as *u8, T_I32)
104 ws_ru(m, "r_surf" as *u8, T_I32) // Continuous terrain and water; vegetation/objects still need separate geometry.
105 ws_ru(m, "r_water_q8" as *u8, T_I32) // Native UR_WATER_Q8, previously padding; block size is unchanged.
106 return 0
107}
108// the derived values, module-scope private state: `var<private>` in WGSL, a bare global in GLSL
109func ws_world_privates(m: *i64) -> i64 {
110 sir_private(m, "cam" as *u8, T_V3F, 0); sir_private(m, "t" as *u8, T_F32, 0); sir_private(m, "yp" as *u8, T_V4F, 0)
111 sir_private(m, "sund" as *u8, T_V3F, 0); sir_private(m, "rain" as *u8, T_F32, 0); sir_private(m, "skt" as *u8, T_V3F, 0)
112 sir_private(m, "sun" as *u8, T_F32, 0); sir_private(m, "skh" as *u8, T_V3F, 0); sir_private(m, "cld" as *u8, T_F32, 0)
113 sir_private(m, "res" as *u8, T_V2F, 0); sir_private(m, "wmax" as *u8, T_F32, 0); sir_private(m, "selb" as *u8, T_F32, 0)
114 sir_private(m, "hok" as *u8, T_F32, 0); sir_private(m, "npct" as *u8, T_F32, 0); sir_private(m, "yflip" as *u8, T_F32, 0)
115 sir_private(m, "pal" as *u8, T_V4F, 12); sir_private(m, "palf" as *u8, T_V4F, 5)
116 return 0
117}
118// f32(<raw i32 word>)
119func ws_fi(m: *i64, n: *u8) -> i64 { return sir_cast(m, sir_ident(m, n, T_I32), T_F32) }
120// fn rgb9(w:u32)->vec3f{return vec3f(f32(w&255u),f32((w>>8u)&255u),f32((w>>16u)&255u))/255.0;} -- the packed RGB word
121func ws_fn_rgb9(m: *i64) -> i64 {
122 let f: i64 = sir_func(m, "rgb9" as *u8, T_V3F)
123 sir_param(m, f, "w" as *u8, T_U32)
124 let r: i64 = sir_cast(m, ws_bin(m, "&" as *u8, ws_id(m, "w" as *u8, T_U32), ws_u(m, "255" as *u8), T_U32), T_F32)
125 let g: i64 = sir_cast(m, ws_bin(m, "&" as *u8, ws_bin(m, ">>" as *u8, ws_id(m, "w" as *u8, T_U32), ws_u(m, "8" as *u8), T_U32), ws_u(m, "255" as *u8), T_U32), T_F32)
126 let b: i64 = sir_cast(m, ws_bin(m, "&" as *u8, ws_bin(m, ">>" as *u8, ws_id(m, "w" as *u8, T_U32), ws_u(m, "16" as *u8), T_U32), ws_u(m, "255" as *u8), T_U32), T_F32)
127 ws_st(m, f, ws_ret(m, ws_bin(m, "/" as *u8, ws_v3(m, r, g, b), ws_f(m, "255.0" as *u8), T_V3F)))
128 return f
129}
130// <arr>[<k>]=vec4f(rgb9(<rn>)*dl2,0.0);
131func ws_pal(m: *i64, f: i64, arr: *u8, k: *u8, rn: *u8) -> i64 {
132 let c: i64 = ws_vt2(m, T_V4F, ws_bin(m, "*" as *u8, ws_c1(m, "rgb9" as *u8, ws_id(m, rn, T_U32), T_V3F), ws_id(m, "dl2" as *u8, T_F32), T_V3F), ws_f(m, "0.0" as *u8))
133 return ws_st(m, f, ws_set(m, sir_index(m, ws_id(m, arr, T_V4F), ws_i(m, k), T_V4F), c))
134}
135// fn upk(){ ... } -- every float the world pass reads, derived ONCE per fragment from the raw words. The arithmetic is
136// the retired JS packer's, line for line: cam/256, yaw and pitch Q12, df=max(0,sunel/4096), dl2=.22+.78*pow(df,.6),
137// nn=1-dl2, the sky words unpacked times dl2 plus nn*k, the sun disc only when the sim says sun AND df>.04, the sun
138// direction from the day fraction (az) and the elevation (el), and the 17 palette words times dl2.
139func ws_fn_upk(m: *i64) -> i64 {
140 let f: i64 = sir_func(m, "upk" as *u8, T_VOID)
141 ws_st(m, f, ws_set(m, ws_id(m, "cam" as *u8, T_V3F), ws_bin(m, "/" as *u8, ws_v3(m, ws_fi(m, "r_camx" as *u8), ws_fi(m, "r_camy" as *u8), ws_fi(m, "r_camz" as *u8)), ws_f(m, "256.0" as *u8), T_V3F)))
142 ws_st(m, f, ws_set(m, ws_id(m, "t" as *u8, T_F32), ws_fi(m, "r_tnow" as *u8)))
143 ws_st(m, f, sir_let(m, "ya" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_fi(m, "r_yaw" as *u8), ws_f(m, "4096.0" as *u8), T_F32)))
144 ws_st(m, f, sir_let(m, "pa" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_fi(m, "r_pitch" as *u8), ws_f(m, "4096.0" as *u8), T_F32)))
145 ws_st(m, f, ws_set(m, ws_id(m, "yp" as *u8, T_V4F), ws_v4(m, ws_c1(m, "sin" as *u8, ws_id(m, "ya" as *u8, T_F32), T_F32), ws_c1(m, "cos" as *u8, ws_id(m, "ya" as *u8, T_F32), T_F32), ws_c1(m, "sin" as *u8, ws_id(m, "pa" as *u8, T_F32), T_F32), ws_c1(m, "cos" as *u8, ws_id(m, "pa" as *u8, T_F32), T_F32))))
146 ws_st(m, f, sir_let(m, "sel" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_fi(m, "r_sunel" as *u8), ws_f(m, "4096.0" as *u8), T_F32)))
147 ws_st(m, f, sir_let(m, "df" as *u8, T_F32, ws_c2(m, "max" as *u8, ws_f(m, "0.0" as *u8), ws_id(m, "sel" as *u8, T_F32), T_F32)))
148 ws_st(m, f, sir_let(m, "dl2" as *u8, T_F32, ws_bin(m, "+" as *u8, ws_f(m, "0.22" as *u8), ws_bin(m, "*" as *u8, ws_f(m, "0.78" as *u8), ws_c2(m, "pow" as *u8, ws_id(m, "df" as *u8, T_F32), ws_f(m, "0.6" as *u8), T_F32), T_F32), T_F32)))
149 ws_st(m, f, sir_let(m, "nn" as *u8, T_F32, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_id(m, "dl2" as *u8, T_F32), T_F32)))
150 ws_st(m, f, sir_let(m, "dfr" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_fi(m, "r_dayt" as *u8), ws_c2(m, "max" as *u8, ws_f(m, "1.0" as *u8), ws_fi(m, "r_dlen" as *u8), T_F32), T_F32)))
151 ws_st(m, f, sir_let(m, "az" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_f(m, "3.14159265" as *u8), ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_bin(m, "*" as *u8, ws_id(m, "dfr" as *u8, T_F32), ws_f(m, "1.6" as *u8), T_F32), T_F32), T_F32)))
152 ws_st(m, f, sir_let(m, "el" as *u8, T_F32, ws_c1(m, "asin" as *u8, ws_c3(m, "clamp" as *u8, ws_id(m, "sel" as *u8, T_F32), ws_f(m, "-0.99" as *u8), ws_f(m, "0.99" as *u8), T_F32), T_F32)))
153 ws_st(m, f, sir_let(m, "sd" as *u8, T_V3F, ws_v3(m, ws_bin(m, "*" as *u8, ws_c1(m, "cos" as *u8, ws_id(m, "el" as *u8, T_F32), T_F32), ws_c1(m, "cos" as *u8, ws_id(m, "az" as *u8, T_F32), T_F32), T_F32), ws_c1(m, "sin" as *u8, ws_id(m, "el" as *u8, T_F32), T_F32), ws_bin(m, "*" as *u8, ws_c1(m, "cos" as *u8, ws_id(m, "el" as *u8, T_F32), T_F32), ws_f(m, "0.45" as *u8), T_F32))))
154 ws_st(m, f, sir_let(m, "sdl" as *u8, T_F32, ws_c1(m, "length" as *u8, ws_id(m, "sd" as *u8, T_V3F), T_F32)))
155 ws_st(m, f, ws_set(m, ws_id(m, "sund" as *u8, T_V3F), ws_bin(m, "/" as *u8, ws_id(m, "sd" as *u8, T_V3F), sir_select(m, ws_cmp(m, "==" as *u8, ws_id(m, "sdl" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_f(m, "1.0" as *u8), ws_id(m, "sdl" as *u8, T_F32), T_F32), T_V3F)))
156 ws_st(m, f, ws_set(m, ws_id(m, "rain" as *u8, T_F32), ws_fi(m, "r_rain" as *u8)))
157 ws_st(m, f, ws_set(m, ws_id(m, "skt" as *u8, T_V3F), ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_c1(m, "rgb9" as *u8, ws_id(m, "r_skt" as *u8, T_U32), T_V3F), ws_id(m, "dl2" as *u8, T_F32), T_V3F), ws_bin(m, "*" as *u8, ws_v3f(m, "0.02" as *u8, "0.03" as *u8, "0.10" as *u8), ws_id(m, "nn" as *u8, T_F32), T_V3F), T_V3F)))
158 ws_st(m, f, ws_set(m, ws_id(m, "skh" as *u8, T_V3F), ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_c1(m, "rgb9" as *u8, ws_id(m, "r_skh" as *u8, T_U32), T_V3F), ws_id(m, "dl2" as *u8, T_F32), T_V3F), ws_bin(m, "*" as *u8, ws_v3f(m, "0.04" as *u8, "0.05" as *u8, "0.12" as *u8), ws_id(m, "nn" as *u8, T_F32), T_V3F), T_V3F)))
159 ws_st(m, f, ws_set(m, ws_id(m, "sun" as *u8, T_F32), sir_select(m, ws_and(m, ws_cmp(m, "==" as *u8, ws_id(m, "r_sun" as *u8, T_I32), ws_i(m, "1" as *u8)), ws_cmp(m, ">" as *u8, ws_id(m, "df" as *u8, T_F32), ws_f(m, "0.04" as *u8))), ws_f(m, "1.0" as *u8), ws_f(m, "0.0" as *u8), T_F32)))
160 ws_st(m, f, ws_set(m, ws_id(m, "cld" as *u8, T_F32), ws_fi(m, "r_cld" as *u8)))
161 ws_st(m, f, ws_set(m, ws_id(m, "res" as *u8, T_V2F), ws_v2(m, ws_fi(m, "r_resw" as *u8), ws_fi(m, "r_resh" as *u8))))
162 ws_st(m, f, ws_set(m, ws_id(m, "wmax" as *u8, T_F32), ws_fi(m, "r_wmax" as *u8)))
163 ws_st(m, f, ws_set(m, ws_id(m, "selb" as *u8, T_F32), ws_fi(m, "r_selb" as *u8)))
164 ws_st(m, f, ws_set(m, ws_id(m, "hok" as *u8, T_F32), ws_fi(m, "r_hok" as *u8)))
165 ws_st(m, f, ws_set(m, ws_id(m, "npct" as *u8, T_F32), ws_fi(m, "r_npct" as *u8)))
166 ws_st(m, f, ws_set(m, ws_id(m, "yflip" as *u8, T_F32), ws_fi(m, "r_yflip" as *u8)))
167 ws_pal(m, f, "pal" as *u8, "0" as *u8, "r_pal0" as *u8); ws_pal(m, f, "pal" as *u8, "1" as *u8, "r_pal1" as *u8); ws_pal(m, f, "pal" as *u8, "2" as *u8, "r_pal2" as *u8)
168 ws_pal(m, f, "pal" as *u8, "3" as *u8, "r_pal3" as *u8); ws_pal(m, f, "pal" as *u8, "4" as *u8, "r_pal4" as *u8); ws_pal(m, f, "pal" as *u8, "5" as *u8, "r_pal5" as *u8)
169 ws_pal(m, f, "pal" as *u8, "6" as *u8, "r_pal6" as *u8); ws_pal(m, f, "pal" as *u8, "7" as *u8, "r_pal7" as *u8); ws_pal(m, f, "pal" as *u8, "8" as *u8, "r_pal8" as *u8)
170 ws_pal(m, f, "pal" as *u8, "9" as *u8, "r_pal9" as *u8); ws_pal(m, f, "pal" as *u8, "10" as *u8, "r_pal10" as *u8); ws_pal(m, f, "pal" as *u8, "11" as *u8, "r_pal11" as *u8)
171 ws_pal(m, f, "palf" as *u8, "0" as *u8, "r_palf0" as *u8); ws_pal(m, f, "palf" as *u8, "1" as *u8, "r_palf1" as *u8); ws_pal(m, f, "palf" as *u8, "2" as *u8, "r_palf2" as *u8)
172 ws_pal(m, f, "palf" as *u8, "3" as *u8, "r_palf3" as *u8); ws_pal(m, f, "palf" as *u8, "4" as *u8, "r_palf4" as *u8)
173 return f
174}
175
176// fn vx(c:vec3i)->u32{if(c.x<0||c.y<0||c.z<0||c.x>127||c.y>47||c.z>127){return 0u;}return textureLoad(tV,vec3i(c.x,c.z,c.y),0).r;}
177func ws_fn_vx(m: *i64) -> i64 {
178 let f: i64 = sir_func(m, "vx" as *u8, T_U32)
179 sir_param(m, f, "c" as *u8, T_V3I)
180 let c0: i64 = ws_or(m, ws_or(m, ws_or(m, ws_or(m, ws_or(m,
181 ws_cmp(m, "<" as *u8, ws_sx(m, "c" as *u8, T_V3I, "x" as *u8, T_I32), ws_i(m, "0" as *u8)),
182 ws_cmp(m, "<" as *u8, ws_sx(m, "c" as *u8, T_V3I, "y" as *u8, T_I32), ws_i(m, "0" as *u8))),
183 ws_cmp(m, "<" as *u8, ws_sx(m, "c" as *u8, T_V3I, "z" as *u8, T_I32), ws_i(m, "0" as *u8))),
184 ws_cmp(m, ">" as *u8, ws_sx(m, "c" as *u8, T_V3I, "x" as *u8, T_I32), ws_i(m, "127" as *u8))),
185 ws_cmp(m, ">" as *u8, ws_sx(m, "c" as *u8, T_V3I, "y" as *u8, T_I32), ws_i(m, "47" as *u8))),
186 ws_cmp(m, ">" as *u8, ws_sx(m, "c" as *u8, T_V3I, "z" as *u8, T_I32), ws_i(m, "127" as *u8)))
187 ws_st(m, f, ws_if(m, c0, ws_ret(m, ws_u(m, "0" as *u8)), 0))
188 let co: i64 = ws_v3i(m, ws_sx(m, "c" as *u8, T_V3I, "x" as *u8, T_I32), ws_sx(m, "c" as *u8, T_V3I, "z" as *u8, T_I32), ws_sx(m, "c" as *u8, T_V3I, "y" as *u8, T_I32))
189 let tl: i64 = sir_texload(m, ws_id(m, "tV" as *u8, T_TEX3U), co, ws_i(m, "0" as *u8))
190 ws_st(m, f, ws_ret(m, ws_sw(m, tl, "r" as *u8, T_U32)))
191 return f
192}
193
194// fn h21(p:vec2f)->f32{return fract(sin(dot(p,vec2f(127.1,311.7)))*43758.5453);}
195func ws_fn_h21(m: *i64) -> i64 {
196 let f: i64 = sir_func(m, "h21" as *u8, T_F32)
197 sir_param(m, f, "p" as *u8, T_V2F)
198 let d: i64 = ws_c2(m, "dot" as *u8, ws_id(m, "p" as *u8, T_V2F), ws_v2f(m, "127.1" as *u8, "311.7" as *u8), T_F32)
199 ws_st(m, f, ws_ret(m, ws_c1(m, "fract" as *u8, ws_bin(m, "*" as *u8, ws_c1(m, "sin" as *u8, d, T_F32), ws_f(m, "43758.5453" as *u8), T_F32), T_F32)))
200 return f
201}
202
203// fn h31(p:vec3f)->f32{return fract(sin(dot(p,vec3f(127.1,311.7,74.7)))*43758.5453);}
204func ws_fn_h31(m: *i64) -> i64 {
205 let f: i64 = sir_func(m, "h31" as *u8, T_F32)
206 sir_param(m, f, "p" as *u8, T_V3F)
207 let d: i64 = ws_c2(m, "dot" as *u8, ws_id(m, "p" as *u8, T_V3F), ws_v3f(m, "127.1" as *u8, "311.7" as *u8, "74.7" as *u8), T_F32)
208 ws_st(m, f, ws_ret(m, ws_c1(m, "fract" as *u8, ws_bin(m, "*" as *u8, ws_c1(m, "sin" as *u8, d, T_F32), ws_f(m, "43758.5453" as *u8), T_F32), T_F32)))
209 return f
210}
211
212// fn pal9(b:u32)->vec3f{var i:i32=i32(b);if(i<0){i=0;}if(i>16){i=16;}if(i<12){return u.pal[i].xyz;}return u.palf[i-12].xyz;}
213func ws_fn_pal9(m: *i64) -> i64 {
214 let f: i64 = sir_func(m, "pal9" as *u8, T_V3F)
215 sir_param(m, f, "b" as *u8, T_U32)
216 ws_st(m, f, sir_var(m, "i" as *u8, T_I32, sir_cast(m, ws_id(m, "b" as *u8, T_U32), T_I32)))
217 ws_st(m, f, ws_if(m, ws_cmp(m, "<" as *u8, ws_id(m, "i" as *u8, T_I32), ws_i(m, "0" as *u8)), ws_set(m, ws_id(m, "i" as *u8, T_I32), ws_i(m, "0" as *u8)), 0))
218 ws_st(m, f, ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "i" as *u8, T_I32), ws_i(m, "16" as *u8)), ws_set(m, ws_id(m, "i" as *u8, T_I32), ws_i(m, "16" as *u8)), 0))
219 let pal: i64 = ws_sw(m, sir_index(m, ws_id(m, "pal" as *u8, T_V4F), ws_id(m, "i" as *u8, T_I32), T_V4F), "xyz" as *u8, T_V3F)
220 ws_st(m, f, ws_if(m, ws_cmp(m, "<" as *u8, ws_id(m, "i" as *u8, T_I32), ws_i(m, "12" as *u8)), ws_ret(m, pal), 0))
221 let palf: i64 = ws_sw(m, sir_index(m, ws_id(m, "palf" as *u8, T_V4F), ws_bin(m, "-" as *u8, ws_id(m, "i" as *u8, T_I32), ws_i(m, "12" as *u8), T_I32), T_V4F), "xyz" as *u8, T_V3F)
222 ws_st(m, f, ws_ret(m, palf))
223 return f
224}
225
226// the 2-octave hash noise used by sky: mix(mix(h21(i),h21(i+(1,0)),f.x),mix(h21(i+(0,1)),h21(i+(1,1)),f.x),f.y)
227func ws_noise2(m: *i64, iname: *u8, fname: *u8) -> i64 {
228 let a: i64 = ws_c1(m, "h21" as *u8, ws_id(m, iname, T_V2F), T_F32)
229 let b: i64 = ws_c1(m, "h21" as *u8, ws_bin(m, "+" as *u8, ws_id(m, iname, T_V2F), ws_v2f(m, "1.0" as *u8, "0.0" as *u8), T_V2F), T_F32)
230 let c: i64 = ws_c1(m, "h21" as *u8, ws_bin(m, "+" as *u8, ws_id(m, iname, T_V2F), ws_v2f(m, "0.0" as *u8, "1.0" as *u8), T_V2F), T_F32)
231 let d: i64 = ws_c1(m, "h21" as *u8, ws_bin(m, "+" as *u8, ws_id(m, iname, T_V2F), ws_v2f(m, "1.0" as *u8, "1.0" as *u8), T_V2F), T_F32)
232 let m1: i64 = ws_c3(m, "mix" as *u8, a, b, ws_sx(m, fname, T_V2F, "x" as *u8, T_F32), T_F32)
233 let m2: i64 = ws_c3(m, "mix" as *u8, c, d, ws_sx(m, fname, T_V2F, "x" as *u8, T_F32), T_F32)
234 return ws_c3(m, "mix" as *u8, m1, m2, ws_sx(m, fname, T_V2F, "y" as *u8, T_F32), T_F32)
235}
236
237// ---- PG22 (2026-09-06): THE VOLUMETRIC WEATHER FIELD ON THE GPU DOOR -- the sky's cloud is a 3D density RAYMARCHED,
238// never a sheet. This is nx_worldgen.wg_cloud_volume's law spoken in the shader dialect: 3D value noise on h31 (three
239// octaves), a vertical envelope between CB_BASE and CB_TOP, and a coverage threshold driven by the weather's cloud
240// param (cld); the CPU tier keeps drawing the sheet (nx_worldgen.wg_cloud_sheet) and nx_cloud_volume_gate proves the
241// volume follows the weather field. The march is one slab, entry to exit in CB_STEPS steps, front-to-back transmittance,
242// lit by a base-to-top gradient plus a silver term toward the sun. Every number is a named string const (a data hook
243// until the weather table carries it). The hand text, statement for statement:
244// fn vn3(q:vec3f)->f32{let i=floor(q);let f0=fract(q);let f=f0*f0*(3.0-f0*2.0);let a=h31(i);let b=h31(i+vec3f(1,0,0));...;let k=h31(i+vec3f(1,1,1));return mix(mix(mix(a,b,f.x),mix(c,d,f.x),f.y),mix(mix(e,g,f.x),mix(h,k,f.x),f.y),f.z);}
245// World-unit artistic cumulus profile, emitted through existing shared IR; not measured weather.
246const CC_BODY_XZ: *u8 = "64.0"
247const CC_BODY_Y: *u8 = "48.0"
248const CC_DETAIL_XZ: *u8 = "8.0"
249const CC_DETAIL_Y: *u8 = "8.0"
250const CC_OCTAVE_LACUNARITY: *u8 = "2.0"
251const CC_OCTAVE_PERSISTENCE: *u8 = "0.5"
252
253const CB_BASE: *u8 = "180.0" // the incumbent sheet's height in blocks, now the slab base
254const CB_TOP: *u8 = "300.0"
255const CB_RLO: *u8 = "24.0" // density ramps in over this many blocks above the base
256const CB_RHI: *u8 = "48.0" // and out over this many below the top
257const CB_CELL: *u8 = "180.0" // one noise cell in blocks, horizontal
258const CB_CELLY: *u8 = "120.0" // and vertical (flatter cells read as stratus)
259const CB_DRIFT_X: *u8 = "240.0" // the incumbent sheet's drift divisors, kept so the motion does not change
260const CB_DRIFT_Z: *u8 = "540.0"
261const CB_THR0: *u8 = "0.78" // coverage threshold at cld=0
262const CB_THRK: *u8 = "0.30" // and how far cld=1 lowers it
263const CB_GAIN: *u8 = "1.4"
264const CB_STEPS: *u8 = "48"
265const CB_STEPS_F: *u8 = "48.0"
266const CB_SIGMA: *u8 = "0.04" // extinction per block of unit density
267const CB_LIT0: *u8 = "0.70" // ambient at the base
268const CB_LIT1: *u8 = "0.30" // brighter toward the top
269const CB_SUNK: *u8 = "0.15" // silver toward the sun
270
271// PRIVATE cloud profile: world-unit artistic defaults, not measured weather.
272// Six sun-ray samples follow the existing banked cloud contract; view/light budgets require device qualification.
273const CB_EROSION: *u8 = "0.22"
274const CB_SUN_Y_MIN: *u8 = "0.01"
275const CB_LIGHT_DISTANCE: *u8 = "480.0"
276const CB_LIGHT_STEPS: *u8 = "6"
277const CB_LIGHT_STEPS_F: *u8 = "6.0"
278const CB_VIEW_DISTANCE: *u8 = "1400.0"
279const CB_PHASE_G: *u8 = "0.35"
280const CB_AMBIENT: *u8 = "0.85"
281const CB_DIRECT: *u8 = "0.72"
282func ws_h31o(m: *i64, a: *u8, b: *u8, c: *u8) -> i64 {
283 return ws_c1(m, "h31" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "i" as *u8, T_V3F), ws_v3f(m, a, b, c), T_V3F), T_F32)
284}
285func ws_fx(m: *i64, sel: *u8) -> i64 { return ws_sx(m, "f" as *u8, T_V3F, sel, T_F32) }
286func ws_py(m: *i64) -> i64 { return ws_sx(m, "p" as *u8, T_V3F, "y" as *u8, T_F32) }
287// fn vn3(q:vec3f)->f32 -- 3D value noise on h31, trilinear with a smoothstep fade (the shape of noise2 lifted one axis)
288func ws_fn_vn3(m: *i64) -> i64 {
289 let f: i64 = sir_func(m, "vn3" as *u8, T_F32)
290 sir_param(m, f, "q" as *u8, T_V3F)
291 ws_st(m, f, sir_let(m, "i" as *u8, T_V3F, ws_c1(m, "floor" as *u8, ws_id(m, "q" as *u8, T_V3F), T_V3F)))
292 ws_st(m, f, sir_let(m, "f0" as *u8, T_V3F, ws_c1(m, "fract" as *u8, ws_id(m, "q" as *u8, T_V3F), T_V3F)))
293 ws_st(m, f, sir_let(m, "f" as *u8, T_V3F, ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "f0" as *u8, T_V3F), ws_id(m, "f0" as *u8, T_V3F), T_V3F), ws_bin(m, "-" as *u8, ws_v1(m, T_V3F, ws_f(m, "3.0" as *u8)), ws_bin(m, "*" as *u8, ws_id(m, "f0" as *u8, T_V3F), ws_f(m, "2.0" as *u8), T_V3F), T_V3F), T_V3F)))
294 ws_st(m, f, sir_let(m, "a" as *u8, T_F32, ws_c1(m, "h31" as *u8, ws_id(m, "i" as *u8, T_V3F), T_F32)))
295 ws_st(m, f, sir_let(m, "b" as *u8, T_F32, ws_h31o(m, "1.0" as *u8, "0.0" as *u8, "0.0" as *u8)))
296 ws_st(m, f, sir_let(m, "c" as *u8, T_F32, ws_h31o(m, "0.0" as *u8, "1.0" as *u8, "0.0" as *u8)))
297 ws_st(m, f, sir_let(m, "d" as *u8, T_F32, ws_h31o(m, "1.0" as *u8, "1.0" as *u8, "0.0" as *u8)))
298 ws_st(m, f, sir_let(m, "e" as *u8, T_F32, ws_h31o(m, "0.0" as *u8, "0.0" as *u8, "1.0" as *u8)))
299 ws_st(m, f, sir_let(m, "g" as *u8, T_F32, ws_h31o(m, "1.0" as *u8, "0.0" as *u8, "1.0" as *u8)))
300 ws_st(m, f, sir_let(m, "h" as *u8, T_F32, ws_h31o(m, "0.0" as *u8, "1.0" as *u8, "1.0" as *u8)))
301 ws_st(m, f, sir_let(m, "k" as *u8, T_F32, ws_h31o(m, "1.0" as *u8, "1.0" as *u8, "1.0" as *u8)))
302 let x0: i64 = ws_c3(m, "mix" as *u8, ws_c3(m, "mix" as *u8, ws_id(m, "a" as *u8, T_F32), ws_id(m, "b" as *u8, T_F32), ws_fx(m, "x" as *u8), T_F32), ws_c3(m, "mix" as *u8, ws_id(m, "c" as *u8, T_F32), ws_id(m, "d" as *u8, T_F32), ws_fx(m, "x" as *u8), T_F32), ws_fx(m, "y" as *u8), T_F32)
303 let x1: i64 = ws_c3(m, "mix" as *u8, ws_c3(m, "mix" as *u8, ws_id(m, "e" as *u8, T_F32), ws_id(m, "g" as *u8, T_F32), ws_fx(m, "x" as *u8), T_F32), ws_c3(m, "mix" as *u8, ws_id(m, "h" as *u8, T_F32), ws_id(m, "k" as *u8, T_F32), ws_fx(m, "x" as *u8), T_F32), ws_fx(m, "y" as *u8), T_F32)
304 ws_st(m, f, ws_ret(m, ws_c3(m, "mix" as *u8, x0, x1, ws_fx(m, "z" as *u8), T_F32)))
305 return f
306}
307// fn cvol(p:vec3f)->f32 -- the cloud density at a world point: three octaves, the envelope, the coverage threshold
308func ws_fn_cvol(m: *i64) -> i64 {
309 let f: i64 = sir_func(m, "cvol" as *u8, T_F32)
310 sir_param(m, f, "p" as *u8, T_V3F)
311 ws_st(m, f, sir_let(m, "hf" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_sx(m, "p" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, CB_BASE), T_F32), ws_bin(m, "-" as *u8, ws_f(m, CB_TOP), ws_f(m, CB_BASE), T_F32), T_F32)))
312 ws_st(m, f, sir_let(m, "wind" as *u8, T_V3F, ws_v3(m, ws_bin(m, "*" as *u8, ws_bin(m, "/" as *u8, ws_id(m, "t" as *u8, T_F32), ws_f(m, CB_DRIFT_X), T_F32), ws_f(m, CB_CELL), T_F32),ws_f(m, "0.0" as *u8),ws_bin(m, "*" as *u8, ws_bin(m, "/" as *u8, ws_id(m, "t" as *u8, T_F32), ws_f(m, CB_DRIFT_Z), T_F32), ws_f(m, CB_CELL), T_F32))))
313 ws_st(m, f, sir_let(m, "pos" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_id(m, "p" as *u8, T_V3F), ws_id(m, "wind" as *u8, T_V3F), T_V3F)))
314 ws_st(m, f, sir_let(m, "q" as *u8, T_V3F, ws_bin(m, "/" as *u8, ws_id(m, "pos" as *u8, T_V3F), ws_v3(m,ws_f(m, CC_BODY_XZ),ws_f(m, CC_BODY_Y),ws_f(m, CC_BODY_XZ)), T_V3F)))
315 ws_st(m, f, sir_let(m, "n0" as *u8, T_F32, ws_c1(m, "vn3" as *u8, ws_id(m, "q" as *u8, T_V3F), T_F32)))
316 ws_st(m, f, sir_let(m, "n1" as *u8, T_F32, ws_c1(m, "vn3" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "q" as *u8, T_V3F), ws_f(m, CC_OCTAVE_LACUNARITY), T_V3F), T_F32)))
317 ws_st(m, f, sir_let(m, "n2" as *u8, T_F32, ws_c1(m, "vn3" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "q" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_f(m, CC_OCTAVE_LACUNARITY), ws_f(m, CC_OCTAVE_LACUNARITY), T_F32), T_V3F), T_F32)))
318 ws_st(m, f, sir_let(m, "shape" as *u8, T_F32, ws_bin(m, "+" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "n0" as *u8, T_F32), ws_bin(m, "*" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "n1" as *u8, T_F32), ws_f(m, "0.5" as *u8), T_F32), ws_f(m, CC_OCTAVE_PERSISTENCE), T_F32), T_F32), ws_bin(m, "*" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "n2" as *u8, T_F32), ws_f(m, "0.5" as *u8), T_F32), ws_bin(m, "*" as *u8, ws_f(m, CC_OCTAVE_PERSISTENCE), ws_f(m, CC_OCTAVE_PERSISTENCE), T_F32), T_F32), T_F32)))
319 ws_st(m, f, sir_let(m, "detail" as *u8, T_F32, ws_c1(m, "vn3" as *u8, ws_bin(m, "/" as *u8, ws_id(m, "pos" as *u8, T_V3F), ws_v3(m,ws_f(m, CC_DETAIL_XZ),ws_f(m, CC_DETAIL_Y),ws_f(m, CC_DETAIL_XZ)), T_V3F), T_F32)))
320 ws_st(m, f, sir_let(m, "env" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_c3(m, "smoothstep" as *u8, ws_f(m, "0.0" as *u8), ws_bin(m, "/" as *u8, ws_f(m, CB_RLO), ws_bin(m, "-" as *u8, ws_f(m, CB_TOP), ws_f(m, CB_BASE), T_F32), T_F32), ws_id(m, "hf" as *u8, T_F32), T_F32), ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_c3(m, "smoothstep" as *u8, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_bin(m, "/" as *u8, ws_f(m, CB_RHI), ws_bin(m, "-" as *u8, ws_f(m, CB_TOP), ws_f(m, CB_BASE), T_F32), T_F32), T_F32), ws_f(m, "1.0" as *u8), ws_id(m, "hf" as *u8, T_F32), T_F32), T_F32), T_F32)))
321 ws_st(m, f, sir_let(m, "thr" as *u8, T_F32, ws_bin(m, "-" as *u8, ws_f(m, CB_THR0), ws_bin(m, "*" as *u8, ws_f(m, CB_THRK), ws_c3(m, "clamp" as *u8, ws_id(m, "cld" as *u8, T_F32), ws_f(m, "0.0" as *u8), ws_f(m, "1.0" as *u8), T_F32), T_F32), T_F32)))
322 ws_st(m, f, sir_let(m, "body" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "shape" as *u8, T_F32), ws_id(m, "thr" as *u8, T_F32), T_F32), ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_id(m, "thr" as *u8, T_F32), T_F32), T_F32)))
323 ws_st(m, f, sir_let(m, "eroded" as *u8, T_F32, ws_bin(m, "-" as *u8, ws_id(m, "body" as *u8, T_F32), ws_bin(m, "*" as *u8, ws_id(m, "detail" as *u8, T_F32), ws_f(m, CB_EROSION), T_F32), T_F32)))
324 ws_st(m, f, ws_ret(m, ws_bin(m, "*" as *u8, ws_c3(m, "clamp" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "eroded" as *u8, T_F32), ws_f(m, CB_GAIN), T_F32), ws_f(m, "0.0" as *u8), ws_f(m, "1.0" as *u8), T_F32), ws_id(m, "env" as *u8, T_F32), T_F32)))
325
326 return f
327}
328
329func ws_fn_csun(m: *i64) -> i64 {
330 let f: i64 = sir_func(m, "csun" as *u8, T_F32)
331 sir_param(m, f, "p" as *u8, T_V3F)
332 ws_st(m, f, sir_let(m, "dy" as *u8, T_F32, ws_c2(m, "max" as *u8, ws_sx(m, "sund" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, CB_SUN_Y_MIN), T_F32)))
333 ws_st(m, f, sir_let(m, "ds" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_c2(m, "min" as *u8, ws_bin(m, "/" as *u8, ws_c2(m, "max" as *u8, ws_bin(m, "-" as *u8, ws_f(m, CB_TOP), ws_sx(m, "p" as *u8, T_V3F, "y" as *u8, T_F32), T_F32), ws_f(m, "0.0" as *u8), T_F32), ws_id(m, "dy" as *u8, T_F32), T_F32), ws_f(m, CB_LIGHT_DISTANCE), T_F32), ws_f(m, CB_LIGHT_STEPS_F), T_F32)))
334 ws_st(m, f, sir_var(m, "tau" as *u8, T_F32, ws_f(m, "0.0" as *u8)))
335 let lp: i64 = sir_let(m, "lp" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_id(m, "p" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "sund" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_bin(m, "+" as *u8, ws_fi(m, "j" as *u8), ws_f(m, "0.5" as *u8), T_F32), ws_id(m, "ds" as *u8, T_F32), T_F32), T_V3F), T_V3F))
336 let lt: i64 = ws_op(m, "tau" as *u8, T_F32, "+" as *u8, ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_c1(m, "cvol" as *u8, ws_id(m, "lp" as *u8, T_V3F), T_F32), ws_id(m, "ds" as *u8, T_F32), T_F32), ws_f(m, CB_SIGMA), T_F32))
337 sir_for_until(m, f, sir_var(m, "j" as *u8, T_I32, ws_i(m, "0" as *u8)), ws_cmp(m, ">=" as *u8, ws_id(m, "j" as *u8, T_I32), ws_i(m, CB_LIGHT_STEPS)), ws_op(m, "j" as *u8, T_I32, "+" as *u8, ws_i(m, "1" as *u8)), ws_q2(m, lp, lt))
338 ws_st(m, f, ws_ret(m, ws_c1(m, "exp" as *u8, ws_bin(m, "-" as *u8, ws_f(m, "0.0" as *u8), ws_id(m, "tau" as *u8, T_F32), T_F32), T_F32)))
339 return f
340}
341// Shared cloud transport convention; density and terrain remain separate owners.
342// Relative scene radiance is reconstructed by inverse of nx_tonemap_aces Q10 rational fit plus nx_atmosphere sqrt convention.
343// This cannot recover clipped physical energy. Palette1 is representative primary-land albedo, not measured hemispheric irradiance.
344// Solar irradiance separates scalar inverse-tone intensity from squared authored RGB chromaticity; per-channel inverse near clipping amplified false warm colors. Relative, not calibrated.
345// Two scattering octaves (half extinction, half contribution, half anisotropy) approximate higher orders, not a path-traced solution.
346// One cloud tone/display encode after linear composite. Incumbent final world grade remains downstream.
347func ws_fn_cloud_decode(m: *i64) -> i64 {
348 let f: i64 = sir_func(m, "cloud_decode" as *u8, T_V3F)
349 sir_param(m, f, "display" as *u8, T_V3F)
350 ws_st(m, f, sir_let(m, "d" as *u8, T_V3F, ws_c3(m, "clamp" as *u8, ws_id(m, "display" as *u8, T_V3F), ws_v1(m, T_V3F, ws_f(m, "0.0" as *u8)), ws_v1(m, T_V3F, ws_f(m, "1.0" as *u8)), T_V3F)))
351 ws_st(m, f, sir_let(m, "y" as *u8, T_V3F, ws_bin(m, "*" as *u8, ws_id(m, "d" as *u8, T_V3F), ws_id(m, "d" as *u8, T_V3F), T_V3F)))
352 ws_st(m, f, sir_let(m, "a" as *u8, T_V3F, ws_bin(m, "-" as *u8, ws_v1(m, T_V3F, ws_f(m, "2.509765625" as *u8)), ws_bin(m, "*" as *u8, ws_f(m, "2.4296875" as *u8), ws_id(m, "y" as *u8, T_V3F), T_V3F), T_V3F)))
353 ws_st(m, f, sir_let(m, "b" as *u8, T_V3F, ws_bin(m, "-" as *u8, ws_v1(m, T_V3F, ws_f(m, "0.0302734375" as *u8)), ws_bin(m, "*" as *u8, ws_f(m, "0.58984375" as *u8), ws_id(m, "y" as *u8, T_V3F), T_V3F), T_V3F)))
354 ws_st(m, f, sir_let(m, "disc" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "b" as *u8, T_V3F), ws_id(m, "b" as *u8, T_V3F), T_V3F), ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_f(m, "4.0" as *u8), ws_id(m, "a" as *u8, T_V3F), T_V3F), ws_bin(m, "*" as *u8, ws_f(m, "0.1396484375" as *u8), ws_id(m, "y" as *u8, T_V3F), T_V3F), T_V3F), T_V3F)))
355 ws_st(m, f, ws_ret(m, ws_bin(m, "/" as *u8, ws_bin(m, "+" as *u8, ws_bin(m, "-" as *u8, ws_v1(m, T_V3F, ws_f(m, "0.0" as *u8)), ws_id(m, "b" as *u8, T_V3F), T_V3F), ws_c1(m, "sqrt" as *u8, ws_id(m, "disc" as *u8, T_V3F), T_V3F), T_V3F), ws_bin(m, "*" as *u8, ws_f(m, "2.0" as *u8), ws_id(m, "a" as *u8, T_V3F), T_V3F), T_V3F)))
356 return f
357}
358func ws_fn_cloud_encode(m: *i64) -> i64 {
359 let f: i64 = sir_func(m, "cloud_encode" as *u8, T_V3F)
360 sir_param(m, f, "radiance" as *u8, T_V3F)
361 ws_st(m, f, sir_let(m, "x" as *u8, T_V3F, ws_c2(m, "max" as *u8, ws_id(m, "radiance" as *u8, T_V3F), ws_v1(m, T_V3F, ws_f(m, "0.0" as *u8)), T_V3F)))
362 ws_st(m, f, sir_let(m, "num" as *u8, T_V3F, ws_bin(m, "*" as *u8, ws_id(m, "x" as *u8, T_V3F), ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_f(m, "2.509765625" as *u8), ws_id(m, "x" as *u8, T_V3F), T_V3F), ws_v1(m, T_V3F, ws_f(m, "0.0302734375" as *u8)), T_V3F), T_V3F)))
363 ws_st(m, f, sir_let(m, "den" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "x" as *u8, T_V3F), ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_f(m, "2.4296875" as *u8), ws_id(m, "x" as *u8, T_V3F), T_V3F), ws_v1(m, T_V3F, ws_f(m, "0.58984375" as *u8)), T_V3F), T_V3F), ws_v1(m, T_V3F, ws_f(m, "0.1396484375" as *u8)), T_V3F)))
364 ws_st(m, f, ws_ret(m, ws_c1(m, "sqrt" as *u8, ws_c3(m, "clamp" as *u8, ws_bin(m, "/" as *u8, ws_id(m, "num" as *u8, T_V3F), ws_id(m, "den" as *u8, T_V3F), T_V3F), ws_v1(m, T_V3F, ws_f(m, "0.0" as *u8)), ws_v1(m, T_V3F, ws_f(m, "1.0" as *u8)), T_V3F), T_V3F)))
365 return f
366}
367func ws_fn_cloud_phase(m: *i64) -> i64 {
368 let f: i64 = sir_func(m, "cloud_phase" as *u8, T_F32)
369 sir_param(m, f, "mu" as *u8, T_F32)
370 sir_param(m, f, "g" as *u8, T_F32)
371 ws_st(m, f, ws_ret(m, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_bin(m, "*" as *u8, ws_id(m, "g" as *u8, T_F32), ws_id(m, "g" as *u8, T_F32), T_F32), T_F32), ws_bin(m, "*" as *u8, ws_f(m, "12.566370614359172" as *u8), ws_c2(m, "pow" as *u8, ws_bin(m, "-" as *u8, ws_bin(m, "+" as *u8, ws_f(m, "1.0" as *u8), ws_bin(m, "*" as *u8, ws_id(m, "g" as *u8, T_F32), ws_id(m, "g" as *u8, T_F32), T_F32), T_F32), ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_f(m, "2.0" as *u8), ws_id(m, "g" as *u8, T_F32), T_F32), ws_c3(m, "clamp" as *u8, ws_id(m, "mu" as *u8, T_F32), ws_f(m, "-1.0" as *u8), ws_f(m, "1.0" as *u8), T_F32), T_F32), T_F32), ws_f(m, "1.5" as *u8), T_F32), T_F32), T_F32)))
372 return f
373}
374func ws_fn_cloud_incident(m: *i64) -> i64 {
375 let f: i64 = sir_func(m, "cloud_incident" as *u8, T_V3F)
376 sir_param(m, f, "p" as *u8, T_V3F)
377 sir_param(m, f, "mu" as *u8, T_F32)
378 ws_st(m, f, sir_let(m, "skyL" as *u8, T_V3F, ws_bin(m, "*" as *u8, ws_bin(m, "+" as *u8, ws_c1(m, "cloud_decode" as *u8, ws_id(m, "skt" as *u8, T_V3F), T_V3F), ws_c1(m, "cloud_decode" as *u8, ws_id(m, "skh" as *u8, T_V3F), T_V3F), T_V3F), ws_f(m, "0.5" as *u8), T_V3F)))
379 ws_st(m, f, sir_let(m, "solarL" as *u8, T_V3F, ws_bin(m, "*" as *u8, ws_c1(m, "cloud_decode" as *u8, ws_v1(m, T_V3F, ws_f(m, "1.0" as *u8)), T_V3F), ws_v3f(m, "1.0" as *u8, "0.9604" as *u8, "0.7744" as *u8), T_V3F)))
380 ws_st(m, f, sir_let(m, "groundA" as *u8, T_V3F, ws_bin(m, "*" as *u8, ws_sw(m, sir_index(m, ws_id(m, "pal" as *u8, T_V4F), ws_i(m, "1" as *u8), T_V4F), "xyz" as *u8, T_V3F), ws_sw(m, sir_index(m, ws_id(m, "pal" as *u8, T_V4F), ws_i(m, "1" as *u8), T_V4F), "xyz" as *u8, T_V3F), T_V3F)))
381 ws_st(m, f, sir_let(m, "groundL" as *u8, T_V3F, ws_bin(m, "*" as *u8, ws_id(m, "groundA" as *u8, T_V3F), ws_bin(m, "+" as *u8, ws_id(m, "skyL" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "solarL" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_f(m, CB_DIRECT), ws_id(m, "sun" as *u8, T_F32), T_F32), ws_c2(m, "max" as *u8, ws_sx(m, "sund" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, "0.0" as *u8), T_F32), T_F32), T_V3F), T_V3F), T_V3F)))
382 ws_st(m, f, sir_let(m, "ambientL" as *u8, T_V3F, ws_bin(m, "*" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "skyL" as *u8, T_V3F), ws_id(m, "groundL" as *u8, T_V3F), T_V3F), ws_bin(m, "*" as *u8, ws_f(m, "0.5" as *u8), ws_f(m, CB_AMBIENT), T_F32), T_V3F)))
383 ws_st(m, f, sir_let(m, "T" as *u8, T_F32, ws_c1(m, "csun" as *u8, ws_id(m, "p" as *u8, T_V3F), T_F32)))
384 ws_st(m, f, sir_let(m, "single" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_id(m, "T" as *u8, T_F32), ws_c2(m, "cloud_phase" as *u8, ws_id(m, "mu" as *u8, T_F32), ws_f(m, CB_PHASE_G), T_F32), T_F32)))
385 ws_st(m, f, sir_let(m, "multiple" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_f(m, "0.5" as *u8), ws_c1(m, "sqrt" as *u8, ws_id(m, "T" as *u8, T_F32), T_F32), T_F32), ws_c2(m, "cloud_phase" as *u8, ws_id(m, "mu" as *u8, T_F32), ws_bin(m, "*" as *u8, ws_f(m, "0.5" as *u8), ws_f(m, CB_PHASE_G), T_F32), T_F32), T_F32)))
386 ws_st(m, f, sir_let(m, "solarWeight" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_f(m, "3.141592653589793" as *u8), ws_f(m, CB_DIRECT), T_F32), ws_id(m, "sun" as *u8, T_F32), T_F32), ws_bin(m, "+" as *u8, ws_id(m, "single" as *u8, T_F32), ws_id(m, "multiple" as *u8, T_F32), T_F32), T_F32)))
387 ws_st(m, f, ws_ret(m, ws_bin(m, "+" as *u8, ws_id(m, "ambientL" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "solarL" as *u8, T_V3F), ws_id(m, "solarWeight" as *u8, T_F32), T_V3F), T_V3F)))
388 return f
389}
390
391func ws_fn_cld3(m: *i64) -> i64 {
392 let f: i64 = sir_func(m, "cld3" as *u8, T_V3F)
393 sir_param(m, f, "rd" as *u8, T_V3F)
394 sir_param(m, f, "s0" as *u8, T_V3F)
395 ws_st(m, f, ws_if(m, ws_cmp(m, "<=" as *u8, ws_id(m, "cld" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_ret(m, ws_id(m, "s0" as *u8, T_V3F)), 0))
396 ws_st(m, f, sir_let(m, "dy" as *u8, T_F32, ws_sx(m, "rd" as *u8, T_V3F, "y" as *u8, T_F32)))
397 ws_st(m, f, ws_if(m, ws_cmp(m, "==" as *u8, ws_id(m, "dy" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_ret(m, ws_id(m, "s0" as *u8, T_V3F)), 0))
398 ws_st(m, f, sir_let(m, "a" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_f(m, CB_BASE), ws_sx(m, "cam" as *u8, T_V3F, "y" as *u8, T_F32), T_F32), ws_id(m, "dy" as *u8, T_F32), T_F32)))
399 ws_st(m, f, sir_let(m, "b" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_f(m, CB_TOP), ws_sx(m, "cam" as *u8, T_V3F, "y" as *u8, T_F32), T_F32), ws_id(m, "dy" as *u8, T_F32), T_F32)))
400 ws_st(m, f, sir_let(m, "t0" as *u8, T_F32, ws_c2(m, "max" as *u8, ws_c2(m, "min" as *u8, ws_id(m, "a" as *u8, T_F32), ws_id(m, "b" as *u8, T_F32), T_F32), ws_f(m, "0.0" as *u8), T_F32)))
401 ws_st(m, f, sir_let(m, "t1" as *u8, T_F32, ws_c2(m, "min" as *u8, ws_c2(m, "max" as *u8, ws_id(m, "a" as *u8, T_F32), ws_id(m, "b" as *u8, T_F32), T_F32), ws_f(m, CB_VIEW_DISTANCE), T_F32)))
402 ws_st(m, f, ws_if(m, ws_cmp(m, "<=" as *u8, ws_id(m, "t1" as *u8, T_F32), ws_id(m, "t0" as *u8, T_F32)), ws_ret(m, ws_id(m, "s0" as *u8, T_V3F)), 0))
403 ws_st(m, f, sir_let(m, "dt" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "t1" as *u8, T_F32), ws_id(m, "t0" as *u8, T_F32), T_F32), ws_f(m, CB_STEPS_F), T_F32)))
404 ws_st(m, f, sir_var(m, "tr" as *u8, T_F32, ws_f(m, "1.0" as *u8)))
405 ws_st(m, f, sir_var(m, "acc" as *u8, T_V3F, ws_v1(m, T_V3F, ws_f(m, "0.0" as *u8))))
406 ws_st(m, f, sir_let(m, "mu" as *u8, T_F32, ws_c3(m, "clamp" as *u8, ws_c2(m, "dot" as *u8, ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "sund" as *u8, T_V3F), T_F32), ws_f(m, "-1.0" as *u8), ws_f(m, "1.0" as *u8), T_F32)))
407 let p0: i64 = sir_let(m, "p" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_id(m, "cam" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "rd" as *u8, T_V3F), ws_bin(m, "+" as *u8, ws_id(m, "t0" as *u8, T_F32), ws_bin(m, "*" as *u8, ws_bin(m, "+" as *u8, ws_fi(m, "i" as *u8), ws_f(m, "0.5" as *u8), T_F32), ws_id(m, "dt" as *u8, T_F32), T_F32), T_F32), T_V3F), T_V3F))
408 let d0: i64 = sir_let(m, "density" as *u8, T_F32, ws_c1(m, "cvol" as *u8, ws_id(m, "p" as *u8, T_V3F), T_F32))
409 let a0: i64 = sir_let(m, "alpha" as *u8, T_F32, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_c1(m, "exp" as *u8, ws_bin(m, "-" as *u8, ws_f(m, "0.0" as *u8), ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "density" as *u8, T_F32), ws_id(m, "dt" as *u8, T_F32), T_F32), ws_f(m, CB_SIGMA), T_F32), T_F32), T_F32), T_F32))
410 let l0: i64 = sir_let(m, "light" as *u8, T_V3F, ws_c2(m, "cloud_incident" as *u8, ws_id(m, "p" as *u8, T_V3F), ws_id(m, "mu" as *u8, T_F32), T_V3F))
411 let c0: i64 = ws_op(m, "acc" as *u8, T_V3F, "+" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "light" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "tr" as *u8, T_F32), ws_id(m, "alpha" as *u8, T_F32), T_F32), T_V3F))
412 let t0s: i64 = ws_op(m, "tr" as *u8, T_F32, "*" as *u8, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_id(m, "alpha" as *u8, T_F32), T_F32))
413 let body: i64 = ws_q2(m, ws_q3(m, p0, d0, a0), ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "density" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_q3(m, l0, c0, t0s), 0))
414 sir_for_until(m, f, sir_var(m, "i" as *u8, T_I32, ws_i(m, "0" as *u8)), ws_cmp(m, ">=" as *u8, ws_id(m, "i" as *u8, T_I32), ws_i(m, CB_STEPS)), ws_op(m, "i" as *u8, T_I32, "+" as *u8, ws_i(m, "1" as *u8)), body)
415 let fog: i64 = ws_c3(m, "smoothstep" as *u8, ws_f(m, "0.0" as *u8), ws_f(m, CB_VIEW_DISTANCE), ws_id(m, "t0" as *u8, T_F32), T_F32)
416 let clearL: i64 = ws_c1(m, "cloud_decode" as *u8, ws_id(m, "s0" as *u8, T_V3F), T_V3F)
417 let composite: i64 = ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, clearL, ws_id(m, "tr" as *u8, T_F32), T_V3F), ws_id(m, "acc" as *u8, T_V3F), T_V3F)
418 let clearFogL: i64 = ws_c1(m, "cloud_decode" as *u8, ws_id(m, "s0" as *u8, T_V3F), T_V3F)
419 ws_st(m, f, ws_ret(m, ws_c1(m, "cloud_encode" as *u8, ws_c3(m, "mix" as *u8, composite, clearFogL, fog, T_V3F), T_V3F)))
420 return f
421}
422func ws_fn_sky(m: *i64) -> i64 {
423 let f: i64 = sir_func(m, "sky" as *u8, T_V3F)
424 sir_param(m, f, "rd" as *u8, T_V3F)
425 // var s:vec3f=mix(u.skh,u.skt,clamp(rd.y*1.6+0.35,0.0,1.0));
426 let cl: i64 = ws_c3(m, "clamp" as *u8, ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_sx(m, "rd" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, "1.6" as *u8), T_F32), ws_f(m, "0.35" as *u8), T_F32), ws_f(m, "0.0" as *u8), ws_f(m, "1.0" as *u8), T_F32)
427 ws_st(m, f, sir_var(m, "s" as *u8, T_V3F, ws_c3(m, "mix" as *u8, ws_id(m, "skh" as *u8, T_V3F), ws_id(m, "skt" as *u8, T_V3F), cl, T_V3F)))
428 // if(u.sun>0.5){let d=dot(rd,u.sund);if(d>0.9993){s=vec3f(1.0,0.98,0.88);}else if(d>0.985){s=mix(s,vec3f(1.0,0.98,0.88),(d-0.985)/0.015*0.6);}}
429 let dlet: i64 = sir_let(m, "d" as *u8, T_F32, ws_c2(m, "dot" as *u8, ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "sund" as *u8, T_V3F), T_F32))
430 let sunc: i64 = ws_set(m, ws_id(m, "s" as *u8, T_V3F), ws_v3f(m, "1.0" as *u8, "0.98" as *u8, "0.88" as *u8))
431 let glow: i64 = ws_set(m, ws_id(m, "s" as *u8, T_V3F), ws_c3(m, "mix" as *u8, ws_id(m, "s" as *u8, T_V3F), ws_v3f(m, "1.0" as *u8, "0.98" as *u8, "0.88" as *u8), ws_bin(m, "*" as *u8, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "d" as *u8, T_F32), ws_f(m, "0.985" as *u8), T_F32), ws_f(m, "0.015" as *u8), T_F32), ws_f(m, "0.6" as *u8), T_F32), T_V3F))
432 let inner: i64 = ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "d" as *u8, T_F32), ws_f(m, "0.9993" as *u8)), sunc, ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "d" as *u8, T_F32), ws_f(m, "0.985" as *u8)), glow, 0))
433 ws_st(m, f, ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "sun" as *u8, T_F32), ws_f(m, "0.5" as *u8)), ws_q2(m, dlet, inner), 0))
434 // PG22: s = cld3(rd, s) -- the cloud is a raymarched 3D density (vn3 / cvol / cld3 above), never the projected
435 // sheet this block used to draw; the cld>0.5 && rd.y>0.04 gate lives inside cld3 as its early return.
436 ws_st(m, f, ws_set(m, ws_id(m, "s" as *u8, T_V3F), ws_c2(m, "cld3" as *u8, ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "s" as *u8, T_V3F), T_V3F)))
437 ws_st(m, f, ws_ret(m, ws_id(m, "s" as *u8, T_V3F)))
438 return f
439}
440
441// struct Hit{t:f32,c:vec3i,fce:i32,b:u32}
442func ws_struct_hit(m: *i64) -> i64 {
443 let st: i64 = sir_struct(m, "Hit" as *u8)
444 sir_member(m, st, "t" as *u8, T_F32)
445 sir_member(m, st, "c" as *u8, T_V3I)
446 sir_member(m, st, "fce" as *u8, T_I32)
447 sir_member(m, st, "b" as *u8, T_U32)
448 return st
449}
450
451// one DDA step: c.<a>=(c.<a>+st.<a>);t=tm.<a>;tm.<a>=(tm.<a>+dd.<a>);fce=select(<f>,<t>,st.<a>>0);
452func ws_dda_step(m: *i64, ax: *u8, fneg: *u8, fpos: *u8) -> i64 {
453 let s1: i64 = ws_opx(m, "c" as *u8, T_V3I, ax, T_I32, "+" as *u8, ws_sx(m, "st" as *u8, T_V3I, ax, T_I32))
454 let s2: i64 = ws_set(m, ws_id(m, "t" as *u8, T_F32), ws_sx(m, "tm" as *u8, T_V3F, ax, T_F32))
455 let s3: i64 = ws_opx(m, "tm" as *u8, T_V3F, ax, T_F32, "+" as *u8, ws_sx(m, "dd" as *u8, T_V3F, ax, T_F32))
456 let s4: i64 = ws_set(m, ws_id(m, "fce" as *u8, T_I32), sir_select(m, ws_cmp(m, ">" as *u8, ws_sx(m, "st" as *u8, T_V3I, ax, T_I32), ws_i(m, "0" as *u8)), ws_i(m, fpos), ws_i(m, fneg), T_I32))
457 return ws_q4(m, s1, s2, s3, s4)
458}
459
460// ---- GE53 THE SURFACE FIELD (WebGPU, emitted from this one source) ---------------------------------------
461// fn hq(x:i32,z:i32)->f32{ if(x<0||z<0||x>127||z>127){return -1.0;} return textureLoad(tH,vec2i(x,z),0).r; }
462// the column's Q height in blocks (the base of its top block), -1 off the window
463func ws_fn_hq(m: *i64) -> i64 {
464 let f: i64 = sir_func(m, "hq" as *u8, T_F32)
465 sir_param(m, f, "x" as *u8, T_I32)
466 sir_param(m, f, "z" as *u8, T_I32)
467 let oob: i64 = ws_or(m, ws_or(m, ws_or(m,
468 ws_cmp(m, "<" as *u8, ws_id(m, "x" as *u8, T_I32), ws_i(m, "0" as *u8)),
469 ws_cmp(m, "<" as *u8, ws_id(m, "z" as *u8, T_I32), ws_i(m, "0" as *u8))),
470 ws_cmp(m, ">" as *u8, ws_id(m, "x" as *u8, T_I32), ws_i(m, "127" as *u8))),
471 ws_cmp(m, ">" as *u8, ws_id(m, "z" as *u8, T_I32), ws_i(m, "127" as *u8)))
472 ws_st(m, f, ws_if(m, oob, ws_ret(m, ws_f(m, "-1.0" as *u8)), 0))
473 let tl: i64 = sir_texload(m, ws_id(m, "tH" as *u8, T_TEX2F), ws_vt2(m, T_V2I, ws_id(m, "x" as *u8, T_I32), ws_id(m, "z" as *u8, T_I32)), ws_i(m, "0" as *u8))
474 ws_st(m, f, ws_ret(m, ws_sw(m, tl, "r" as *u8, T_F32)))
475 return f
476}
477// fn surf(p:vec2f)->f32 -- the terrain SURFACE height at a world xz: bilinear between the four columns,
478// one block above the column base (the top of the ground). -1 when any corner is off the field.
479func ws_fn_surf(m: *i64) -> i64 {
480 let f: i64 = sir_func(m, "surf" as *u8, T_F32)
481 sir_param(m, f, "p" as *u8, T_V2F)
482 ws_st(m, f, sir_let(m, "ix" as *u8, T_I32, sir_cast(m, ws_c1(m, "floor" as *u8, ws_sx(m, "p" as *u8, T_V2F, "x" as *u8, T_F32), T_F32), T_I32)))
483 ws_st(m, f, sir_let(m, "iz" as *u8, T_I32, sir_cast(m, ws_c1(m, "floor" as *u8, ws_sx(m, "p" as *u8, T_V2F, "y" as *u8, T_F32), T_F32), T_I32)))
484 ws_st(m, f, sir_let(m, "fr" as *u8, T_V2F, ws_c1(m, "fract" as *u8, ws_id(m, "p" as *u8, T_V2F), T_V2F)))
485 ws_st(m, f, sir_let(m, "h00" as *u8, T_F32, ws_c2(m, "hq" as *u8, ws_id(m, "ix" as *u8, T_I32), ws_id(m, "iz" as *u8, T_I32), T_F32)))
486 ws_st(m, f, sir_let(m, "h10" as *u8, T_F32, ws_c2(m, "hq" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "ix" as *u8, T_I32), ws_i(m, "1" as *u8), T_I32), ws_id(m, "iz" as *u8, T_I32), T_F32)))
487 ws_st(m, f, sir_let(m, "h01" as *u8, T_F32, ws_c2(m, "hq" as *u8, ws_id(m, "ix" as *u8, T_I32), ws_bin(m, "+" as *u8, ws_id(m, "iz" as *u8, T_I32), ws_i(m, "1" as *u8), T_I32), T_F32)))
488 ws_st(m, f, sir_let(m, "h11" as *u8, T_F32, ws_c2(m, "hq" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "ix" as *u8, T_I32), ws_i(m, "1" as *u8), T_I32), ws_bin(m, "+" as *u8, ws_id(m, "iz" as *u8, T_I32), ws_i(m, "1" as *u8), T_I32), T_F32)))
489 let miss: i64 = ws_or(m, ws_or(m, ws_or(m,
490 ws_cmp(m, "<" as *u8, ws_id(m, "h00" as *u8, T_F32), ws_f(m, "0.0" as *u8)),
491 ws_cmp(m, "<" as *u8, ws_id(m, "h10" as *u8, T_F32), ws_f(m, "0.0" as *u8))),
492 ws_cmp(m, "<" as *u8, ws_id(m, "h01" as *u8, T_F32), ws_f(m, "0.0" as *u8))),
493 ws_cmp(m, "<" as *u8, ws_id(m, "h11" as *u8, T_F32), ws_f(m, "0.0" as *u8)))
494 ws_st(m, f, ws_if(m, miss, ws_ret(m, ws_f(m, "-1.0" as *u8)), 0))
495 let mx0: i64 = ws_c3(m, "mix" as *u8, ws_id(m, "h00" as *u8, T_F32), ws_id(m, "h10" as *u8, T_F32), ws_sx(m, "fr" as *u8, T_V2F, "x" as *u8, T_F32), T_F32)
496 let mx1: i64 = ws_c3(m, "mix" as *u8, ws_id(m, "h01" as *u8, T_F32), ws_id(m, "h11" as *u8, T_F32), ws_sx(m, "fr" as *u8, T_V2F, "x" as *u8, T_F32), T_F32)
497 ws_st(m, f, ws_ret(m, ws_bin(m, "+" as *u8, ws_c3(m, "mix" as *u8, mx0, mx1, ws_sx(m, "fr" as *u8, T_V2F, "y" as *u8, T_F32), T_F32), ws_f(m, "1.0" as *u8), T_F32)))
498 return f
499}
500// fn terrain(b:u32)->i32 -- the ground classes the field replaces; structures (wood, leaves, crops, water) stay cells
501func ws_fn_terrain(m: *i64) -> i64 {
502 let f: i64 = sir_func(m, "terrain" as *u8, T_I32)
503 sir_param(m, f, "b" as *u8, T_U32)
504 let tb: i64 = ws_or(m, ws_or(m, ws_or(m, ws_or(m, ws_or(m, ws_or(m, ws_or(m,
505 ws_beq(m, "1" as *u8), ws_beq(m, "2" as *u8)), ws_beq(m, "3" as *u8)), ws_beq(m, "5" as *u8)), ws_beq(m, "8" as *u8)), ws_beq(m, "9" as *u8)), ws_beq(m, "10" as *u8)), ws_beq(m, "11" as *u8))
506 ws_st(m, f, ws_if(m, tb, ws_ret(m, ws_i(m, "1" as *u8)), 0))
507 ws_st(m, f, ws_ret(m, ws_i(m, "0" as *u8)))
508 return f
509}
510// fn smarch(ro:vec3f,rd:vec3f,mx:i32)->f32 -- march the continuous surface: quarter-block steps (the field is
511// bilinear between columns, so a quarter block can never skip one), exit above the tallest column when climbing,
512// six bisections at the crossing. Returns t, or -1 for sky. The GPU twin of the sim's wray_surf.
513func ws_fn_smarch(m: *i64) -> i64 {
514 let f: i64 = sir_func(m, "smarch" as *u8, T_F32)
515 sir_param(m, f, "ro" as *u8, T_V3F)
516 sir_param(m, f, "rd" as *u8, T_V3F)
517 sir_param(m, f, "mx" as *u8, T_I32)
518 ws_st(m, f, sir_var(m, "t" as *u8, T_F32, ws_f(m, "0.0" as *u8)))
519 ws_st(m, f, sir_var(m, "tp" as *u8, T_F32, ws_f(m, "0.0" as *u8)))
520 ws_st(m, f, sir_var(m, "hit" as *u8, T_I32, ws_i(m, "0" as *u8)))
521 let s1: i64 = ws_op(m, "t" as *u8, T_F32, "+" as *u8, ws_f(m, "0.25" as *u8))
522 let s2: i64 = sir_let(m, "p" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "t" as *u8, T_F32), T_V3F), T_V3F))
523 let s3: i64 = ws_if(m, ws_and(m, ws_cmp(m, ">" as *u8, ws_sx(m, "p" as *u8, T_V3F, "y" as *u8, T_F32), ws_bin(m, "+" as *u8, ws_id(m, "wmax" as *u8, T_F32), ws_f(m, "2.0" as *u8), T_F32)), ws_cmp(m, ">=" as *u8, ws_sx(m, "rd" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, "0.0" as *u8))), ws_ret(m, ws_f(m, "-1.0" as *u8)), 0)
524 let oob: i64 = ws_or(m, ws_or(m, ws_or(m,
525 ws_cmp(m, "<" as *u8, ws_sx(m, "p" as *u8, T_V3F, "x" as *u8, T_F32), ws_f(m, "-8.0" as *u8)),
526 ws_cmp(m, ">" as *u8, ws_sx(m, "p" as *u8, T_V3F, "x" as *u8, T_F32), ws_f(m, "136.0" as *u8))),
527 ws_cmp(m, "<" as *u8, ws_sx(m, "p" as *u8, T_V3F, "z" as *u8, T_F32), ws_f(m, "-8.0" as *u8))),
528 ws_cmp(m, ">" as *u8, ws_sx(m, "p" as *u8, T_V3F, "z" as *u8, T_F32), ws_f(m, "136.0" as *u8)))
529 let s4: i64 = ws_if(m, oob, ws_ret(m, ws_f(m, "-1.0" as *u8)), 0)
530 let s5: i64 = sir_let(m, "hs" as *u8, T_F32, ws_c1(m, "surf" as *u8, ws_sx(m, "p" as *u8, T_V3F, "xz" as *u8, T_V2F), T_F32))
531 let s6: i64 = ws_if(m, ws_and(m, ws_cmp(m, ">=" as *u8, ws_id(m, "hs" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_cmp(m, "<=" as *u8, ws_sx(m, "p" as *u8, T_V3F, "y" as *u8, T_F32), ws_id(m, "hs" as *u8, T_F32))), ws_q2(m, ws_set(m, ws_id(m, "hit" as *u8, T_I32), ws_i(m, "1" as *u8)), sir_break(m)), 0)
532 let s7: i64 = ws_set(m, ws_id(m, "tp" as *u8, T_F32), ws_id(m, "t" as *u8, T_F32))
533 let body: i64 = ws_q4(m, ws_q3(m, s1, s2, s3), s4, s5, ws_q2(m, s6, s7))
534 sir_for_until(m, f, sir_var(m, "i" as *u8, T_I32, ws_i(m, "0" as *u8)), ws_cmp(m, ">=" as *u8, ws_id(m, "i" as *u8, T_I32), ws_bin(m, "*" as *u8, ws_id(m, "mx" as *u8, T_I32), ws_i(m, "4" as *u8), T_I32)), ws_op(m, "i" as *u8, T_I32, "+" as *u8, ws_i(m, "1" as *u8)), body)
535 ws_st(m, f, ws_if(m, ws_cmp(m, "==" as *u8, ws_id(m, "hit" as *u8, T_I32), ws_i(m, "0" as *u8)), ws_ret(m, ws_f(m, "-1.0" as *u8)), 0))
536 ws_st(m, f, sir_var(m, "lo" as *u8, T_F32, ws_id(m, "tp" as *u8, T_F32)))
537 ws_st(m, f, sir_var(m, "hi" as *u8, T_F32, ws_id(m, "t" as *u8, T_F32)))
538 let k1: i64 = sir_let(m, "md" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "lo" as *u8, T_F32), ws_id(m, "hi" as *u8, T_F32), T_F32), ws_f(m, "0.5" as *u8), T_F32))
539 let k2: i64 = sir_let(m, "q" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "md" as *u8, T_F32), T_V3F), T_V3F))
540 let k3: i64 = sir_let(m, "h2" as *u8, T_F32, ws_c1(m, "surf" as *u8, ws_sx(m, "q" as *u8, T_V3F, "xz" as *u8, T_V2F), T_F32))
541 let k4: i64 = ws_if(m, ws_and(m, ws_cmp(m, ">=" as *u8, ws_id(m, "h2" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_cmp(m, "<=" as *u8, ws_sx(m, "q" as *u8, T_V3F, "y" as *u8, T_F32), ws_id(m, "h2" as *u8, T_F32))), ws_set(m, ws_id(m, "hi" as *u8, T_F32), ws_id(m, "md" as *u8, T_F32)), ws_set(m, ws_id(m, "lo" as *u8, T_F32), ws_id(m, "md" as *u8, T_F32)))
542 sir_for_until(m, f, sir_var(m, "k" as *u8, T_I32, ws_i(m, "0" as *u8)), ws_cmp(m, ">=" as *u8, ws_id(m, "k" as *u8, T_I32), ws_i(m, "6" as *u8)), ws_op(m, "k" as *u8, T_I32, "+" as *u8, ws_i(m, "1" as *u8)), ws_q4(m, k1, k2, k3, k4))
543 ws_st(m, f, ws_ret(m, ws_id(m, "hi" as *u8, T_F32)))
544 return f
545}
546// fn gnd(p:vec2f)->f32 -- the ground light from the field's own gradient (central differences a quarter block
547// apart), Lambert against the sun and NORMALISED TO LEVEL GROUND: level lights exactly as the shipped flat top
548// face (1.0), the lee side floors at the shipped darkest face (0.42) -- the same two values shade's six-way
549// face table carries, so a flat field is byte-identical in brightness to a flat block top.
550func ws_fn_gnd(m: *i64) -> i64 {
551 let f: i64 = sir_func(m, "gnd" as *u8, T_F32)
552 sir_param(m, f, "p" as *u8, T_V2F)
553 ws_st(m, f, sir_let(m, "hl" as *u8, T_F32, ws_c1(m, "surf" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "p" as *u8, T_V2F), ws_v2f(m, "0.25" as *u8, "0.0" as *u8), T_V2F), T_F32)))
554 ws_st(m, f, sir_let(m, "hr" as *u8, T_F32, ws_c1(m, "surf" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "p" as *u8, T_V2F), ws_v2f(m, "0.25" as *u8, "0.0" as *u8), T_V2F), T_F32)))
555 ws_st(m, f, sir_let(m, "hd" as *u8, T_F32, ws_c1(m, "surf" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "p" as *u8, T_V2F), ws_v2f(m, "0.0" as *u8, "0.25" as *u8), T_V2F), T_F32)))
556 ws_st(m, f, sir_let(m, "hu" as *u8, T_F32, ws_c1(m, "surf" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "p" as *u8, T_V2F), ws_v2f(m, "0.0" as *u8, "0.25" as *u8), T_V2F), T_F32)))
557 let miss: i64 = ws_or(m, ws_or(m, ws_or(m,
558 ws_cmp(m, "<" as *u8, ws_id(m, "hl" as *u8, T_F32), ws_f(m, "0.0" as *u8)),
559 ws_cmp(m, "<" as *u8, ws_id(m, "hr" as *u8, T_F32), ws_f(m, "0.0" as *u8))),
560 ws_cmp(m, "<" as *u8, ws_id(m, "hd" as *u8, T_F32), ws_f(m, "0.0" as *u8))),
561 ws_cmp(m, "<" as *u8, ws_id(m, "hu" as *u8, T_F32), ws_f(m, "0.0" as *u8)))
562 ws_st(m, f, ws_if(m, miss, ws_ret(m, ws_f(m, "1.0" as *u8)), 0))
563 let nx: i64 = ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "hl" as *u8, T_F32), ws_id(m, "hr" as *u8, T_F32), T_F32), ws_f(m, "0.5" as *u8), T_F32)
564 let nz: i64 = ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "hd" as *u8, T_F32), ws_id(m, "hu" as *u8, T_F32), T_F32), ws_f(m, "0.5" as *u8), T_F32)
565 ws_st(m, f, sir_let(m, "n9" as *u8, T_V3F, ws_c1(m, "normalize" as *u8, ws_v3(m, nx, ws_f(m, "1.0" as *u8), nz), T_V3F)))
566 ws_st(m, f, sir_let(m, "cp" as *u8, T_F32, ws_c2(m, "max" as *u8, ws_c2(m, "dot" as *u8, ws_id(m, "n9" as *u8, T_V3F), ws_id(m, "sund" as *u8, T_V3F), T_F32), ws_f(m, "0.0" as *u8), T_F32)))
567 ws_st(m, f, sir_let(m, "cf" as *u8, T_F32, ws_c2(m, "max" as *u8, ws_sx(m, "sund" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, "0.001" as *u8), T_F32)))
568 let span: i64 = ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_f(m, "0.42" as *u8), T_F32)
569 ws_st(m, f, ws_ret(m, ws_c2(m, "min" as *u8, ws_bin(m, "+" as *u8, ws_f(m, "0.42" as *u8), ws_bin(m, "*" as *u8, span, ws_bin(m, "/" as *u8, ws_id(m, "cp" as *u8, T_F32), ws_id(m, "cf" as *u8, T_F32), T_F32), T_F32), T_F32), ws_f(m, "1.0" as *u8), T_F32)))
570 return f
571}
572
573// fn march(ro:vec3f,rd:vec3f,skipw:i32,mx:i32)->Hit{ ... }
574func ws_fn_march(m: *i64, hty: i64) -> i64 {
575 let f: i64 = sir_func(m, "march" as *u8, hty)
576 sir_param(m, f, "ro" as *u8, T_V3F)
577 sir_param(m, f, "rd" as *u8, T_V3F)
578 sir_param(m, f, "skipw" as *u8, T_I32)
579 sir_param(m, f, "mx" as *u8, T_I32)
580 sir_param(m, f, "skipt" as *u8, T_I32) // GE53: 1 = terrain cells are air (the field is the ground); callers pass u.r_surf
581 // var h:Hit;h.t=-1.0;h.fce=0;h.b=0u;h.c=vec3i(0);
582 ws_st(m, f, sir_var(m, "h" as *u8, hty, 0))
583 ws_st(m, f, ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "t" as *u8, T_F32), ws_f(m, "-1.0" as *u8)))
584 ws_st(m, f, ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "fce" as *u8, T_I32), ws_i(m, "0" as *u8)))
585 ws_st(m, f, ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "b" as *u8, T_U32), ws_u(m, "0" as *u8)))
586 ws_st(m, f, ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "c" as *u8, T_V3I), ws_v1(m, T_V3I, ws_i(m, "0" as *u8))))
587 // var c:vec3i=vec3i(floor(ro));let st=vec3i(sign(rd));
588 ws_st(m, f, sir_var(m, "c" as *u8, T_V3I, ws_v1(m, T_V3I, ws_c1(m, "floor" as *u8, ws_id(m, "ro" as *u8, T_V3F), T_V3F))))
589 ws_st(m, f, sir_let(m, "st" as *u8, T_V3I, ws_v1(m, T_V3I, ws_c1(m, "sign" as *u8, ws_id(m, "rd" as *u8, T_V3F), T_V3F))))
590 // let dd=abs(vec3f(1.0)/max(abs(rd),vec3f(1e-6)));
591 ws_st(m, f, sir_let(m, "dd" as *u8, T_V3F, ws_c1(m, "abs" as *u8, ws_bin(m, "/" as *u8, ws_v1(m, T_V3F, ws_f(m, "1.0" as *u8)), ws_c2(m, "max" as *u8, ws_c1(m, "abs" as *u8, ws_id(m, "rd" as *u8, T_V3F), T_V3F), ws_v1(m, T_V3F, ws_f(m, "1e-6" as *u8)), T_V3F), T_V3F), T_V3F)))
592 // var tm=(vec3f(st)*(vec3f(c)-ro)+vec3f(st)*0.5+vec3f(0.5))*dd;
593 let tm0: i64 = ws_bin(m, "*" as *u8, ws_v1(m, T_V3F, ws_id(m, "st" as *u8, T_V3I)), ws_bin(m, "-" as *u8, ws_v1(m, T_V3F, ws_id(m, "c" as *u8, T_V3I)), ws_id(m, "ro" as *u8, T_V3F), T_V3F), T_V3F)
594 let tm1: i64 = ws_bin(m, "+" as *u8, tm0, ws_bin(m, "*" as *u8, ws_v1(m, T_V3F, ws_id(m, "st" as *u8, T_V3I)), ws_f(m, "0.5" as *u8), T_V3F), T_V3F)
595 let tm2: i64 = ws_bin(m, "+" as *u8, tm1, ws_v1(m, T_V3F, ws_f(m, "0.5" as *u8)), T_V3F)
596 ws_st(m, f, sir_var(m, "tm" as *u8, T_V3F, ws_bin(m, "*" as *u8, tm2, ws_id(m, "dd" as *u8, T_V3F), T_V3F)))
597 ws_st(m, f, sir_var(m, "t" as *u8, T_F32, ws_f(m, "0.0" as *u8)))
598 ws_st(m, f, sir_var(m, "fce" as *u8, T_I32, ws_i(m, "0" as *u8)))
599 // for(var i:i32=0;i<200;i++){ ... }
600 let b1: i64 = ws_if(m, ws_cmp(m, ">=" as *u8, ws_id(m, "i" as *u8, T_I32), ws_id(m, "mx" as *u8, T_I32)), sir_break(m), 0)
601 let cx: i64 = ws_and(m, ws_cmp(m, "<" as *u8, ws_sx(m, "tm" as *u8, T_V3F, "x" as *u8, T_F32), ws_sx(m, "tm" as *u8, T_V3F, "y" as *u8, T_F32)), ws_cmp(m, "<" as *u8, ws_sx(m, "tm" as *u8, T_V3F, "x" as *u8, T_F32), ws_sx(m, "tm" as *u8, T_V3F, "z" as *u8, T_F32)))
602 let cy: i64 = ws_cmp(m, "<" as *u8, ws_sx(m, "tm" as *u8, T_V3F, "y" as *u8, T_F32), ws_sx(m, "tm" as *u8, T_V3F, "z" as *u8, T_F32))
603 let b2: i64 = ws_if(m, cx, ws_dda_step(m, "x" as *u8, "1" as *u8, "2" as *u8), ws_if(m, cy, ws_dda_step(m, "y" as *u8, "3" as *u8, "4" as *u8), ws_dda_step(m, "z" as *u8, "5" as *u8, "6" as *u8)))
604 // if(f32(c.y)>u.wmax&&rd.y>=0.0){return h;}if(c.y<0){return h;}
605 let b3: i64 = ws_if(m, ws_and(m, ws_cmp(m, ">" as *u8, sir_cast(m, ws_sx(m, "c" as *u8, T_V3I, "y" as *u8, T_I32), T_F32), ws_id(m, "wmax" as *u8, T_F32)), ws_cmp(m, ">=" as *u8, ws_sx(m, "rd" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, "0.0" as *u8))), ws_ret(m, ws_id(m, "h" as *u8, hty)), 0)
606 let b4: i64 = ws_if(m, ws_cmp(m, "<" as *u8, ws_sx(m, "c" as *u8, T_V3I, "y" as *u8, T_I32), ws_i(m, "0" as *u8)), ws_ret(m, ws_id(m, "h" as *u8, hty)), 0)
607 // if(c.x< -8||c.x>135||c.z< -8||c.z>135){return h;}
608 let oob: i64 = ws_or(m, ws_or(m, ws_or(m, ws_cmp(m, "<" as *u8, ws_sx(m, "c" as *u8, T_V3I, "x" as *u8, T_I32), ws_i(m, "-8" as *u8)), ws_cmp(m, ">" as *u8, ws_sx(m, "c" as *u8, T_V3I, "x" as *u8, T_I32), ws_i(m, "135" as *u8))), ws_cmp(m, "<" as *u8, ws_sx(m, "c" as *u8, T_V3I, "z" as *u8, T_I32), ws_i(m, "-8" as *u8))), ws_cmp(m, ">" as *u8, ws_sx(m, "c" as *u8, T_V3I, "z" as *u8, T_I32), ws_i(m, "135" as *u8)))
609 let b5: i64 = ws_if(m, oob, ws_ret(m, ws_id(m, "h" as *u8, hty)), 0)
610 // var b=vx(c);if(skipw==1&&b==4u){b=0u;}
611 let b6: i64 = sir_var(m, "b" as *u8, T_U32, ws_c1(m, "vx" as *u8, ws_id(m, "c" as *u8, T_V3I), T_U32))
612 // GE53: under skipt the terrain classes are air too -- the field is the ground, only structures stay cells
613 let b7: i64 = ws_q2(m,
614 ws_if(m, ws_and(m, ws_cmp(m, "==" as *u8, ws_id(m, "skipw" as *u8, T_I32), ws_i(m, "1" as *u8)), ws_cmp(m, "==" as *u8, ws_id(m, "b" as *u8, T_U32), ws_u(m, "4" as *u8))), ws_set(m, ws_id(m, "b" as *u8, T_U32), ws_u(m, "0" as *u8)), 0),
615 ws_if(m, ws_and(m, ws_cmp(m, "==" as *u8, ws_id(m, "skipt" as *u8, T_I32), ws_i(m, "1" as *u8)), ws_cmp(m, "==" as *u8, ws_c1(m, "terrain" as *u8, ws_id(m, "b" as *u8, T_U32), T_I32), ws_i(m, "1" as *u8))), ws_set(m, ws_id(m, "b" as *u8, T_U32), ws_u(m, "0" as *u8)), 0))
616 // if(b!=0u){h.t=t;h.c=c;h.fce=fce;h.b=b;return h;}
617 let hit: i64 = ws_q5(m,
618 ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "t" as *u8, T_F32), ws_id(m, "t" as *u8, T_F32)),
619 ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "c" as *u8, T_V3I), ws_id(m, "c" as *u8, T_V3I)),
620 ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "fce" as *u8, T_I32), ws_id(m, "fce" as *u8, T_I32)),
621 ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "b" as *u8, T_U32), ws_id(m, "b" as *u8, T_U32)),
622 ws_ret(m, ws_id(m, "h" as *u8, hty)))
623 let b8: i64 = ws_if(m, ws_cmp(m, "!=" as *u8, ws_id(m, "b" as *u8, T_U32), ws_u(m, "0" as *u8)), hit, 0)
624 let body: i64 = ws_q4(m, ws_q4(m, b1, b2, b3, b4), b5, b6, ws_q2(m, b7, b8))
625 sir_for_until(m, f, sir_var(m, "i" as *u8, T_I32, ws_i(m, "0" as *u8)), ws_cmp(m, ">=" as *u8, ws_id(m, "i" as *u8, T_I32), ws_i(m, "200" as *u8)), ws_op(m, "i" as *u8, T_I32, "+" as *u8, ws_i(m, "1" as *u8)), body)
626 ws_st(m, f, ws_ret(m, ws_id(m, "h" as *u8, hty)))
627 return f
628}
629
630// one face arm of shade: uv=hp.<sw>;oc.<ax>=(oc.<ax><op>1);n=vec3f(<nx>,<ny>,<nz>);
631func ws_face(m: *i64, sw: *u8, ax: *u8, op: *u8, nx: *u8, ny: *u8, nz: *u8) -> i64 {
632 return ws_q3(m,
633 ws_set(m, ws_id(m, "uv" as *u8, T_V2F), ws_sx(m, "hp" as *u8, T_V3F, sw, T_V2F)),
634 ws_opx(m, "oc" as *u8, T_V3I, ax, T_I32, op, ws_i(m, "1" as *u8)),
635 ws_set(m, ws_id(m, "n" as *u8, T_V3F), ws_v3f(m, nx, ny, nz)))
636}
637// li=(li*<k>)
638func ws_li(m: *i64, k: *u8) -> i64 { return ws_op(m, "li" as *u8, T_F32, "*" as *u8, ws_f(m, k)) }
639// fce==<k>
640func 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)) }
641// b==<k>u
642func 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)) }
643// one AO probe: if(f.<fa> <cmp> <edge>){var nb=oc; <nudge>; if(vx(nb)!=0u&&vx(nb)!=4u){ao=(ao+(<gain>)*2.0);}}
644func ws_ao(m: *i64, fa: *u8, cmp: *u8, edge: *u8, nudge: i64, gain: i64) -> i64 {
645 let nbv: i64 = sir_var(m, "nb" as *u8, T_V3I, ws_id(m, "oc" as *u8, T_V3I))
646 let solid: i64 = ws_and(m, ws_cmp(m, "!=" as *u8, ws_c1(m, "vx" as *u8, ws_id(m, "nb" as *u8, T_V3I), T_U32), ws_u(m, "0" as *u8)), ws_cmp(m, "!=" as *u8, ws_c1(m, "vx" as *u8, ws_id(m, "nb" as *u8, T_V3I), T_U32), ws_u(m, "4" as *u8)))
647 let add: i64 = ws_op(m, "ao" as *u8, T_F32, "+" as *u8, ws_bin(m, "*" as *u8, gain, ws_f(m, "2.0" as *u8), T_F32))
648 return ws_if(m, ws_cmp(m, cmp, ws_sx(m, "f" as *u8, T_V2F, fa, T_F32), ws_f(m, edge)), ws_q3(m, nbv, nudge, ws_if(m, solid, add, 0)), 0)
649}
650// nb.<ax>=(nb.<ax><op>1)
651func 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)) }
652// fce==3||fce==4
653func ws_topbot(m: *i64) -> i64 { return ws_or(m, ws_fce(m, "3" as *u8), ws_fce(m, "4" as *u8)) }
654
655// fn shade(ro:vec3f,rd:vec3f,t:f32,c:vec3i,fce:i32,b:u32)->vec3f{ ... }
656// GE53 helpers -- each call builds a FRESH node tree (a node is never two children).
657// Terrain lighting belongs only to a field hit, never to water or an object top face.
658func ws_smooth(m: *i64) -> i64 {
659 let field: i64 = ws_and(m, ws_cmp(m, "==" as *u8, sir_ident(m, "r_surf" as *u8, T_I32), ws_i(m, "1" as *u8)), ws_fce(m, "3" as *u8))
660 return ws_and(m, field, ws_cmp(m, "==" as *u8, ws_c1(m, "terrain" as *u8, ws_id(m, "b" as *u8, T_U32), T_I32), ws_i(m, "1" as *u8)))
661}
662// The analytic plane has two sides; neither inherits the voxel material's cell decoration.
663func ws_cont_water(m: *i64) -> i64 {
664 return ws_and(m, ws_and(m, ws_cmp(m, "==" as *u8, sir_ident(m, "r_surf" as *u8, T_I32), ws_i(m, "1" as *u8)), ws_beq(m, "4" as *u8)), ws_topbot(m))
665}
666func ws_cont_surface(m: *i64) -> i64 { return ws_or(m, ws_smooth(m), ws_cont_water(m)) }
667// one step of the scan-down to the column's top solid cell: if(cy9>0&&vx(vec3i(cx9,cy9,cz9))==0u){cy9=cy9-1;}
668func ws_step_down(m: *i64) -> i64 {
669 return ws_if(m, ws_and(m, ws_cmp(m, ">" as *u8, ws_id(m, "cy9" as *u8, T_I32), ws_i(m, "0" as *u8)), ws_cmp(m, "==" as *u8, ws_c1(m, "vx" as *u8, ws_vt3(m, T_V3I, ws_id(m, "cx9" as *u8, T_I32), ws_id(m, "cy9" as *u8, T_I32), ws_id(m, "cz9" as *u8, T_I32)), T_U32), ws_u(m, "0" as *u8))), ws_op(m, "cy9" as *u8, T_I32, "-" as *u8, ws_i(m, "1" as *u8)), 0)
670}
671// ---- GR27 (2026-09-06): THE GROUND IS A MATERIAL, NOT A PAINT -----------------------------------------------
672// fn sand(hp:vec3f,c:vec3i,rd:vec3f,t:f32)->vec2f -- the field's ground material, all arithmetic on the surface
673// field and the voxel volume, no texture. x = the light multiplier: the gnd() Lambert (level 1.0, lee floor 0.42)
674// taken on the field normal TILTED by grain facets and wind ripples, then wet-darkened; y = the specular: a thin
675// water film inside the wet band (a Blinn lobe plus a Fresnel sky sheen) and dry quartz glints.
676// FOOTPRINT: one pixel spans 2/res.x world units per unit distance (sc = px/(res.x*0.5)), stretched by 1/|n.rd|
677// at grazing angles. A hash cannot be mip-averaged, so every detail whose period falls under TWO footprints
678// (the Nyquist bound) fades to zero instead of aliasing -- grains and ripples survive a grazing view by
679// fading, never by sparkling; beyond that range sand reads as its albedo, which is what sand does.
680// WET BAND: the volume is probed for water (class 4) on a ring of SD_RING_DIRS directions x SD_WET_R radii at
681// the column's top solid cell and one below it; the nearest water radius sets the wetness (adjacent 1, three
682// cells 1/3, beyond 0) and a water cell ABOVE the column means submerged (1). Wet sand darkens because pore
683// water index-matches the grains (albedo x SD_WET_DARK) and gains a film sheen; the swash erases ripples.
684// Every constant below is a data hook: the ripple heading is the wind row's heading and the grain scale the
685// recipe's sand grade; both become raw words when the material table lands, and are NAMED here until then.
686const SD_GRAIN_PER_BLOCK: *u8 = "32.0" // facets per block edge: 3 cm at a 1 m block, coarse beach sand
687const SD_GRAIN_SLOPE: *u8 = "1.2" // facet steepness as a normal slope
688const SD_RIPPLE_PER_BLOCK: *u8 = "9.0" // wind ripples per block: an 11 cm wavelength at a 1 m block
689const SD_RIPPLE_SLOPE: *u8 = "0.45" // crest slope
690const SD_RIPPLE_DX: *u8 = "0.8" // ripple normal heading (unit): the wind heading, a data hook
691const SD_RIPPLE_DZ: *u8 = "0.6"
692const SD_PATCH: *u8 = "0.25" // ripple phase jitter per 4-block patch so the field is not one sine
693const SD_TAU: *u8 = "6.2831853"
694const SD_QUARTER_TURN: *u8 = "1.5707963"
695const SD_EIGHTH_TURN: *u8 = "0.7853982"
696const SD_RING_DIRS: *u8 = "8"
697const SD_RING_STEPS: *u8 = "24" // SD_RING_DIRS x SD_WET_R
698const SD_WET_R: *u8 = "3.0" // wet band reach in cells
699const SD_WET_DRY: *u8 = "4.0" // SD_WET_R + 1: no water within reach
700const SD_WET_DARK: *u8 = "0.55" // wet albedo multiplier
701const SD_FILM_POW: *u8 = "48.0"
702const SD_FILM_GAIN: *u8 = "0.55"
703const SD_SHEEN_GAIN: *u8 = "0.10"
704const SD_GLINT_POW: *u8 = "96.0"
705const SD_GLINT_GAIN: *u8 = "0.35"
706const SD_GLINT_FRAC: *u8 = "0.9" // facets whose hash exceeds this are quartz glints
707const SD_NDV_FLOOR: *u8 = "0.15" // the footprint stretch floor at grazing angles
708const SD_SHADOW_SPEC: *u8 = "0.2" // in a block shadow the film keeps its sky sheen and loses the sun
709const SD_TWO: *u8 = "2.0"
710const SD_HALF: *u8 = "0.5"
711// helpers -- every call builds a FRESH node tree (a node is never two children)
712func ws_sd_pxz(m: *i64) -> i64 { return ws_sx(m, "hp" as *u8, T_V3F, "xz" as *u8, T_V2F) }
713func ws_sd_f(m: *i64, n: *u8) -> i64 { return ws_id(m, n, T_F32) }
714func ws_sd_v3(m: *i64, n: *u8) -> i64 { return ws_id(m, n, T_V3F) }
715// surf(hp.xz <op> (dx,dz))
716func 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) }
717// h21(gc + (dx,dz))
718func 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) }
719func 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)) }
720func 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) }
721// vx(c + vec3i(dx*k, <y>, dz*k)) == 4u
722func 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)) }
723// i32(floor(sin(a + <shift>) + 0.5)) -- the ring direction from the angle, sin only (the covered subset)
724func 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) }
725// clamp(1 - 2*fp*<freq>, 0, 1) -- the Nyquist fade of a detail with <freq> periods per block
726func 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) }
727// (a - b) * <k>
728func 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) }
729// <s> + gam*<g> - dry*rs*<rdk> -- one axis of the tilted normal
730func ws_sd_tilt(m: *i64, s: *u8, g: *u8, rdk: *u8) -> i64 {
731 let a: i64 = ws_bin(m, "+" as *u8, ws_sd_f(m, s), ws_bin(m, "*" as *u8, ws_sd_f(m, "gam" as *u8), ws_sd_f(m, g), T_F32), T_F32)
732 return ws_bin(m, "-" as *u8, a, ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_sd_f(m, "dry" as *u8), ws_sd_f(m, "rs" as *u8), T_F32), ws_f(m, rdk), T_F32), T_F32)
733}
734// the sand classes: 1 the shore slot (SHORE repaints the grass slot as shore sand), 2 packed sand, 5 sand at and
735// below the waterline (nx_wasm_craft gencol) -- and ONLY under the field (ws_smooth), which today is the shore
736// world's ground; a per-class material word is the data hook owed before another world's field lands
737func 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)) }
738func ws_sandy(m: *i64) -> i64 { return ws_and(m, ws_smooth(m), ws_sandcls(m)) }
739// the block-shadow arm: li*=0.55 as shipped, and the film specular loses the sun (keeps its sky sheen)
740func 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))) }
741func ws_fn_sand(m: *i64) -> i64 {
742 let f: i64 = sir_func(m, "sand" as *u8, T_V2F)
743 sir_param(m, f, "hp" as *u8, T_V3F)
744 sir_param(m, f, "c" as *u8, T_V3I)
745 sir_param(m, f, "rd" as *u8, T_V3F)
746 sir_param(m, f, "t" as *u8, T_F32)
747 // the field normal from the same quarter-block central differences gnd uses; off the field = the flat answer
748 ws_st(m, f, sir_let(m, "hl" as *u8, T_F32, ws_sd_surf(m, "-" as *u8, "0.25" as *u8, "0.0" as *u8)))
749 ws_st(m, f, sir_let(m, "hr" as *u8, T_F32, ws_sd_surf(m, "+" as *u8, "0.25" as *u8, "0.0" as *u8)))
750 ws_st(m, f, sir_let(m, "hd" as *u8, T_F32, ws_sd_surf(m, "-" as *u8, "0.0" as *u8, "0.25" as *u8)))
751 ws_st(m, f, sir_let(m, "hu" as *u8, T_F32, ws_sd_surf(m, "+" as *u8, "0.0" as *u8, "0.25" as *u8)))
752 let miss: i64 = ws_or(m, ws_or(m, ws_or(m, ws_sd_lt0(m, "hl" as *u8), ws_sd_lt0(m, "hr" as *u8)), ws_sd_lt0(m, "hd" as *u8)), ws_sd_lt0(m, "hu" as *u8))
753 ws_st(m, f, ws_if(m, miss, ws_ret(m, ws_v2f(m, "1.0" as *u8, "0.0" as *u8)), 0))
754 ws_st(m, f, sir_let(m, "sx" as *u8, T_F32, ws_sd_dslope(m, "hl" as *u8, "hr" as *u8, SD_TWO)))
755 ws_st(m, f, sir_let(m, "sz" as *u8, T_F32, ws_sd_dslope(m, "hd" as *u8, "hu" as *u8, SD_TWO)))
756 ws_st(m, f, sir_let(m, "nrm" as *u8, T_V3F, ws_c1(m, "normalize" as *u8, ws_v3(m, ws_sd_f(m, "sx" as *u8), ws_f(m, "1.0" as *u8), ws_sd_f(m, "sz" as *u8)), T_V3F)))
757 // the pixel footprint at this hit, stretched by the grazing angle
758 ws_st(m, f, sir_let(m, "ndv" as *u8, T_F32, ws_c2(m, "max" as *u8, ws_c1(m, "abs" as *u8, ws_c2(m, "dot" as *u8, ws_sd_v3(m, "nrm" as *u8), ws_sd_v3(m, "rd" as *u8), T_F32), T_F32), ws_f(m, SD_NDV_FLOOR), T_F32)))
759 ws_st(m, f, sir_let(m, "fp" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_bin(m, "*" as *u8, ws_sd_f(m, "t" as *u8), ws_bin(m, "/" as *u8, ws_f(m, SD_TWO), ws_sx(m, "res" as *u8, T_V2F, "x" as *u8, T_F32), T_F32), T_F32), ws_sd_f(m, "ndv" as *u8), T_F32)))
760 // grain facets: three hash taps a facet apart give the facet's two slopes; the amplitude fades at the Nyquist bound
761 ws_st(m, f, sir_let(m, "gc" as *u8, T_V2F, ws_c1(m, "floor" as *u8, ws_bin(m, "*" as *u8, ws_sd_pxz(m), ws_f(m, SD_GRAIN_PER_BLOCK), T_V2F), T_V2F)))
762 ws_st(m, f, sir_let(m, "g0" as *u8, T_F32, ws_sd_g(m, "0.0" as *u8, "0.0" as *u8)))
763 ws_st(m, f, sir_let(m, "g1" as *u8, T_F32, ws_sd_g(m, "1.0" as *u8, "0.0" as *u8)))
764 ws_st(m, f, sir_let(m, "g2" as *u8, T_F32, ws_sd_g(m, "0.0" as *u8, "1.0" as *u8)))
765 ws_st(m, f, sir_let(m, "gam" as *u8, T_F32, ws_sd_fade(m, SD_GRAIN_PER_BLOCK)))
766 ws_st(m, f, sir_let(m, "gx" as *u8, T_F32, ws_sd_dslope(m, "g0" as *u8, "g1" as *u8, SD_GRAIN_SLOPE)))
767 ws_st(m, f, sir_let(m, "gz" as *u8, T_F32, ws_sd_dslope(m, "g0" as *u8, "g2" as *u8, SD_GRAIN_SLOPE)))
768 // wind ripples: a crest slope along the wind heading, phase-jittered per patch, fading at its own Nyquist bound
769 let ph0: i64 = ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_c2(m, "dot" as *u8, ws_sd_pxz(m), ws_v2f(m, SD_RIPPLE_DX, SD_RIPPLE_DZ), T_F32), ws_f(m, SD_RIPPLE_PER_BLOCK), T_F32), ws_f(m, SD_TAU), T_F32)
770 let ph1: i64 = ws_bin(m, "*" as *u8, ws_c1(m, "h21" as *u8, ws_c1(m, "floor" as *u8, ws_bin(m, "*" as *u8, ws_sd_pxz(m), ws_f(m, SD_PATCH), T_V2F), T_V2F), T_F32), ws_f(m, SD_TAU), T_F32)
771 ws_st(m, f, sir_let(m, "ph" as *u8, T_F32, ws_bin(m, "+" as *u8, ph0, ph1, T_F32)))
772 ws_st(m, f, sir_let(m, "ram" as *u8, T_F32, ws_sd_fade(m, SD_RIPPLE_PER_BLOCK)))
773 ws_st(m, f, sir_let(m, "rs" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_c1(m, "sin" as *u8, ws_bin(m, "+" as *u8, ws_sd_f(m, "ph" as *u8), ws_f(m, SD_QUARTER_TURN), T_F32), T_F32), ws_f(m, SD_RIPPLE_SLOPE), T_F32), ws_sd_f(m, "ram" as *u8), T_F32)))
774 // the wet band: the nearest water on the ring, at this cell's height and one below
775 ws_st(m, f, sir_var(m, "wd" as *u8, T_F32, ws_f(m, SD_WET_DRY)))
776 let kk: i64 = sir_let(m, "k" as *u8, T_I32, ws_bin(m, "+" as *u8, ws_bin(m, "/" as *u8, ws_id(m, "j" as *u8, T_I32), ws_i(m, SD_RING_DIRS), T_I32), ws_i(m, "1" as *u8), T_I32))
777 let dd: i64 = sir_let(m, "d" as *u8, T_I32, ws_bin(m, "-" as *u8, ws_id(m, "j" as *u8, T_I32), ws_bin(m, "*" as *u8, ws_bin(m, "/" as *u8, ws_id(m, "j" as *u8, T_I32), ws_i(m, SD_RING_DIRS), T_I32), ws_i(m, SD_RING_DIRS), T_I32), T_I32))
778 let aa: i64 = sir_let(m, "a" as *u8, T_F32, ws_bin(m, "*" as *u8, sir_cast(m, ws_id(m, "d" as *u8, T_I32), T_F32), ws_f(m, SD_EIGHTH_TURN), T_F32))
779 let dx: i64 = sir_let(m, "dx" as *u8, T_I32, ws_sd_dir(m, SD_QUARTER_TURN))
780 let dz: i64 = sir_let(m, "dz" as *u8, T_I32, ws_sd_dir(m, "0.0" as *u8))
781 let near: i64 = ws_if(m, ws_or(m, ws_sd_wat(m, "0" as *u8), ws_sd_wat(m, "-1" as *u8)), ws_set(m, ws_id(m, "wd" as *u8, T_F32), ws_c2(m, "min" as *u8, ws_id(m, "wd" as *u8, T_F32), sir_cast(m, ws_id(m, "k" as *u8, T_I32), T_F32), T_F32)), 0)
782 sir_for_until(m, f, sir_var(m, "j" as *u8, T_I32, ws_i(m, "0" as *u8)), ws_cmp(m, ">=" as *u8, ws_id(m, "j" as *u8, T_I32), ws_i(m, SD_RING_STEPS)), ws_op(m, "j" as *u8, T_I32, "+" as *u8, ws_i(m, "1" as *u8)), ws_q5(m, kk, dd, aa, ws_q2(m, dx, dz), near))
783 let sub: i64 = 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_i(m, "0" as *u8), ws_i(m, "1" as *u8), ws_i(m, "0" as *u8)), T_V3I), T_U32), ws_u(m, "4" as *u8))
784 ws_st(m, f, ws_if(m, sub, ws_set(m, ws_id(m, "wd" as *u8, T_F32), ws_f(m, "0.0" as *u8)), 0))
785 ws_st(m, f, sir_let(m, "wet" as *u8, T_F32, ws_c3(m, "clamp" as *u8, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_f(m, SD_WET_DRY), ws_sd_f(m, "wd" as *u8), T_F32), ws_f(m, SD_WET_R), T_F32), ws_f(m, "0.0" as *u8), ws_f(m, "1.0" as *u8), T_F32)))
786 ws_st(m, f, sir_let(m, "dry" as *u8, T_F32, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_sd_f(m, "wet" as *u8), T_F32)))
787 // the tilted normal: field slope + faded facets + the ripples the swash has not erased
788 ws_st(m, f, sir_let(m, "pn" as *u8, T_V3F, ws_c1(m, "normalize" as *u8, ws_v3(m, ws_sd_tilt(m, "sx" as *u8, "gx" as *u8, SD_RIPPLE_DX), ws_f(m, "1.0" as *u8), ws_sd_tilt(m, "sz" as *u8, "gz" as *u8, SD_RIPPLE_DZ)), T_V3F)))
789 // light: the gnd() Lambert on the tilted normal (level 1.0, lee floor 0.42), then wet darkening
790 ws_st(m, f, sir_let(m, "cp" as *u8, T_F32, ws_c2(m, "max" as *u8, ws_c2(m, "dot" as *u8, ws_sd_v3(m, "pn" as *u8), ws_sd_v3(m, "sund" as *u8), T_F32), ws_f(m, "0.0" as *u8), T_F32)))
791 ws_st(m, f, sir_let(m, "cf" as *u8, T_F32, ws_c2(m, "max" as *u8, ws_sx(m, "sund" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, "0.001" as *u8), T_F32)))
792 let span: i64 = ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_f(m, "0.42" as *u8), T_F32)
793 ws_st(m, f, sir_let(m, "lp" as *u8, T_F32, ws_c2(m, "min" as *u8, ws_bin(m, "+" as *u8, ws_f(m, "0.42" as *u8), ws_bin(m, "*" as *u8, span, ws_bin(m, "/" as *u8, ws_sd_f(m, "cp" as *u8), ws_sd_f(m, "cf" as *u8), T_F32), T_F32), T_F32), ws_f(m, "1.0" as *u8), T_F32)))
794 ws_st(m, f, sir_let(m, "lw" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_sd_f(m, "lp" as *u8), ws_c3(m, "mix" as *u8, ws_f(m, "1.0" as *u8), ws_f(m, SD_WET_DARK), ws_sd_f(m, "wet" as *u8), T_F32), T_F32)))
795 // specular: the film's Blinn lobe and Fresnel sky sheen inside the band, quartz glints on dry facets
796 ws_st(m, f, sir_let(m, "hv" as *u8, T_V3F, ws_c1(m, "normalize" as *u8, ws_bin(m, "-" as *u8, ws_sd_v3(m, "sund" as *u8), ws_sd_v3(m, "rd" as *u8), T_V3F), T_V3F)))
797 ws_st(m, f, sir_let(m, "fr" as *u8, T_F32, ws_c2(m, "pow" as *u8, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_sd_f(m, "ndv" as *u8), T_F32), ws_f(m, "5.0" as *u8), T_F32)))
798 ws_st(m, f, sir_let(m, "film" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_sd_f(m, "wet" as *u8), ws_c2(m, "pow" as *u8, ws_c2(m, "max" as *u8, ws_c2(m, "dot" as *u8, ws_sd_v3(m, "pn" as *u8), ws_sd_v3(m, "hv" as *u8), T_F32), ws_f(m, "0.0" as *u8), T_F32), ws_f(m, SD_FILM_POW), T_F32), T_F32), ws_f(m, SD_FILM_GAIN), T_F32)))
799 ws_st(m, f, sir_let(m, "sheen" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_sd_f(m, "wet" as *u8), ws_sd_f(m, "fr" as *u8), T_F32), ws_f(m, SD_SHEEN_GAIN), T_F32)))
800 ws_st(m, f, sir_let(m, "gn" as *u8, T_V3F, ws_c1(m, "normalize" as *u8, ws_v3(m, ws_sd_f(m, "gx" as *u8), ws_f(m, "1.0" as *u8), ws_sd_f(m, "gz" as *u8)), T_V3F)))
801 ws_st(m, f, sir_var(m, "glint" as *u8, T_F32, ws_f(m, "0.0" as *u8)))
802 let gl: i64 = ws_set(m, ws_id(m, "glint" as *u8, T_F32), ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_sd_f(m, "gam" as *u8), ws_c2(m, "pow" as *u8, ws_c2(m, "max" as *u8, ws_c2(m, "dot" as *u8, ws_sd_v3(m, "gn" as *u8), ws_sd_v3(m, "hv" as *u8), T_F32), ws_f(m, "0.0" as *u8), T_F32), ws_f(m, SD_GLINT_POW), T_F32), T_F32), ws_f(m, SD_GLINT_GAIN), T_F32))
803 ws_st(m, f, ws_if(m, ws_cmp(m, ">" as *u8, ws_sd_f(m, "g0" as *u8), ws_f(m, SD_GLINT_FRAC)), gl, 0))
804 // x = light, y = specular: the sun terms scaled by the sun flag, the sheen is the sky's and stays
805 let sunspec: i64 = ws_bin(m, "*" as *u8, ws_sd_f(m, "sun" as *u8), ws_bin(m, "+" as *u8, ws_sd_f(m, "film" as *u8), ws_sd_f(m, "glint" as *u8), T_F32), T_F32)
806 ws_st(m, f, ws_ret(m, ws_v2(m, ws_sd_f(m, "lw" as *u8), ws_bin(m, "+" as *u8, ws_sd_f(m, "sheen" as *u8), sunspec, T_F32))))
807 return f
808}
809func ws_fn_shade(m: *i64, hty: i64) -> i64 {
810 let f: i64 = sir_func(m, "shade" as *u8, T_V3F)
811 sir_param(m, f, "ro" as *u8, T_V3F)
812 sir_param(m, f, "rd" as *u8, T_V3F)
813 sir_param(m, f, "t" as *u8, T_F32)
814 sir_param(m, f, "c" as *u8, T_V3I)
815 sir_param(m, f, "fce" as *u8, T_I32)
816 sir_param(m, f, "b" as *u8, T_U32)
817 // let hp=ro+rd*t; var uv:vec2f; var oc:vec3i=c; var n:vec3f=vec3f(0.0);
818 ws_st(m, f, sir_let(m, "hp" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "t" as *u8, T_F32), T_V3F), T_V3F)))
819 ws_st(m, f, sir_var(m, "uv" as *u8, T_V2F, 0))
820 ws_st(m, f, sir_var(m, "oc" as *u8, T_V3I, ws_id(m, "c" as *u8, T_V3I)))
821 ws_st(m, f, sir_var(m, "n" as *u8, T_V3F, ws_v1(m, T_V3F, ws_f(m, "0.0" as *u8))))
822 // the six faces
823 let f6: i64 = ws_face(m, "xy" as *u8, "z" as *u8, "-" as *u8, "0.0" as *u8, "0.0" as *u8, "-1.0" as *u8)
824 let f5: i64 = ws_if(m, ws_fce(m, "5" as *u8), ws_face(m, "xy" as *u8, "z" as *u8, "+" as *u8, "0.0" as *u8, "0.0" as *u8, "1.0" as *u8), f6)
825 let f4: i64 = ws_if(m, ws_fce(m, "4" as *u8), ws_face(m, "xz" as *u8, "y" as *u8, "-" as *u8, "0.0" as *u8, "-1.0" as *u8, "0.0" as *u8), f5)
826 let f3: i64 = ws_if(m, ws_fce(m, "3" as *u8), ws_face(m, "xz" as *u8, "y" as *u8, "+" as *u8, "0.0" as *u8, "1.0" as *u8, "0.0" as *u8), f4)
827 let f2: i64 = ws_if(m, ws_fce(m, "2" as *u8), ws_face(m, "zy" as *u8, "x" as *u8, "-" as *u8, "-1.0" as *u8, "0.0" as *u8, "0.0" as *u8), f3)
828 ws_st(m, f, ws_if(m, ws_fce(m, "1" as *u8), ws_face(m, "zy" as *u8, "x" as *u8, "+" as *u8, "1.0" as *u8, "0.0" as *u8, "0.0" as *u8), f2))
829 // let f=fract(uv); var bb:u32=b; if(b==1u&&fce!=3&&fce!=4){bb=2u;if(f.y>0.8){bb=1u;}}
830 ws_st(m, f, sir_let(m, "f" as *u8, T_V2F, ws_c1(m, "fract" as *u8, ws_id(m, "uv" as *u8, T_V2F), T_V2F)))
831 ws_st(m, f, sir_var(m, "bb" as *u8, T_U32, ws_id(m, "b" as *u8, T_U32)))
832 let grass: i64 = ws_q2(m, ws_set(m, ws_id(m, "bb" as *u8, T_U32), ws_u(m, "2" as *u8)), ws_if(m, ws_cmp(m, ">" as *u8, ws_sx(m, "f" as *u8, T_V2F, "y" as *u8, T_F32), ws_f(m, "0.8" as *u8)), ws_set(m, ws_id(m, "bb" as *u8, T_U32), ws_u(m, "1" as *u8)), 0))
833 ws_st(m, f, ws_if(m, ws_and(m, ws_and(m, ws_beq(m, "1" as *u8), ws_cmp(m, "!=" as *u8, ws_id(m, "fce" as *u8, T_I32), ws_i(m, "3" as *u8))), ws_cmp(m, "!=" as *u8, ws_id(m, "fce" as *u8, T_I32), ws_i(m, "4" as *u8))), grass, 0))
834 // var li:f32; the six-way face light
835 ws_st(m, f, sir_var(m, "li" as *u8, T_F32, 0))
836 let l6: i64 = ws_set(m, ws_id(m, "li" as *u8, T_F32), ws_f(m, "0.56" as *u8))
837 let l5: i64 = ws_if(m, ws_fce(m, "5" as *u8), ws_set(m, ws_id(m, "li" as *u8, T_F32), ws_f(m, "0.62" as *u8)), l6)
838 let l2: i64 = ws_if(m, ws_fce(m, "2" as *u8), ws_set(m, ws_id(m, "li" as *u8, T_F32), ws_f(m, "0.7" as *u8)), l5)
839 let l1: i64 = ws_if(m, ws_fce(m, "1" as *u8), ws_set(m, ws_id(m, "li" as *u8, T_F32), ws_f(m, "0.76" as *u8)), l2)
840 let l4: i64 = ws_if(m, ws_fce(m, "4" as *u8), ws_set(m, ws_id(m, "li" as *u8, T_F32), ws_f(m, "0.42" as *u8)), l1)
841 ws_st(m, f, ws_if(m, ws_fce(m, "3" as *u8), ws_set(m, ws_id(m, "li" as *u8, T_F32), ws_f(m, "1.0" as *u8)), l4))
842 // GE53: on the field the ground's own gradient lights the top face (level = the same 1.0, lee = the same 0.42 floor)
843 // GR27: on the field the sand classes are a MATERIAL -- sand() lights the tilted normal and returns the film specular
844 // in sp; every other class on the field keeps the bare gradient light
845 ws_st(m, f, sir_var(m, "sp" as *u8, T_F32, ws_f(m, "0.0" as *u8)))
846 let sm: i64 = ws_q3(m, sir_let(m, "sm" as *u8, T_V2F, ws_c4(m, "sand" as *u8, ws_id(m, "hp" as *u8, T_V3F), ws_id(m, "c" as *u8, T_V3I), ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "t" as *u8, T_F32), T_V2F)), ws_set(m, ws_id(m, "li" as *u8, T_F32), ws_sx(m, "sm" as *u8, T_V2F, "x" as *u8, T_F32)), ws_set(m, ws_id(m, "sp" as *u8, T_F32), ws_sx(m, "sm" as *u8, T_V2F, "y" as *u8, T_F32)))
847 ws_st(m, f, ws_if(m, ws_smooth(m), ws_if(m, ws_sandcls(m), sm, ws_set(m, ws_id(m, "li" as *u8, T_F32), ws_c1(m, "gnd" as *u8, ws_sx(m, "hp" as *u8, T_V3F, "xz" as *u8, T_V2F), T_F32))), 0))
848 // if(u.sun>0.5){if(fce==1){li*=1.12;}if(fce==2){li*=0.92;}if(fce==5){li*=1.04;}}
849 ws_st(m, f, ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "sun" as *u8, T_F32), ws_f(m, "0.5" as *u8)), ws_q3(m, ws_if(m, ws_fce(m, "1" as *u8), ws_li(m, "1.12" as *u8), 0), ws_if(m, ws_fce(m, "2" as *u8), ws_li(m, "0.92" as *u8), 0), ws_if(m, ws_fce(m, "5" as *u8), ws_li(m, "1.04" as *u8), 0)), 0))
850 // let sd3=floor(hp)*0.13; let bs=f32(b)*7.0;
851 ws_st(m, f, sir_let(m, "sd3" as *u8, T_V3F, ws_bin(m, "*" as *u8, ws_c1(m, "floor" as *u8, ws_id(m, "hp" as *u8, T_V3F), T_V3F), ws_f(m, "0.13" as *u8), T_V3F)))
852 ws_st(m, f, sir_let(m, "bs" as *u8, T_F32, ws_bin(m, "*" as *u8, sir_cast(m, ws_id(m, "b" as *u8, T_U32), T_F32), ws_f(m, "7.0" as *u8), T_F32)))
853 // t00 / t10 / t01 = h31(vec3f(floor(f*24.0 [+ offset]),bs)+sd3)
854 let f24a: i64 = ws_bin(m, "*" as *u8, ws_id(m, "f" as *u8, T_V2F), ws_f(m, "24.0" as *u8), T_V2F)
855 ws_st(m, f, sir_let(m, "t00" as *u8, T_F32, ws_c1(m, "h31" as *u8, ws_bin(m, "+" as *u8, ws_vt2(m, T_V3F, ws_c1(m, "floor" as *u8, f24a, T_V2F), ws_id(m, "bs" as *u8, T_F32)), ws_id(m, "sd3" as *u8, T_V3F), T_V3F), T_F32)))
856 let f24b: i64 = ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "f" as *u8, T_V2F), ws_f(m, "24.0" as *u8), T_V2F), ws_v2f(m, "1.0" as *u8, "0.0" as *u8), T_V2F)
857 ws_st(m, f, sir_let(m, "t10" as *u8, T_F32, ws_c1(m, "h31" as *u8, ws_bin(m, "+" as *u8, ws_vt2(m, T_V3F, ws_c1(m, "floor" as *u8, f24b, T_V2F), ws_id(m, "bs" as *u8, T_F32)), ws_id(m, "sd3" as *u8, T_V3F), T_V3F), T_F32)))
858 let f24c: i64 = ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "f" as *u8, T_V2F), ws_f(m, "24.0" as *u8), T_V2F), ws_v2f(m, "0.0" as *u8, "1.0" as *u8), T_V2F)
859 ws_st(m, f, sir_let(m, "t01" as *u8, T_F32, ws_c1(m, "h31" as *u8, ws_bin(m, "+" as *u8, ws_vt2(m, T_V3F, ws_c1(m, "floor" as *u8, f24c, T_V2F), ws_id(m, "bs" as *u8, T_F32)), ws_id(m, "sd3" as *u8, T_V3F), T_V3F), T_F32)))
860 // let bmp=(t10-t00)*0.6+(t01-t00)*0.45;
861 ws_st(m, f, sir_let(m, "bmp" as *u8, T_F32, ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "t10" as *u8, T_F32), ws_id(m, "t00" as *u8, T_F32), T_F32), ws_f(m, "0.6" as *u8), T_F32), ws_bin(m, "*" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "t01" as *u8, T_F32), ws_id(m, "t00" as *u8, T_F32), T_F32), ws_f(m, "0.45" as *u8), T_F32), T_F32)))
862 // var bamp:f32; the block-class relief amplitude
863 ws_st(m, f, sir_var(m, "bamp" as *u8, T_F32, 0))
864 let a4: i64 = ws_if(m, ws_beq(m, "4" as *u8), ws_set(m, ws_id(m, "bamp" as *u8, T_F32), ws_f(m, "0.25" as *u8)), ws_set(m, ws_id(m, "bamp" as *u8, T_F32), ws_f(m, "0.7" as *u8)))
865 let a7: i64 = ws_if(m, ws_beq(m, "7" as *u8), ws_set(m, ws_id(m, "bamp" as *u8, T_F32), ws_f(m, "1.3" as *u8)), a4)
866 let rough: i64 = ws_or(m, ws_or(m, ws_or(m, ws_or(m, ws_beq(m, "3" as *u8), ws_beq(m, "2" as *u8)), ws_beq(m, "9" as *u8)), ws_beq(m, "10" as *u8)), ws_beq(m, "11" as *u8))
867 ws_st(m, f, ws_if(m, rough, ws_set(m, ws_id(m, "bamp" as *u8, T_F32), ws_f(m, "1.0" as *u8)), a7))
868 ws_st(m, f, ws_if(m, ws_or(m, ws_sandy(m), ws_cont_water(m)), ws_set(m, ws_id(m, "bamp" as *u8, T_F32), ws_f(m, "0.0" as *u8)), 0)) // GR27: the per-cell hash relief IS the paint the material replaces
869 // let dfade=clamp(1.0-t/24.0,0.0,1.0); li*=clamp(1.0+bmp*bamp*dfade,0.55,1.45); li*=0.9+t00*0.2*dfade;
870 ws_st(m, f, sir_let(m, "dfade" as *u8, T_F32, ws_c3(m, "clamp" as *u8, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_bin(m, "/" as *u8, ws_id(m, "t" as *u8, T_F32), ws_f(m, "24.0" as *u8), T_F32), T_F32), ws_f(m, "0.0" as *u8), ws_f(m, "1.0" as *u8), T_F32)))
871 ws_st(m, f, ws_op(m, "li" as *u8, T_F32, "*" as *u8, 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_id(m, "bmp" as *u8, T_F32), ws_id(m, "bamp" as *u8, T_F32), T_F32), ws_id(m, "dfade" as *u8, T_F32), T_F32), T_F32), ws_f(m, "0.55" as *u8), ws_f(m, "1.45" as *u8), T_F32)))
872 // The sand material owns its detail response; legacy voxel paint belongs to other surfaces.
873 ws_st(m, f, ws_if(m, sir_not(m, ws_or(m, ws_sandy(m), ws_cont_water(m))), ws_op(m, "li" as *u8, T_F32, "*" as *u8, ws_bin(m, "+" as *u8, ws_f(m, "0.9" as *u8), ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "t00" as *u8, T_F32), ws_f(m, "0.2" as *u8), T_F32), ws_id(m, "dfade" as *u8, T_F32), T_F32), T_F32)), 0))
874 // if(bb==1u&&fce==3&&t<24.0){let tf=h21(floor(f*38.0)+floor(hp.xz)*3.7);if(tf>0.82){li*=1.28;}else if(tf<0.14){li*=0.78;}}
875 let tf: i64 = sir_let(m, "tf" as *u8, T_F32, ws_c1(m, "h21" as *u8, ws_bin(m, "+" as *u8, ws_c1(m, "floor" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "f" as *u8, T_V2F), ws_f(m, "38.0" as *u8), T_V2F), T_V2F), ws_bin(m, "*" as *u8, ws_c1(m, "floor" as *u8, ws_sx(m, "hp" as *u8, T_V3F, "xz" as *u8, T_V2F), T_V2F), ws_f(m, "3.7" as *u8), T_V2F), T_V2F), T_F32))
876 let tfi: i64 = ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "tf" as *u8, T_F32), ws_f(m, "0.82" as *u8)), ws_li(m, "1.28" as *u8), ws_if(m, ws_cmp(m, "<" as *u8, ws_id(m, "tf" as *u8, T_F32), ws_f(m, "0.14" as *u8)), ws_li(m, "0.78" as *u8), 0))
877 ws_st(m, f, ws_if(m, ws_and(m, sir_not(m, ws_sandy(m)), ws_and(m, ws_and(m, ws_cmp(m, "==" as *u8, ws_id(m, "bb" as *u8, T_U32), ws_u(m, "1" as *u8)), ws_fce(m, "3" as *u8)), ws_cmp(m, "<" as *u8, ws_id(m, "t" as *u8, T_F32), ws_f(m, "24.0" as *u8)))), ws_q2(m, tf, tfi), 0))
878 // if(f.x<0.055||f.x>0.945||f.y<0.055||f.y>0.945){li*=0.82;}
879 let edge: i64 = ws_or(m, ws_or(m, ws_or(m, ws_cmp(m, "<" as *u8, ws_sx(m, "f" as *u8, T_V2F, "x" as *u8, T_F32), ws_f(m, "0.055" as *u8)), ws_cmp(m, ">" as *u8, ws_sx(m, "f" as *u8, T_V2F, "x" as *u8, T_F32), ws_f(m, "0.945" as *u8))), ws_cmp(m, "<" as *u8, ws_sx(m, "f" as *u8, T_V2F, "y" as *u8, T_F32), ws_f(m, "0.055" as *u8))), ws_cmp(m, ">" as *u8, ws_sx(m, "f" as *u8, T_V2F, "y" as *u8, T_F32), ws_f(m, "0.945" as *u8)))
880 ws_st(m, f, ws_if(m, ws_and(m, edge, sir_not(m, ws_cont_surface(m))), ws_li(m, "0.82" as *u8), 0)) // GE53: no cell-edge grid on the field
881 // var ao:f32=0.0; the four edge-AO probes
882 ws_st(m, f, sir_var(m, "ao" as *u8, T_F32, ws_f(m, "0.0" as *u8)))
883 let n1: i64 = ws_if(m, ws_topbot(m), ws_nb(m, "x" as *u8, "-" as *u8), ws_if(m, ws_cmp(m, "<" as *u8, ws_id(m, "fce" as *u8, T_I32), ws_i(m, "3" as *u8)), ws_nb(m, "z" as *u8, "-" as *u8), ws_nb(m, "x" as *u8, "-" as *u8)))
884 ws_st(m, f, ws_ao(m, "x" as *u8, "<" as *u8, "0.17" as *u8, n1, ws_bin(m, "-" as *u8, ws_f(m, "0.17" as *u8), ws_sx(m, "f" as *u8, T_V2F, "x" as *u8, T_F32), T_F32)))
885 let n2: i64 = ws_if(m, ws_topbot(m), ws_nb(m, "x" as *u8, "+" as *u8), ws_if(m, ws_cmp(m, "<" as *u8, ws_id(m, "fce" as *u8, T_I32), ws_i(m, "3" as *u8)), ws_nb(m, "z" as *u8, "+" as *u8), ws_nb(m, "x" as *u8, "+" as *u8)))
886 ws_st(m, f, ws_ao(m, "x" as *u8, ">" as *u8, "0.83" as *u8, n2, ws_bin(m, "-" as *u8, ws_sx(m, "f" as *u8, T_V2F, "x" as *u8, T_F32), ws_f(m, "0.83" as *u8), T_F32)))
887 let n3: i64 = ws_if(m, ws_topbot(m), ws_nb(m, "z" as *u8, "-" as *u8), ws_nb(m, "y" as *u8, "-" as *u8))
888 ws_st(m, f, ws_ao(m, "y" as *u8, "<" as *u8, "0.17" as *u8, n3, ws_bin(m, "-" as *u8, ws_f(m, "0.17" as *u8), ws_sx(m, "f" as *u8, T_V2F, "y" as *u8, T_F32), T_F32)))
889 let n4: i64 = ws_if(m, ws_topbot(m), ws_nb(m, "z" as *u8, "+" as *u8), ws_nb(m, "y" as *u8, "+" as *u8))
890 ws_st(m, f, ws_ao(m, "y" as *u8, ">" as *u8, "0.83" as *u8, n4, ws_bin(m, "-" as *u8, ws_sx(m, "f" as *u8, T_V2F, "y" as *u8, T_F32), ws_f(m, "0.83" as *u8), T_F32)))
891 // li*=1.0-min(ao,0.45);
892 ws_st(m, f, ws_if(m, sir_not(m, ws_cont_surface(m)), ws_op(m, "li" as *u8, T_F32, "*" as *u8, ws_bin(m, "-" as *u8, ws_f(m, "1.0" as *u8), ws_c2(m, "min" as *u8, ws_id(m, "ao" as *u8, T_F32), ws_f(m, "0.45" as *u8), T_F32), T_F32)), 0)) // GE53: no cell-corner AO on the field
893 // if(u.sun>0.5){let sh=march(hp+n*0.02,u.sund,1,60);if(sh.t>0.0){li*=0.55;}}
894 let sh: i64 = sir_let(m, "sh" as *u8, hty, ws_c5(m, "march" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "hp" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "n" as *u8, T_V3F), ws_f(m, "0.02" as *u8), T_V3F), T_V3F), ws_id(m, "sund" as *u8, T_V3F), ws_i(m, "1" as *u8), ws_i(m, "60" as *u8), sir_ident(m, "r_surf" as *u8, T_I32), hty))
895 // GE53: on the field a cell march cannot shadow the ground (terrain cells are air to it), so the surface march does
896 let shs: i64 = ws_if(m, ws_and(m, ws_and(m, ws_cmp(m, "==" as *u8, sir_ident(m, "r_surf" as *u8, T_I32), ws_i(m, "1" as *u8)), ws_cmp(m, "<=" as *u8, ws_mem(m, ws_id(m, "sh" as *u8, hty), "t" as *u8, T_F32), ws_f(m, "0.0" as *u8))), ws_cmp(m, ">" as *u8, ws_c3(m, "smarch" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "hp" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "n" as *u8, T_V3F), ws_f(m, "0.02" as *u8), T_V3F), T_V3F), ws_id(m, "sund" as *u8, T_V3F), ws_i(m, "60" as *u8), T_F32), ws_f(m, "0.0" as *u8))), ws_shd(m), 0)
897 ws_st(m, f, ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "sun" as *u8, T_F32), ws_f(m, "0.5" as *u8)), ws_q3(m, sh, ws_if(m, ws_cmp(m, ">" as *u8, ws_mem(m, ws_id(m, "sh" as *u8, hty), "t" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_shd(m), 0), shs), 0))
898 // let col=pal9(bb)*li; let fw9=vec3f(1.0)-exp(-vec3f(0.123,0.287,0.700)*t/168.0); return mix(col,sky(rd),fw9);
899 ws_st(m, f, sir_let(m, "col" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_c1(m, "pal9" as *u8, ws_id(m, "bb" as *u8, T_U32), T_V3F), ws_id(m, "li" as *u8, T_F32), T_V3F), ws_v1(m, T_V3F, ws_id(m, "sp" as *u8, T_F32)), T_V3F))) // GR27: + the film specular
900 let tau: i64 = ws_bin(m, "/" as *u8, ws_bin(m, "*" as *u8, sir_neg(m, ws_v3f(m, "0.123" as *u8, "0.287" as *u8, "0.700" as *u8), T_V3F), ws_id(m, "t" as *u8, T_F32), T_V3F), ws_f(m, "168.0" as *u8), T_V3F)
901 ws_st(m, f, sir_let(m, "fw9" as *u8, T_V3F, ws_bin(m, "-" as *u8, ws_v1(m, T_V3F, ws_f(m, "1.0" as *u8)), ws_c1(m, "exp" as *u8, tau, T_V3F), T_V3F)))
902 ws_st(m, f, ws_ret(m, ws_c3(m, "mix" as *u8, ws_id(m, "col" as *u8, T_V3F), ws_c1(m, "sky" as *u8, ws_id(m, "rd" as *u8, T_V3F), T_V3F), ws_id(m, "fw9" as *u8, T_V3F), T_V3F)))
903 return f
904}
905
906// the hotbar slot's block id: if(s2==0){bt=3;}else if(s2==1){bt=2;}...else{bt=13;}
907func ws_bt(m: *i64, k: *u8, v: *u8, els: i64) -> i64 {
908 return ws_if(m, ws_cmp(m, "==" as *u8, ws_id(m, "s2" as *u8, T_I32), ws_i(m, k)), ws_set(m, ws_id(m, "bt" as *u8, T_I32), ws_i(m, v)), els)
909}
910// px.<a> <op> (o.<a> + <e>) / px.<a> <op> (o.<a> + hbS - <e>)
911func 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)) }
912
913// the fragment entry: fs -- the world pass per pixel, the hand text statement for statement (yflip carries the
914// WebGPU top-left origin as a uniform so ONE source serves both doors)
915// One hit policy for visible geometry and geometry seen through water.
916// Continuous still-water intersection. Level is simulation data; no water voxel supplies geometry.
917func ws_fn_water_hit(m: *i64, hty: i64) -> i64 {
918 let f: i64 = sir_func(m, "water_hit" as *u8, hty)
919 sir_param(m, f, "ro" as *u8, T_V3F); sir_param(m, f, "rd" as *u8, T_V3F)
920 sir_param(m, f, "prior" as *u8, hty); sir_param(m, f, "mx" as *u8, T_I32)
921 ws_st(m, f, ws_if(m, ws_cmp(m, "==" as *u8, ws_sx(m, "rd" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_ret(m, ws_id(m, "prior" as *u8, hty)), 0))
922 ws_st(m, f, sir_let(m, "level" as *u8, T_F32, ws_bin(m, "/" as *u8, sir_cast(m, ws_id(m, "r_water_q8" as *u8, T_I32), T_F32), ws_f(m, "256.0" as *u8), T_F32)))
923 ws_st(m, f, sir_let(m, "wt" as *u8, T_F32, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "level" as *u8, T_F32), ws_sx(m, "ro" as *u8, T_V3F, "y" as *u8, T_F32), T_F32), ws_sx(m, "rd" as *u8, T_V3F, "y" as *u8, T_F32), T_F32)))
924 let outside: i64 = ws_or(m, ws_cmp(m, "<" as *u8, ws_id(m, "wt" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_cmp(m, ">" as *u8, ws_id(m, "wt" as *u8, T_F32), sir_cast(m, ws_id(m, "mx" as *u8, T_I32), T_F32)))
925 ws_st(m, f, ws_if(m, outside, ws_ret(m, ws_id(m, "prior" as *u8, hty)), 0))
926 let occluded: i64 = ws_and(m, ws_cmp(m, ">=" as *u8, ws_mem(m, ws_id(m, "prior" as *u8, hty), "t" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_cmp(m, ">=" as *u8, ws_id(m, "wt" as *u8, T_F32), ws_mem(m, ws_id(m, "prior" as *u8, hty), "t" as *u8, T_F32)))
927 ws_st(m, f, ws_if(m, occluded, ws_ret(m, ws_id(m, "prior" as *u8, hty)), 0))
928 ws_st(m, f, sir_let(m, "wp" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "wt" as *u8, T_F32), T_V3F), T_V3F)))
929 ws_st(m, f, sir_let(m, "bed" as *u8, T_F32, ws_c1(m, "surf" as *u8, ws_sx(m, "wp" as *u8, T_V3F, "xz" as *u8, T_V2F), T_F32)))
930 let dry: i64 = ws_or(m, ws_cmp(m, "<" as *u8, ws_id(m, "bed" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_cmp(m, ">=" as *u8, ws_id(m, "bed" as *u8, T_F32), ws_id(m, "level" as *u8, T_F32)))
931 ws_st(m, f, ws_if(m, dry, ws_ret(m, ws_id(m, "prior" as *u8, hty)), 0))
932 ws_st(m, f, sir_var(m, "result" as *u8, hty, ws_id(m, "prior" as *u8, hty)))
933 ws_st(m, f, ws_set(m, ws_mem(m, ws_id(m, "result" as *u8, hty), "t" as *u8, T_F32), ws_id(m, "wt" as *u8, T_F32)))
934 ws_st(m, f, ws_set(m, ws_mem(m, ws_id(m, "result" as *u8, hty), "b" as *u8, T_U32), ws_u(m, "4" as *u8)))
935 ws_st(m, f, ws_set(m, ws_mem(m, ws_id(m, "result" as *u8, hty), "c" as *u8, T_V3I), ws_v1(m, T_V3I, ws_c1(m, "floor" as *u8, ws_id(m, "wp" as *u8, T_V3F), T_V3F))))
936 ws_st(m, f, ws_set(m, ws_mem(m, ws_id(m, "result" as *u8, hty), "fce" as *u8, T_I32), ws_i(m, "3" as *u8)))
937 ws_st(m, f, ws_if(m, ws_cmp(m, ">" as *u8, ws_sx(m, "rd" as *u8, T_V3F, "y" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_set(m, ws_mem(m, ws_id(m, "result" as *u8, hty), "fce" as *u8, T_I32), ws_i(m, "4" as *u8)), 0))
938 ws_st(m, f, ws_ret(m, ws_id(m, "result" as *u8, hty)))
939 return f
940}
941
942func ws_fn_scene_hit(m: *i64, hty: i64) -> i64 {
943 ws_fn_water_hit(m, hty)
944 let f: i64 = sir_func(m, "scene_hit" as *u8, hty)
945 sir_param(m, f, "ro" as *u8, T_V3F)
946 sir_param(m, f, "rd" as *u8, T_V3F)
947 sir_param(m, f, "skipw" as *u8, T_I32)
948 sir_param(m, f, "mx" as *u8, T_I32)
949 sir_param(m, f, "ts" as *u8, T_F32)
950 ws_st(m, f, sir_var(m, "h" as *u8, hty, ws_c5(m, "march" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_id(m, "rd" as *u8, T_V3F), ws_c2(m, "max" as *u8, ws_id(m, "skipw" as *u8, T_I32), ws_id(m, "r_surf" as *u8, T_I32), T_I32), ws_id(m, "mx" as *u8, T_I32), sir_ident(m, "r_surf" as *u8, T_I32), hty)))
951 // Both camera and transmitted-water rays resolve the same continuous ground.
952 let hp9: i64 = sir_let(m, "hp9" as *u8, T_V3F, ws_bin(m, "+" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "ts" as *u8, T_F32), T_V3F), T_V3F))
953 let cx9: i64 = sir_let(m, "cx9" as *u8, T_I32, sir_cast(m, ws_c1(m, "floor" as *u8, ws_sx(m, "hp9" as *u8, T_V3F, "x" as *u8, T_F32), T_F32), T_I32))
954 let cz9: i64 = sir_let(m, "cz9" as *u8, T_I32, sir_cast(m, ws_c1(m, "floor" as *u8, ws_sx(m, "hp9" as *u8, T_V3F, "z" as *u8, T_F32), T_F32), T_I32))
955 let cy9: i64 = sir_var(m, "cy9" as *u8, T_I32, ws_c2(m, "min" as *u8, sir_cast(m, ws_c1(m, "floor" as *u8, ws_sx(m, "hp9" as *u8, T_V3F, "y" as *u8, T_F32), T_F32), T_I32), ws_i(m, "47" as *u8), T_I32))
956 // Search the actual column extent: water and air cannot supply the seabed material.
957 let ground_class: i64 = ws_c1(m, "terrain" as *u8, ws_c1(m, "vx" as *u8, ws_vt3(m, T_V3I, ws_id(m, "cx9" as *u8, T_I32), ws_id(m, "cy9" as *u8, T_I32), ws_id(m, "cz9" as *u8, T_I32)), T_U32), T_I32)
958 let stop_scan: i64 = ws_or(m, ws_cmp(m, "<=" as *u8, ws_id(m, "cy9" as *u8, T_I32), ws_i(m, "0" as *u8)), ws_cmp(m, "==" as *u8, ground_class, ws_i(m, "1" as *u8)))
959 let scan: i64 = sir_loop(m, ws_q2(m, ws_if(m, stop_scan, sir_break(m), 0), ws_op(m, "cy9" as *u8, T_I32, "-" as *u8, ws_i(m, "1" as *u8))))
960 let sett: i64 = ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "t" as *u8, T_F32), ws_id(m, "ts" as *u8, T_F32))
961 let setf: i64 = ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "fce" as *u8, T_I32), ws_i(m, "3" as *u8))
962 let setc: i64 = ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "c" as *u8, T_V3I), ws_vt3(m, T_V3I, ws_id(m, "cx9" as *u8, T_I32), ws_id(m, "cy9" as *u8, T_I32), ws_id(m, "cz9" as *u8, T_I32)))
963 let setb: i64 = ws_set(m, ws_mem(m, ws_id(m, "h" as *u8, hty), "b" as *u8, T_U32), ws_c1(m, "vx" as *u8, ws_mem(m, ws_id(m, "h" as *u8, hty), "c" as *u8, T_V3I), T_U32))
964 let nearer: i64 = ws_and(m, ws_cmp(m, ">" as *u8, ws_id(m, "ts" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_or(m, ws_cmp(m, "<" as *u8, ws_mem(m, ws_id(m, "h" as *u8, hty), "t" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_cmp(m, "<" as *u8, ws_id(m, "ts" as *u8, T_F32), ws_mem(m, ws_id(m, "h" as *u8, hty), "t" as *u8, T_F32))))
965 let inner: i64 = ws_if(m, nearer, ws_q5(m, hp9, ws_q4(m, cx9, cz9, cy9, scan), sett, setf, ws_q2(m, setc, setb)), 0)
966 ws_st(m, f, ws_if(m, ws_cmp(m, "==" as *u8, sir_ident(m, "r_surf" as *u8, T_I32), ws_i(m, "1" as *u8)), inner, 0))
967 // Resolve water against the same field after ground/objects, preserving nearest-hit ordering.
968 let water_call: i64 = ws_c4(m, "water_hit" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_id(m, "rd" as *u8, T_V3F), ws_id(m, "h" as *u8, hty), ws_id(m, "mx" as *u8, T_I32), hty)
969 ws_st(m, f, ws_if(m, ws_and(m, ws_cmp(m, "==" as *u8, ws_id(m, "r_surf" as *u8, T_I32), ws_i(m, "1" as *u8)), ws_cmp(m, "==" as *u8, ws_id(m, "skipw" as *u8, T_I32), ws_i(m, "0" as *u8))), ws_set(m, ws_id(m, "h" as *u8, hty), water_call), 0))
970 ws_st(m, f, ws_ret(m, ws_id(m, "h" as *u8, hty)))
971 return f
972}
973
974func ws_fn_fs(m: *i64, hty: i64) -> i64 {
975 sir_fragout(m, "fc" as *u8, T_V4F, 0)
976 let f: i64 = sir_func(m, "main" as *u8, T_VOID)
977 sir_param_position(m, f, "pos" as *u8)
978 // upk(); -- GE55: derive every float from the raw words FIRST; every statement below reads the private state
979 ws_st(m, f, sir_expr(m, sir_call(m, "upk" as *u8, T_VOID)))
980 // let px=vec2f(pos.x,mix(pos.y,u.res.y-pos.y,u.yflip));
981 let flipped: i64 = ws_bin(m, "-" as *u8, ws_sx(m, "res" as *u8, T_V2F, "y" as *u8, T_F32), ws_sx(m, "pos" as *u8, T_V4F, "y" as *u8, T_F32), T_F32)
982 ws_st(m, f, sir_let(m, "px" as *u8, T_V2F, ws_v2(m, ws_sx(m, "pos" as *u8, T_V4F, "x" as *u8, T_F32), ws_c3(m, "mix" as *u8, ws_sx(m, "pos" as *u8, T_V4F, "y" as *u8, T_F32), flipped, ws_id(m, "yflip" as *u8, T_F32), T_F32))))
983 // let sc=(px-u.res*0.5)/(u.res.x*0.5);
984 ws_st(m, f, sir_let(m, "sc" as *u8, T_V2F, ws_bin(m, "/" as *u8, ws_bin(m, "-" as *u8, ws_id(m, "px" as *u8, T_V2F), ws_bin(m, "*" as *u8, ws_id(m, "res" as *u8, T_V2F), ws_f(m, "0.5" as *u8), T_V2F), T_V2F), ws_bin(m, "*" as *u8, ws_sx(m, "res" as *u8, T_V2F, "x" as *u8, T_F32), ws_f(m, "0.5" as *u8), T_F32), T_V2F)))
985 // let fw=vec3f(u.yp.x*u.yp.w,u.yp.z,u.yp.y*u.yp.w); let rt=vec3f(u.yp.y,0.0,-u.yp.x); let up=vec3f(-u.yp.x*u.yp.z,u.yp.w,-u.yp.y*u.yp.z);
986 ws_st(m, f, sir_let(m, "fw" as *u8, T_V3F, ws_v3(m, ws_bin(m, "*" as *u8, ws_sx(m, "yp" as *u8, T_V4F, "x" as *u8, T_F32), ws_sx(m, "yp" as *u8, T_V4F, "w" as *u8, T_F32), T_F32), ws_sx(m, "yp" as *u8, T_V4F, "z" as *u8, T_F32), ws_bin(m, "*" as *u8, ws_sx(m, "yp" as *u8, T_V4F, "y" as *u8, T_F32), ws_sx(m, "yp" as *u8, T_V4F, "w" as *u8, T_F32), T_F32))))
987 ws_st(m, f, sir_let(m, "rt" as *u8, T_V3F, ws_v3(m, ws_sx(m, "yp" as *u8, T_V4F, "y" as *u8, T_F32), ws_f(m, "0.0" as *u8), sir_neg(m, ws_sx(m, "yp" as *u8, T_V4F, "x" as *u8, T_F32), T_F32))))
988 ws_st(m, f, sir_let(m, "up" as *u8, T_V3F, ws_v3(m, ws_bin(m, "*" as *u8, sir_neg(m, ws_sx(m, "yp" as *u8, T_V4F, "x" as *u8, T_F32), T_F32), ws_sx(m, "yp" as *u8, T_V4F, "z" as *u8, T_F32), T_F32), ws_sx(m, "yp" as *u8, T_V4F, "w" as *u8, T_F32), ws_bin(m, "*" as *u8, sir_neg(m, ws_sx(m, "yp" as *u8, T_V4F, "y" as *u8, T_F32), T_F32), ws_sx(m, "yp" as *u8, T_V4F, "z" as *u8, T_F32), T_F32))))
989 // let rd=normalize(fw+rt*sc.x+up*sc.y); let ro=u.cam; let h=march(ro,rd,0,200);
990 ws_st(m, f, sir_let(m, "rd" as *u8, T_V3F, ws_c1(m, "normalize" as *u8, ws_bin(m, "+" as *u8, ws_bin(m, "+" as *u8, ws_id(m, "fw" as *u8, T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "rt" as *u8, T_V3F), ws_sx(m, "sc" as *u8, T_V2F, "x" as *u8, T_F32), T_V3F), T_V3F), ws_bin(m, "*" as *u8, ws_id(m, "up" as *u8, T_V3F), ws_sx(m, "sc" as *u8, T_V2F, "y" as *u8, T_F32), T_V3F), T_V3F), T_V3F)))
991 ws_st(m, f, sir_let(m, "ro" as *u8, T_V3F, ws_id(m, "cam" as *u8, T_V3F)))
992 // Water and camera use this identical ray against the same immutable per-frame field.
993 ws_st(m, f, sir_var(m, "ground_t" as *u8, T_F32, ws_f(m, "-1.0" as *u8)))
994 ws_st(m, f, ws_if(m, ws_cmp(m, "==" as *u8, sir_ident(m, "r_surf" as *u8, T_I32), ws_i(m, "1" as *u8)), ws_set(m, ws_id(m, "ground_t" as *u8, T_F32), ws_c3(m, "smarch" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_id(m, "rd" as *u8, T_V3F), ws_i(m, "200" as *u8), T_F32)), 0))
995 ws_st(m, f, sir_let(m, "h" as *u8, hty, ws_c5(m, "scene_hit" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_id(m, "rd" as *u8, T_V3F), ws_i(m, "0" as *u8), ws_i(m, "200" as *u8), ws_id(m, "ground_t" as *u8, T_F32), hty)))
996 // var col:vec3f; if(h.t<0.0){col=sky(rd);}else{col=shade(...);if(h.b==4u){let h2=march(ro,rd,1,200);if(h2.t>0.0){col=col*0.58+shade(...h2...)*0.42;}}}
997 ws_st(m, f, sir_var(m, "col" as *u8, T_V3F, 0))
998 let sh1: i64 = ws_c6(m, "shade" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_id(m, "rd" as *u8, T_V3F), ws_mem(m, ws_id(m, "h" as *u8, hty), "t" as *u8, T_F32), ws_mem(m, ws_id(m, "h" as *u8, hty), "c" as *u8, T_V3I), ws_mem(m, ws_id(m, "h" as *u8, hty), "fce" as *u8, T_I32), ws_mem(m, ws_id(m, "h" as *u8, hty), "b" as *u8, T_U32), T_V3F)
999 let sh2: i64 = ws_c6(m, "shade" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_id(m, "rd" as *u8, T_V3F), ws_mem(m, ws_id(m, "h2" as *u8, hty), "t" as *u8, T_F32), ws_mem(m, ws_id(m, "h2" as *u8, hty), "c" as *u8, T_V3I), ws_mem(m, ws_id(m, "h2" as *u8, hty), "fce" as *u8, T_I32), ws_mem(m, ws_id(m, "h2" as *u8, hty), "b" as *u8, T_U32), T_V3F)
1000 let blend: i64 = ws_set(m, ws_id(m, "col" as *u8, T_V3F), ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_id(m, "col" as *u8, T_V3F), ws_f(m, "0.58" as *u8), T_V3F), ws_bin(m, "*" as *u8, sh2, ws_f(m, "0.42" as *u8), T_V3F), T_V3F))
1001 let h2: i64 = sir_let(m, "h2" as *u8, hty, ws_c5(m, "scene_hit" as *u8, ws_id(m, "ro" as *u8, T_V3F), ws_id(m, "rd" as *u8, T_V3F), ws_i(m, "1" as *u8), ws_i(m, "200" as *u8), ws_id(m, "ground_t" as *u8, T_F32), hty))
1002 let water: i64 = ws_if(m, ws_cmp(m, "==" as *u8, ws_mem(m, ws_id(m, "h" as *u8, hty), "b" as *u8, T_U32), ws_u(m, "4" as *u8)), ws_q2(m, h2, ws_if(m, ws_cmp(m, ">" as *u8, ws_mem(m, ws_id(m, "h2" as *u8, hty), "t" as *u8, T_F32), ws_f(m, "0.0" as *u8)), blend, 0)), 0)
1003 ws_st(m, f, ws_if(m, ws_cmp(m, "<" as *u8, ws_mem(m, ws_id(m, "h" as *u8, hty), "t" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_set(m, ws_id(m, "col" as *u8, T_V3F), ws_c1(m, "sky" as *u8, ws_id(m, "rd" as *u8, T_V3F), T_V3F)), ws_q2(m, ws_set(m, ws_id(m, "col" as *u8, T_V3F), sh1), water)))
1004 // let ctr=u.res*0.5;
1005 ws_st(m, f, sir_let(m, "ctr" as *u8, T_V2F, ws_bin(m, "*" as *u8, ws_id(m, "res" as *u8, T_V2F), ws_f(m, "0.5" as *u8), T_V2F)))
1006 // if(u.rain>0.5){let rr=h21(vec2f(floor((px.x+px.y*0.35)/2.0),floor((px.y+u.t*13.0)/26.0)));if(rr>0.945){col=mix(col,vec3f(0.75,0.8,0.92),0.45);}col*=0.93;}
1007 let rrx: i64 = ws_c1(m, "floor" as *u8, ws_bin(m, "/" as *u8, ws_bin(m, "+" as *u8, ws_sx(m, "px" as *u8, T_V2F, "x" as *u8, T_F32), ws_bin(m, "*" as *u8, ws_sx(m, "px" as *u8, T_V2F, "y" as *u8, T_F32), ws_f(m, "0.35" as *u8), T_F32), T_F32), ws_f(m, "2.0" as *u8), T_F32), T_F32)
1008 let rry: i64 = ws_c1(m, "floor" as *u8, ws_bin(m, "/" as *u8, ws_bin(m, "+" as *u8, ws_sx(m, "px" as *u8, T_V2F, "y" as *u8, T_F32), ws_bin(m, "*" as *u8, ws_id(m, "t" as *u8, T_F32), ws_f(m, "13.0" as *u8), T_F32), T_F32), ws_f(m, "26.0" as *u8), T_F32), T_F32)
1009 let rr: i64 = sir_let(m, "rr" as *u8, T_F32, ws_c1(m, "h21" as *u8, ws_v2(m, rrx, rry), T_F32))
1010 let drops: i64 = ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "rr" as *u8, T_F32), ws_f(m, "0.945" as *u8)), ws_set(m, ws_id(m, "col" as *u8, T_V3F), ws_c3(m, "mix" as *u8, ws_id(m, "col" as *u8, T_V3F), ws_v3f(m, "0.75" as *u8, "0.8" as *u8, "0.92" as *u8), ws_f(m, "0.45" as *u8), T_V3F)), 0)
1011 ws_st(m, f, ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "rain" as *u8, T_F32), ws_f(m, "0.5" as *u8)), ws_q3(m, rr, drops, ws_op(m, "col" as *u8, T_V3F, "*" as *u8, ws_f(m, "0.93" as *u8))), 0))
1012 // the crosshair
1013 let dx: i64 = ws_c1(m, "abs" as *u8, ws_bin(m, "-" as *u8, ws_sx(m, "px" as *u8, T_V2F, "x" as *u8, T_F32), ws_sx(m, "ctr" as *u8, T_V2F, "x" as *u8, T_F32), T_F32), T_F32)
1014 let dy: i64 = ws_c1(m, "abs" as *u8, ws_bin(m, "-" as *u8, ws_sx(m, "px" as *u8, T_V2F, "y" as *u8, T_F32), ws_sx(m, "ctr" as *u8, T_V2F, "y" as *u8, T_F32), T_F32), T_F32)
1015 let dx2: i64 = ws_c1(m, "abs" as *u8, ws_bin(m, "-" as *u8, ws_sx(m, "px" as *u8, T_V2F, "x" as *u8, T_F32), ws_sx(m, "ctr" as *u8, T_V2F, "x" as *u8, T_F32), T_F32), T_F32)
1016 let dy2: i64 = ws_c1(m, "abs" as *u8, ws_bin(m, "-" as *u8, ws_sx(m, "px" as *u8, T_V2F, "y" as *u8, T_F32), ws_sx(m, "ctr" as *u8, T_V2F, "y" as *u8, T_F32), T_F32), T_F32)
1017 let cross: i64 = ws_or(m, ws_and(m, ws_cmp(m, "<" as *u8, dx, ws_f(m, "8.0" as *u8)), ws_cmp(m, "<" as *u8, dy, ws_f(m, "1.5" as *u8))), ws_and(m, ws_cmp(m, "<" as *u8, dy2, ws_f(m, "8.0" as *u8)), ws_cmp(m, "<" as *u8, dx2, ws_f(m, "1.5" as *u8))))
1018 let ccol: i64 = ws_if(m, ws_cmp(m, ">=" as *u8, ws_id(m, "npct" as *u8, T_F32), ws_f(m, "0.0" as *u8)), ws_set(m, ws_id(m, "col" as *u8, T_V3F), ws_v3f(m, "1.0" as *u8, "0.45" as *u8, "0.65" as *u8)), ws_if(m, ws_cmp(m, ">" as *u8, ws_id(m, "hok" as *u8, T_F32), ws_f(m, "0.5" as *u8)), ws_set(m, ws_id(m, "col" as *u8, T_V3F), ws_v3f(m, "1.0" as *u8, "0.82" as *u8, "0.35" as *u8)), ws_set(m, ws_id(m, "col" as *u8, T_V3F), ws_v1(m, T_V3F, ws_f(m, "1.0" as *u8)))))
1019 ws_st(m, f, ws_if(m, cross, ccol, 0))
1020 // let hbY=u.res.y*0.045;let hbS=u.res.x*0.018;
1021 ws_st(m, f, sir_let(m, "hbY" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_sx(m, "res" as *u8, T_V2F, "y" as *u8, T_F32), ws_f(m, "0.045" as *u8), T_F32)))
1022 ws_st(m, f, sir_let(m, "hbS" as *u8, T_F32, ws_bin(m, "*" as *u8, ws_sx(m, "res" as *u8, T_V2F, "x" as *u8, T_F32), ws_f(m, "0.018" as *u8), T_F32)))
1023 // for(var s2:i32=0;s2<7;s2++){let o=vec2f(u.res.x*0.02+f32(s2)*hbS*1.5,hbY); if(inside){var bt:i32; <bt chain>; if(s2<5){col=u.pal[bt-1].xyz;}else{col=u.palf[bt-12].xyz;} if(selected&&edge){col=vec3f(1.0);}}}
1024 let ox: i64 = ws_bin(m, "+" as *u8, ws_bin(m, "*" as *u8, ws_sx(m, "res" as *u8, T_V2F, "x" as *u8, T_F32), ws_f(m, "0.02" as *u8), T_F32), ws_bin(m, "*" as *u8, ws_bin(m, "*" as *u8, sir_cast(m, ws_id(m, "s2" as *u8, T_I32), T_F32), ws_id(m, "hbS" as *u8, T_F32), T_F32), ws_f(m, "1.5" as *u8), T_F32), T_F32)
1025 let o: i64 = sir_let(m, "o" as *u8, T_V2F, ws_v2(m, ox, ws_id(m, "hbY" as *u8, T_F32)))
1026 let inside: i64 = ws_and(m, ws_and(m, ws_and(m, ws_pxo(m, "x" as *u8, ">=" as *u8, ws_f(m, "0.0" as *u8)), ws_pxo(m, "x" as *u8, "<" as *u8, ws_id(m, "hbS" as *u8, T_F32))), ws_pxo(m, "y" as *u8, ">=" as *u8, ws_f(m, "0.0" as *u8))), ws_pxo(m, "y" as *u8, "<" as *u8, ws_id(m, "hbS" as *u8, T_F32)))
1027 let btv: i64 = sir_var(m, "bt" as *u8, T_I32, 0)
1028 let btc: i64 = ws_bt(m, "0" as *u8, "3" as *u8, ws_bt(m, "1" as *u8, "2" as *u8, ws_bt(m, "2" as *u8, "6" as *u8, ws_bt(m, "3" as *u8, "7" as *u8, ws_bt(m, "4" as *u8, "5" as *u8, ws_bt(m, "5" as *u8, "12" as *u8, ws_set(m, ws_id(m, "bt" as *u8, T_I32), ws_i(m, "13" as *u8))))))))
1029 let pick: i64 = ws_if(m, ws_cmp(m, "<" as *u8, ws_id(m, "s2" as *u8, T_I32), ws_i(m, "5" as *u8)),
1030 ws_set(m, ws_id(m, "col" as *u8, T_V3F), ws_sw(m, sir_index(m, ws_id(m, "pal" as *u8, T_V4F), ws_bin(m, "-" as *u8, ws_id(m, "bt" as *u8, T_I32), ws_i(m, "1" as *u8), T_I32), T_V4F), "xyz" as *u8, T_V3F)),
1031 ws_set(m, ws_id(m, "col" as *u8, T_V3F), ws_sw(m, sir_index(m, ws_id(m, "palf" as *u8, T_V4F), ws_bin(m, "-" as *u8, ws_id(m, "bt" as *u8, T_I32), ws_i(m, "12" as *u8), T_I32), T_V4F), "xyz" as *u8, T_V3F)))
1032 let rim: i64 = ws_or(m, ws_or(m, ws_or(m, ws_pxo(m, "x" as *u8, "<" as *u8, ws_f(m, "2.0" as *u8)), ws_cmp(m, ">" as *u8, ws_sx(m, "px" as *u8, T_V2F, "x" as *u8, T_F32), ws_bin(m, "-" as *u8, ws_bin(m, "+" as *u8, ws_sx(m, "o" as *u8, T_V2F, "x" as *u8, T_F32), ws_id(m, "hbS" as *u8, T_F32), T_F32), ws_f(m, "2.0" as *u8), T_F32))), ws_pxo(m, "y" as *u8, "<" as *u8, ws_f(m, "2.0" as *u8))), ws_cmp(m, ">" as *u8, ws_sx(m, "px" as *u8, T_V2F, "y" as *u8, T_F32), ws_bin(m, "-" as *u8, ws_bin(m, "+" as *u8, ws_sx(m, "o" as *u8, T_V2F, "y" as *u8, T_F32), ws_id(m, "hbS" as *u8, T_F32), T_F32), ws_f(m, "2.0" as *u8), T_F32)))
1033 let selected: i64 = ws_if(m, ws_and(m, ws_cmp(m, "==" as *u8, ws_id(m, "bt" as *u8, T_I32), sir_cast(m, ws_id(m, "selb" as *u8, T_F32), T_I32)), rim), ws_set(m, ws_id(m, "col" as *u8, T_V3F), ws_v1(m, T_V3F, ws_f(m, "1.0" as *u8))), 0)
1034 let slot: i64 = ws_if(m, inside, ws_q4(m, btv, btc, pick, selected), 0)
1035 sir_for_until(m, f, sir_var(m, "s2" as *u8, T_I32, ws_i(m, "0" as *u8)), ws_cmp(m, ">=" as *u8, ws_id(m, "s2" as *u8, T_I32), ws_i(m, "7" as *u8)), ws_op(m, "s2" as *u8, T_I32, "+" as *u8, ws_i(m, "1" as *u8)), ws_q2(m, o, slot))
1036 // return vec4f(vec3f(0.94)*pow(max(col,vec3f(0.0))*(1.0/0.94),vec3f(1.45)),1.0);
1037 let graded: i64 = ws_bin(m, "*" as *u8, ws_v1(m, T_V3F, ws_f(m, "0.94" as *u8)), ws_c2(m, "pow" as *u8, ws_bin(m, "*" as *u8, ws_c2(m, "max" as *u8, ws_id(m, "col" as *u8, T_V3F), ws_v1(m, T_V3F, ws_f(m, "0.0" as *u8)), T_V3F), ws_bin(m, "/" as *u8, ws_f(m, "1.0" as *u8), ws_f(m, "0.94" as *u8), T_F32), T_V3F), ws_v1(m, T_V3F, ws_f(m, "1.45" as *u8)), T_V3F), T_V3F)
1038 ws_st(m, f, ws_ret(m, ws_vt2(m, T_V4F, graded, ws_f(m, "1.0" as *u8))))
1039 return f
1040}
1041
1042// THE WORLD MODULE: uniforms, the voxel texture, struct Hit, every function, the fragment entry. Returns the entry.
1043func shsrc_world(m: *i64) -> i64 {
1044 ws_world_uniforms_raw(m)
1045 ws_world_privates(m)
1046 sir_texture(m, "tV" as *u8, T_TEX3U)
1047 sir_texture(m, "tH" as *u8, T_TEX2F) // GE53: the surface field, one f32 height per column (r32float 128x128), uploaded from the sim's hq block
1048 let hty: i64 = sir_struct_ty(ws_struct_hit(m))
1049 ws_fn_rgb9(m)
1050 ws_fn_upk(m)
1051 ws_fn_vx(m)
1052 ws_fn_h21(m)
1053 ws_fn_h31(m)
1054 ws_fn_vn3(m) // PG22: the cloud volume's noise, density and march -- after h31, before sky which calls cld3
1055 ws_fn_cvol(m)
1056 ws_fn_csun(m)
1057 ws_fn_cloud_decode(m)
1058 ws_fn_cloud_encode(m)
1059 ws_fn_cloud_phase(m)
1060 ws_fn_cloud_incident(m)
1061 ws_fn_cld3(m)
1062 ws_fn_pal9(m)
1063 ws_fn_sky(m)
1064 ws_fn_hq(m)
1065 ws_fn_surf(m)
1066 ws_fn_terrain(m)
1067 ws_fn_smarch(m)
1068 ws_fn_gnd(m)
1069 ws_fn_sand(m) // GR27: after surf, h21, vx and gnd (GLSL declares before use), before shade which calls it
1070 ws_fn_march(m, hty)
1071 ws_fn_scene_hit(m, hty)
1072 ws_fn_shade(m, hty)
1073 return ws_fn_fs(m, hty)
1074}