code wiki / _hdl_build / nx_cornell_gate.nx
nx_cornell_gate.nx source
↩ module page · 121 lines · 6248 B
1// nx_cornell_gate.nx -- ★THE CORNELL BOX GI VERIFICATION (field-evidence rung 3). The field's standard light-transport
2// test, solved with Goral et al.'s own radiosity method. The verification is MEASURED and CAUSAL:
3// T1 DIRECT-ONLY control: white back wall has r-g == EXACTLY 0 (white light on neutral white -- no tint source).
4// T2 WITH BOUNCE: colour bleeding APPEARS -- back-wall column beside the RED wall turns r>g, beside the GREEN wall g>r.
5// (The tint can ONLY have come from interreflection: the walls are the only coloured thing in the scene.)
6// T3 SOFT SHADOW: floor beside the tall block (occluded from the light) is much darker than open floor.
7// T4 determinism. T5 the classic image -> knowledge/nx_cornell.png (direct-only | with interreflection).
8// license_tier: ORIGINAL expect_exit: 0
9import "nx_syscalls.nx"
10import "nx_png.nx"
11import "nx_trimesh.nx"
12import "nx_cornell.nx"
13
14func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
15func pn(v: i64) -> i64 { let b: *u8=sys_mmap(32) as *u8; var x: i64=v; var ng: i64=0; if x<0{ng=1;x=0-x} var i: i64=31; if x==0{b[i]=48 as u8;i=i-1} while x>0{b[i]=(48+x%10) as u8;x=x/10;i=i-1} if ng==1{b[i]=45 as u8;i=i-1} sys_write(1,(b as i64+i+1) as *u8,31-i); return 0 }
16func clearfb(fb: *i64, n: i64, c: i64) -> i64 { var i: i64=0; while i<n { fb[i]=c; i=i+1 } return 0 }
17
18const BG: i64 = 10 + 10*256 + 14*65536
19const W: i64 = 400
20const H: i64 = 420
21
22// mean (r-g) over back-wall column i (indices 200 + i*12 + j, j=0..11)
23func col_rg(i: i64) -> i64 {
24 let b3: *i64 = sys_mmap(24) as *i64
25 var s: i64 = 0
26 var j: i64 = 0
27 while j < 12 { cor_b(200 + i*12 + j, b3); s = s + (b3[0] - b3[1]); j = j + 1 }
28 return s/12
29}
30// index of the floor patch (0..99) nearest x,z
31func floor_near(x: i64, z: i64) -> i64 {
32 let c3: *i64 = sys_mmap(24) as *i64
33 var best: i64 = 0-1
34 var bd: i64 = 9000000000
35 var i: i64 = 0
36 while i < 100 {
37 cor_center(i, c3)
38 let dx: i64 = c3[0]-x
39 let dz: i64 = c3[2]-z
40 let d: i64 = dx*dx + dz*dz
41 if d < bd { bd = d; best = i }
42 i = i + 1
43 }
44 return best
45}
46func lum(i: i64) -> i64 { let b3: *i64 = sys_mmap(24) as *i64; cor_b(i, b3); return (b3[0]+b3[1]+b3[2])/3 }
47
48func main() -> i64 {
49 hw("=== nx_cornell_gate -- the Cornell box: measured colour bleeding + soft shadow (radiosity) ===\n" as *u8)
50 var fails: i64 = 0
51 let np: i64 = cornell_build()
52 hw(" patches="); pn(np); hw("\n" as *u8)
53 cornell_formfactors()
54
55 // ---- T1 direct-only control: NO bleeding possible ----
56 cornell_solve(1)
57 let d_red: i64 = col_rg(0) // column beside the RED wall
58 let d_grn: i64 = col_rg(11) // column beside the GREEN wall
59 hw(" direct-only back wall: (r-g) red-side="); pn(d_red); hw(" green-side="); pn(d_grn); hw("\n" as *u8)
60 var t1: i64 = 0
61 if d_red == 0 { if d_grn == 0 { t1 = 1 } }
62 if t1 == 1 { hw("T1 PASS direct-only control: white wall is EXACTLY neutral (r-g == 0) -- no tint without a bounce\n" as *u8) }
63 else { fails=fails+1; hw("T1 FAIL\n" as *u8) }
64
65 // ---- T2 with interreflection: colour bleeding APPEARS ----
66 cornell_solve(4)
67 let b_red: i64 = col_rg(0)
68 let b_grn: i64 = 0 - col_rg(11) // g-r on the green side
69 let mid: i64 = col_rg(6) // centre column: near-neutral
70 var amid: i64 = mid
71 if amid < 0 { amid = 0-amid }
72 hw(" with bounce: red-side (r-g)=+"); pn(b_red); hw(" green-side (g-r)=+"); pn(b_grn); hw(" centre |r-g|="); pn(amid); hw("\n" as *u8)
73 var t2: i64 = 0
74 if b_red > 10 { if b_grn > 10 { if b_red > amid*3 { if b_grn > amid*3 { t2 = 1 } } } }
75 if t2 == 1 { hw("T2 PASS COLOUR BLEEDING: red wall tints the white wall red, green tints it green, centre stays near-neutral -- the Cornell phenomenon, from interreflection ONLY\n" as *u8) }
76 else { fails=fails+1; hw("T2 FAIL\n" as *u8) }
77
78 // ---- T3 soft shadow: floor occluded by the tall block vs open floor ----
79 let sh: i64 = floor_near(0-230, 330)
80 let op: i64 = floor_near(210, 300)
81 let lsh: i64 = lum(sh)
82 let lop: i64 = lum(op)
83 hw(" floor: shadowed(beside tall block) lum="); pn(lsh); hw(" open lum="); pn(lop); hw("\n" as *u8)
84 var t3: i64 = 0
85 if lop > 0 { if lsh*100 < lop*72 { t3 = 1 } }
86 if t3 == 1 { hw("T3 PASS SOFT SHADOW: the tall block occludes the area light (shadowed floor markedly darker)\n" as *u8) }
87 else { fails=fails+1; hw("T3 FAIL\n" as *u8) }
88
89 // ---- T4 determinism ----
90 let keep: *i64 = sys_mmap(8) as *i64
91 keep[0] = col_rg(0)
92 cornell_solve(4)
93 var t4: i64 = 0
94 if col_rg(0) == keep[0] { t4 = 1 }
95 if t4 == 1 { hw("T4 PASS deterministic\n" as *u8) } else { fails=fails+1; hw("T4 FAIL\n" as *u8) }
96
97 // ---- T5 the classic image: direct-only | with interreflection ----
98 let npx: i64 = W*H
99 let fb: *i64 = sys_mmap(npx*8) as *i64
100 let zb: *i64 = sys_mmap(npx*8) as *i64
101 let GW: i64 = W*2
102 let gal: *i64 = sys_mmap(GW*H*8) as *i64
103 clearfb(gal, GW*H, BG)
104 cornell_solve(1)
105 cornell_tomesh(1900)
106 clearfb(fb, npx, BG); trimesh_zclear(zb, npx); trimesh_render(fb, zb, W, H, 0, 0, 800, 540, 3)
107 var y: i64 = 0
108 while y < H { var x: i64=0; while x<W { gal[y*GW+x]=fb[y*W+x]; x=x+1 } y=y+1 }
109 cornell_solve(4)
110 cornell_tomesh(1900)
111 clearfb(fb, npx, BG); trimesh_zclear(zb, npx); trimesh_render(fb, zb, W, H, 0, 0, 800, 540, 3)
112 y = 0
113 while y < H { var x: i64=0; while x<W { gal[y*GW+W+x]=fb[y*W+x]; x=x+1 } y=y+1 }
114 write_png(gal, GW, H, "knowledge/nx_cornell.png" as *u8)
115 hw("T5 evidence -> knowledge/nx_cornell.png (direct-only | with interreflection)\n" as *u8)
116
117 if fails == 0 { hw("CORNELL-GATE GREEN -- the Cornell box on the sovereign stack: patch radiosity (Goral et al.'s method for Goral et al.'s box), MEASURED colour bleeding (indirect-only, causally isolated by the direct-only control) + occluder soft shadow, deterministic. Residual vs the full reference: measured spectral reflectances + rotated blocks + photograph comparison -> census PARTIAL, honestly.\n" as *u8); sys_exit(0); return 0 }
118 hw("CORNELL-GATE RED fails="); pn(fails); hw("\n" as *u8)
119 sys_exit(1)
120 return 1
121}