code wiki / (root) / nx_world_shader_cumulus_canonical_t156.nx

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}