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}