code wiki / (root) / nx_gi_path_gate.nx

nx_gi_path_gate.nx source

↩ module page · 156 lines · 9626 B

1// nx_gi_path_gate.nx -- THE TEETH OF THE BEAUTY TIER'S FIRST BYTE (graphics GR42 / GR10). In-process over 2// nx_gi_path_lib: no fork, no fixture files, every tooth arithmetic on the tracer's own functions, so the gate runs in 3// well under a second and its RED can only mean the transport changed. Inherits nx_gate_verdict (gv_check / gv_bite / 4// gv_verdict): the exit code IS the verdict, declared == executed by construction, and every neg-control is NAMED so the 5// gatelaw census can see it. 6// WHAT IS PROVEN HERE, and only this: (1) a hit is refined onto the surface (the no-terracing law) and the refinement is 7// load-bearing (the incumbent raymarcher's bare step would miss by more than the tolerance); (2) a path is deterministic 8// byte-for-byte under one seed and changes under another; (3) the linear decode pairs with the display encode (the 9// pale-frame defect fires the neg-control); (4) the cosine-weighted sampler has the cosine mean 2/3 (a uniform sampler's 10// 1/2 fires the neg-control); (5) a straight-up ray is sky-only; (6) transport never gains energy; (7) directions 11// normalise; (8) the palette stays in display range. NOT PROVEN: photorealism, or anything a referee would grade -- 12// that is GR42's UNGRADED cell until a calibrated referee exists. 13// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 14import "nx_syscalls.nx" 15import "nx_gate_verdict.nx" 16import "nx_gi_path_lib.nx" 17 18const GG_SEED: i64 = 77 19const GG_WORDS: i64 = 16 20const GG_SURF_TOL: i64 = 2 // units: a refined hit may sit this far from the terrain surface (2^-8 of a step, rounded up) 21const GG_DOWN_Y: i64 = 0 - 700 // a ray pitched down toward the terrain (fx1024 components before normalising) 22const GG_DOWN_Z: i64 = 731 23const GG_SAMPLES: i64 = 4096 // cosine-sampler census size 24const GG_COS_MEAN: i64 = 683 // E[cos] over a cosine-weighted hemisphere = 2/3, in fx1024 25const GG_UNIFORM_MEAN: i64 = 512 // E[cos] over a UNIFORM hemisphere = 1/2: the wrong sampler's signature 26const GG_COS_TOL: i64 = 24 // 4096 samples of an integer sampler: 3 sigma is ~14, the band is wider than that on purpose 27const GG_RT_TOL: i64 = 1 // sqrt(lin(c)*255) must land within one display step of c 28const GG_LEN_TOL: i64 = 2 29const GG_N_PROBES: i64 = 5 30const GG_PITCH_STEP: i64 = 512 // yaw step between fixture probe rays (1/8 turn) 31const GG_PITCH_LIFT: i64 = 60 // each probe pitches a little higher so one of them clears the lake 32 33func gg_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 34// a newline WITHOUT a newline literal: the nx lexer treats a bare-newline string as ambiguous (banked law), so the byte is constructed 35func gg_nl() -> i64 { let b: *u8 = sys_mmap(2); b[0] = 10 as u8; sys_write(1, b, 1); sys_munmap(b, 2); return 0 } 36 37func main() -> i64 { 38 gv_head("nx_gi_path_gate -- the sovereign path tracer's transport laws, in-process" as *u8) 39 let ctr: *i64 = gv_ctr() 40 let Wp: *i64 = sys_mmap(32*8) as *i64 41 wg_weather(0, Wp) 42 let hitb: *i64 = sys_mmap(GG_WORDS*8) as *i64 43 let n: *i64 = sys_mmap(GG_WORDS*8) as *i64 44 let alb: *i64 = sys_mmap(GG_WORDS*8) as *i64 45 let scr: *i64 = sys_mmap(GG_WORDS*8) as *i64 46 let dir: *i64 = sys_mmap(GG_WORDS*8) as *i64 47 let sky: *i64 = sys_mmap(GG_WORDS*8) as *i64 48 let L: *i64 = sys_mmap(GG_WORDS*8) as *i64 49 let L2: *i64 = sys_mmap(GG_WORDS*8) as *i64 50 let stats: *i64 = sys_mmap(GG_WORDS*8) as *i64 51 let st: *i64 = sys_mmap(GG_WORDS*8) as *i64 52 let d: *i64 = sys_mmap(GG_WORDS*8) as *i64 53 let camy: i64 = wg_cam_base_y(GG_SEED) 54 55 // ---- (1) the hit is refined onto the surface, and the refinement is load-bearing 56 d[0] = 0; d[1] = GG_DOWN_Y; d[2] = GG_DOWN_Z 57 gp_norm3(d) 58 let hit: i64 = gp_march(0, camy, 0, d[0], d[1], d[2], GG_SEED, hitb) 59 gv_check("down-ray-hits-terrain" as *u8, hit, ctr) 60 let gap: i64 = gg_abs(hitb[2] - hitb[4]) 61 gv_check("hit-refined-onto-surface-within-tolerance" as *u8, (gap <= GG_SURF_TOL) as i64, ctr) 62 let coarse_step: i64 = GP_STEP_MIN + hitb[5]/GP_STEP_DIV // what the last unrefined step was at that distance 63 gv_bite("neg-control-unrefined-step-would-miss-the-surface" as *u8, (coarse_step > GG_SURF_TOL) as i64, (gap > GG_SURF_TOL) as i64, ctr) 64 65 // ---- (2) determinism under one seed, difference under another. THE FIXTURE MUST REACH THE STOCHASTIC BRANCH: 66 // the first probe ray landed on the LAKE (a deterministic mirror event), so the seed tooth was vacuous by 67 // construction. Search pitches until the primary ray lands on terrain above water, and assert that it did. 68 var pk: i64 = 0 69 var found: i64 = 0 70 while pk < 8 { 71 if found == 0 { 72 d[0] = it_sin4096(pk*GG_PITCH_STEP)*GG_DOWN_Z/GP_CIRCLE; d[1] = GG_DOWN_Y + pk*GG_PITCH_LIFT; d[2] = it_cos4096(pk*GG_PITCH_STEP)*GG_DOWN_Z/GP_CIRCLE 73 gp_norm3(d) 74 stats[GP_ST_TERRAIN] = 0; stats[GP_ST_WATER] = 0; stats[GP_ST_SKY] = 0 75 st[0] = GG_SEED*GP_LCG_A + GP_LCG_C 76 gp_trace(0, camy, 0, d[0], d[1], d[2], GG_SEED, Wp, st, hitb, n, alb, scr, dir, sky, L, stats) 77 if stats[GP_ST_TERRAIN] > 0 { found = 1 } 78 } 79 pk = pk + 1 80 } 81 gv_check("fixture-reached-a-terrain-hit-before-the-seed-teeth" as *u8, found, ctr) 82 gv_puts(" values: L=" as *u8); gv_num(L[0]); gv_puts("," as *u8); gv_num(L[1]); gv_puts("," as *u8); gv_num(L[2]); gv_puts(" terrain_hits=" as *u8); gv_num(stats[GP_ST_TERRAIN]); gg_nl() 83 let a0: i64 = L[0]; let a1: i64 = L[1]; let a2: i64 = L[2] 84 st[0] = GG_SEED*GP_LCG_A + GP_LCG_C 85 gp_trace(0, camy, 0, d[0], d[1], d[2], GG_SEED, Wp, st, hitb, n, alb, scr, dir, sky, L2, stats) 86 var same: i64 = 0 87 if a0 == L2[0] { if a1 == L2[1] { if a2 == L2[2] { same = 1 } } } 88 gv_check("same-seed-same-path-byte-identical" as *u8, same, ctr) 89 st[0] = (GG_SEED + 1)*GP_LCG_A + GP_LCG_C 90 gp_trace(0, camy, 0, d[0], d[1], d[2], GG_SEED, Wp, st, hitb, n, alb, scr, dir, sky, L2, stats) 91 var differs: i64 = 1 92 if a0 == L2[0] { if a1 == L2[1] { if a2 == L2[2] { differs = 0 } } } 93 gv_puts(" values: other-seed L=" as *u8); gv_num(L2[0]); gv_puts("," as *u8); gv_num(L2[1]); gv_puts("," as *u8); gv_num(L2[2]); gg_nl() 94 gv_bite("neg-control-different-sampler-seed-changes-the-estimate" as *u8, differs, 1 - same, ctr) 95 96 // ---- (3) linear decode pairs with the display encode (the pale-frame defect fires the neg-control) 97 var rt_ok: i64 = 1 98 var raw_fires: i64 = 0 99 var pi: i64 = 1 100 while pi <= GG_N_PROBES { 101 let c: i64 = pi*GP_MAXCH/GG_N_PROBES // 51, 102, 153, 204, 255 102 let back: i64 = vm_isqrt(gp_lin(c)*GP_MAXCH/GP_FX) 103 if gg_abs(back - c) > GG_RT_TOL { rt_ok = 0 } 104 let raw: i64 = vm_isqrt(c*GP_FX*GP_MAXCH/GP_FX) // encoding a DISPLAY value as if it were linear radiance 105 if gg_abs(raw - c) > GG_RT_TOL { raw_fires = 1 } 106 pi = pi + 1 107 } 108 gv_check("linear-decode-then-encode-returns-the-display-value" as *u8, rt_ok, ctr) 109 gv_bite("neg-control-encoding-display-as-linear-is-caught" as *u8, raw_fires, 1 - rt_ok, ctr) 110 111 // ---- (4) the cosine-weighted sampler: mean cosine 2/3, a uniform sampler's 1/2 would fire 112 n[0] = 0; n[1] = GP_FX; n[2] = 0 113 st[0] = GG_SEED 114 var sum: i64 = 0 115 var below: i64 = 0 116 var k: i64 = 0 117 while k < GG_SAMPLES { 118 gp_cosine_dir(n, st, scr, dir) 119 sum = sum + dir[1] 120 if dir[1] < 0 { below = below + 1 } 121 k = k + 1 122 } 123 let mean: i64 = sum/GG_SAMPLES 124 gv_check("cosine-sampler-mean-cosine-is-two-thirds" as *u8, (gg_abs(mean - GG_COS_MEAN) <= GG_COS_TOL) as i64, ctr) 125 gv_check("cosine-sampler-never-leaves-the-hemisphere" as *u8, (below == 0) as i64, ctr) 126 gv_bite("neg-control-uniform-hemisphere-mean-would-fire" as *u8, (gg_abs(GG_UNIFORM_MEAN - GG_COS_MEAN) > GG_COS_TOL) as i64, (gg_abs(mean - GG_COS_MEAN) > GG_COS_TOL) as i64, ctr) 127 128 // ---- (5) a straight-up ray is sky-only, (6) transport never gains energy 129 stats[GP_ST_SKY] = 0; stats[GP_ST_TERRAIN] = 0; stats[GP_ST_WATER] = 0 130 d[0] = 0; d[1] = GP_FX; d[2] = 0 131 st[0] = GG_SEED 132 gp_trace(0, camy, 0, d[0], d[1], d[2], GG_SEED, Wp, st, hitb, n, alb, scr, dir, sky, L, stats) 133 gv_check("straight-up-ray-is-sky-only" as *u8, ((stats[GP_ST_SKY] == 1) & (stats[GP_ST_TERRAIN] == 0)) as i64, ctr) 134 let cap: i64 = GP_MAXCH*GP_FX*GP_FX 135 gv_check("sky-path-radiance-never-exceeds-the-source" as *u8, ((L[0] <= cap) & (L[1] <= cap) & (L[2] <= cap)) as i64, ctr) 136 137 // ---- (7) directions normalise, (8) palette stays in display range 138 d[0] = 300; d[1] = 400; d[2] = 0 139 gp_norm3(d) 140 let len2: i64 = vm_isqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]) 141 gv_check("norm3-yields-a-unit-fx1024-vector" as *u8, (gg_abs(len2 - GP_FX) <= GG_LEN_TOL) as i64, ctr) 142 var pal_ok: i64 = 1 143 var q: i64 = 0 144 while q < GG_N_PROBES { 145 let hx: i64 = q*GP_VEG_SCALE 146 let hh: i64 = wg_terrain_h(hx, hx, GG_SEED) 147 gp_albedo(hx, hx, hh, GP_FX, GG_SEED, alb) 148 if alb[0] < 0 { pal_ok = 0 } if alb[0] > GP_MAXCH { pal_ok = 0 } 149 if alb[1] < 0 { pal_ok = 0 } if alb[1] > GP_MAXCH { pal_ok = 0 } 150 if alb[2] < 0 { pal_ok = 0 } if alb[2] > GP_MAXCH { pal_ok = 0 } 151 q = q + 1 152 } 153 gv_check("albedo-palette-stays-in-display-range" as *u8, pal_ok, ctr) 154 155 return gv_verdict("nx_gi_path_gate" as *u8, ctr, "transport laws of the sovereign integer path tracer, tested in-process on the library; photorealism is NOT claimed here" as *u8) 156}