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}