code wiki / _hdl_build / nx_ng_gsview.nx
nx_ng_gsview.nx source
↩ module page · 167 lines · 10378 B
1// nx_ng_gsview.nx -- CAP-GS-REALTIME, generation 11: the real-time Gaussian-splat RASTERIZER + VIEWER, and the
2// first VISIBLE artifact of the neural-graphics ladder. Takes explicit gaussian primitives (the CAP-GAUSSIAN-SPLAT
3// representation), SORTS them by depth, SPLATS each as a radial footprint into a software RGB framebuffer, and
4// ALPHA-OVER composites front-to-back -- a single forward pass (no per-ray iteration = "real-time"). Then EMITS
5// the framebuffer as a pixel-perfect HTML canvas you can open.
6//
7// SOVEREIGN per the visual law ([[project-sovereign-visual-engine-2026-06-17]]): pixels authored in NishiLang,
8// software raster into nx_image, displayed via the proven nx_scene_demo canvas bridge (base64 -> putImageData =
9// the ONLY browser touch, a framebuffer surface, NOT WebGL/WebGPU). Reuses nx_image + nx_base64; the canvas
10// emitter is copied from nx_scene_demo (that organ has a main(), so we copy the 3 fns rather than import it).
11//
12// Honest gated proof: T1 RENDER -- a gaussian splats a colored blob at its center (center pixel ~= its color,
13// background elsewhere); T2 DEPTH-SORT -- the index sort orders gaussians front-to-back (min depth first);
14// T3 OCCLUSION -- where a FRONT gaussian overlaps a BACK one, the front color dominates (real alpha-over);
15// T4 VISIBLE ARTIFACT -- a non-trivial canvas page is emitted to web_assets/ng_gsplat_view.html.
16// HONEST: radial parabolic footprint (the exp-Gaussian kernel is proven in nx_ng_gsplat); 1-pass global sort
17// (tile binning = the real-time-at-scale follow-on); fixed primitives (optimization = nx_ng_gsplat). no float.
18// Sovereign. license_tier: ORIGINAL expect_exit: 0
19import "nx_image.nx"
20import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
21import "nx_base64.nx"
22const K_MAGIC_262144: i64 = 262144
23
24const VLOG: *u8 = "knowledge/status/ng_gsview.log"
25const OUTP: *u8 = "web_assets/ng_gsplat_view.html"
26const NGA: i64 = 4
27
28func vpr(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
29// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
30// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
31// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
32// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
33func vpn(v: i64) -> i64 { nxi_out(v); return 0 }
34func vl_ws(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
35// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
36// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
37// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
38// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
39func vl_wn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 }
40
41// --- canvas emitter copied verbatim from nx_scene_demo (sovereign framebuffer -> pixel-perfect canvas) ---
42func sc_app(out: *u8, off: *i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { out[off[0]] = s[i]; off[0] = off[0] + 1; i = i + 1 } return 0 }
43func sc_app_n(out: *u8, off: *i64, v: i64) -> i64 {
44 let t: *u8 = sys_mmap(28); var m: i64 = v; var k: i64 = 0
45 if m == 0 { t[0] = 48 as u8; k = 1 }
46 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
47 var q: i64 = k - 1; while q >= 0 { out[off[0]] = t[q]; off[0] = off[0] + 1; q = q - 1 }
48 return 0
49}
50func nx_img_canvas_page(img: *Image, scale: i64, out: *u8, cap: i64) -> i64 {
51 let W: i64 = img.width
52 let H: i64 = img.height
53 let nbytes: i64 = W * H * 3
54 let b64: *u8 = sys_mmap(nbytes * 2 + 64)
55 let bn: i64 = b64_encode(img.pixels, nbytes, b64)
56 let off: *i64 = (sys_mmap(8)) as *i64
57 off[0] = 0
58 sc_app(out, off, "<!doctype html><html><head><meta charset=\"utf-8\"><title>Nishi Gaussian-Splat Viewer</title></head><body style=\"background:#111;text-align:center\">" as *u8)
59 sc_app(out, off, "<h2 style=\"color:#dde;font-family:sans-serif\">CAP-GS-REALTIME — sovereign software splat raster (no WebGL), pixels authored in NishiLang</h2>" as *u8)
60 sc_app(out, off, "<canvas id=c width=" as *u8); sc_app_n(out, off, W * scale)
61 sc_app(out, off, " height=" as *u8); sc_app_n(out, off, H * scale)
62 sc_app(out, off, " style=\"image-rendering:pixelated;border:2px solid #444\"></canvas><script>var W=" as *u8); sc_app_n(out, off, W)
63 sc_app(out, off, ",H=" as *u8); sc_app_n(out, off, H)
64 sc_app(out, off, ",S=" as *u8); sc_app_n(out, off, scale)
65 sc_app(out, off, ",b=\"" as *u8)
66 var i: i64 = 0
67 while i < bn { out[off[0]] = b64[i]; off[0] = off[0] + 1; i = i + 1 }
68 sc_app(out, off, "\";var r=atob(b),o=document.createElement('canvas');o.width=W;o.height=H;var x=o.getContext('2d'),d=x.createImageData(W,H),p=0,i2=0;for(i2=0;i2<W*H;i2++){d.data[i2*4]=r.charCodeAt(p++);d.data[i2*4+1]=r.charCodeAt(p++);d.data[i2*4+2]=r.charCodeAt(p++);d.data[i2*4+3]=255;}x.putImageData(d,0,0);var c=document.getElementById('c'),t=c.getContext('2d');t.imageSmoothingEnabled=false;t.drawImage(o,0,0,W*S,H*S);</script></body></html>\n" as *u8)
69 out[off[0]] = 0 as u8
70 return off[0]
71}
72
73func main() -> i64 {
74 vpr("nx_ng_gsview: CAP-GS-REALTIME -- 2D depth-sorted gaussian-splat raster + viewer (sovereign, no float)\n" as *u8)
75 let W: i64 = 64
76 let H: i64 = 64
77 let img: *Image = nx_image_alloc(W, H, 3)
78
79 // explicit gaussian primitives (scrambled depth order on purpose -> the SORT must fix it). per g: cx,cy,r2,depth,R,G,B
80 let cx: *i64=sys_mmap(NGA*8) as *i64; let cy: *i64=sys_mmap(NGA*8) as *i64; let r2: *i64=sys_mmap(NGA*8) as *i64
81 let dep: *i64=sys_mmap(NGA*8) as *i64; let cr: *i64=sys_mmap(NGA*8) as *i64; let cg: *i64=sys_mmap(NGA*8) as *i64; let cb: *i64=sys_mmap(NGA*8) as *i64
82 cx[0]=24; cy[0]=34; r2[0]=225; dep[0]=20; cr[0]=255; cg[0]=40; cb[0]=40 // red
83 cx[1]=40; cy[1]=34; r2[1]=225; dep[1]=30; cr[1]=40; cg[1]=255; cb[1]=40 // green (behind red)
84 cx[2]=32; cy[2]=18; r2[2]=144; dep[2]=10; cr[2]=60; cg[2]=90; cb[2]=255 // blue (frontmost)
85 cx[3]=46; cy[3]=46; r2[3]=100; dep[3]=25; cr[3]=240; cg[3]=220; cb[3]=40 // yellow
86
87 // T2: DEPTH SORT (selection sort of indices, ascending depth = front-to-back)
88 let ord: *i64=sys_mmap(NGA*8) as *i64
89 var i: i64=0; while i<NGA { ord[i]=i; i=i+1 }
90 i=0
91 while i<NGA {
92 var mn: i64=i; var j: i64=i+1
93 while j<NGA { if dep[ord[j]] < dep[ord[mn]] { mn=j } j=j+1 }
94 let tmp: i64=ord[i]; ord[i]=ord[mn]; ord[mn]=tmp
95 i=i+1
96 }
97 var sort_ok: i64=1
98 if ord[0]!=2 { sort_ok=0 } // blue (depth 10) must be first
99 if ord[NGA-1]!=1 { sort_ok=0 } // green (depth 30) must be last
100
101 // RENDER: per pixel, alpha-over composite the sorted gaussians (front-to-back) over a dark background
102 let bgR: i64=20; let bgG: i64=20; let bgB: i64=32
103 var y: i64=0
104 while y < H {
105 var x: i64=0
106 while x < W {
107 var T: i64=256; var aR: i64=0; var aG: i64=0; var aB: i64=0
108 var k: i64=0
109 while k < NGA {
110 let g: i64=ord[k]
111 let dx: i64=x-cx[g]; let dy: i64=y-cy[g]; let d2: i64=dx*dx+dy*dy
112 if d2 < r2[g] {
113 var alpha: i64 = 256 - (d2*256)/r2[g] // parabolic radial footprint (256 center -> 0 edge)
114 if alpha<0 { alpha=0 }
115 if alpha>256 { alpha=256 }
116 let w: i64=(T*alpha)/256
117 aR=aR+(w*cr[g])/256; aG=aG+(w*cg[g])/256; aB=aB+(w*cb[g])/256
118 T=(T*(256-alpha))/256
119 }
120 k=k+1
121 }
122 aR=aR+(T*bgR)/256; aG=aG+(T*bgG)/256; aB=aB+(T*bgB)/256
123 nx_image_set(img,x,y,0,aR); nx_image_set(img,x,y,1,aG); nx_image_set(img,x,y,2,aB)
124 x=x+1
125 }
126 y=y+1
127 }
128
129 // T1 RENDER: red gaussian center pixel ~ red
130 let r_c: i64=nx_image_get(img,24,34,0); let r_cg: i64=nx_image_get(img,24,34,1); let r_cb: i64=nx_image_get(img,24,34,2)
131 var t1: i64=0; if r_c>180 { if r_cg<100 { if r_cb<100 { t1=1 } } }
132 // T3 OCCLUSION: red(front,depth20) overlaps green(back,depth30) near (32,34) -> red dominates
133 let o_r: i64=nx_image_get(img,32,34,0); let o_g: i64=nx_image_get(img,32,34,1)
134 var t3: i64=0; if o_r > o_g { t3=1 }
135 // background corner
136 let bg_chk: i64=nx_image_get(img,1,1,2)
137
138 // T4 EMIT the visible canvas
139 let out: *u8=sys_mmap(K_MAGIC_262144)
140 let len: i64=nx_img_canvas_page(img, 6, out, K_MAGIC_262144)
141 var wrote: i64=0
142 let fd: i64=sys_openat_wr(OUTP, 420)
143 if fd>=0 { sys_write(fd,out,len); sys_close(fd); wrote=1 }
144 var t4: i64=0; if len>1000 { if wrote==1 { t4=1 } }
145
146 vpr(" T1 render: red-center rgb=(" as *u8); vpn(r_c); vpr("," as *u8); vpn(r_cg); vpr("," as *u8); vpn(r_cb); vpr(") ~red=" as *u8); vpn(t1); vpr("\n" as *u8)
147 vpr(" T2 depth-sort order=[" as *u8); vpn(ord[0]); vpr("," as *u8); vpn(ord[1]); vpr("," as *u8); vpn(ord[2]); vpr("," as *u8); vpn(ord[3]); vpr("] (front->back) ok=" as *u8); vpn(sort_ok); vpr("\n" as *u8)
148 vpr(" T3 occlusion: overlap(32,34) R=" as *u8); vpn(o_r); vpr(" G=" as *u8); vpn(o_g); vpr(" front-dominates=" as *u8); vpn(t3); vpr("\n" as *u8)
149 vpr(" T4 emitted " as *u8); vpn(len); vpr(" bytes -> " as *u8); vpr(OUTP); vpr(" wrote=" as *u8); vpn(wrote); vpr("\n" as *u8)
150
151 var ok: i64=1
152 if t1!=1 { ok=0 }
153 if sort_ok!=1 { ok=0 }
154 if t3!=1 { ok=0 }
155 if t4!=1 { ok=0 }
156 let logf: i64=sys_openat_append(VLOG, 420)
157 if logf>=0 {
158 vl_ws(logf,"NGGSVIEW authored=organ gs-realtime-2d bytes=" as *u8); vl_wn(logf,len)
159 vl_ws(logf," t1=" as *u8); vl_wn(logf,t1); vl_ws(logf," sort=" as *u8); vl_wn(logf,sort_ok); vl_ws(logf," t3=" as *u8); vl_wn(logf,t3); vl_ws(logf," t4=" as *u8); vl_wn(logf,t4)
160 if ok==1 { vl_ws(logf," verdict=GREEN\n" as *u8) } else { vl_ws(logf," verdict=RED\n" as *u8) }
161 sys_close(logf)
162 }
163 vpr(" verdict=" as *u8)
164 if ok==1 { vpr("GREEN (depth-sorted gaussian splats composited into a software framebuffer + emitted a viewable canvas = real-time splat viewer)\n" as *u8); sys_exit(0); return 0 }
165 vpr("RED\n" as *u8)
166 sys_exit(1); return 1
167}