code wiki / _hdl_build / nx_being_showcase.nx
nx_being_showcase.nx source
↩ module page · 203 lines · 8441 B
1// nx_being_showcase.nx -- ★VISUAL-PARITY RUNG for /compare/koikatsu (operator 2026-08-04, frank feedback:
2// "we have no colors, we have a clay blob, no sense of human form"). The clay was the COARSE single-mesh export
3// rendered with every quality feature OFF. This organ renders the being the estate can already build: DENSE atlas
4// skin (GC=9, 2x the scene gate), per-part vertex colors (ba_part_color), Gouraud + Blinn-Phong specular +
5// baked sun shadows + multi-octave albedo, SSAA still, plus a TOON still (posterize + z-edge lines = the
6// cel-shade R rung, first bit native) and the lit turntable APNG. Writes STRAIGHT into the page dir (run from
7// ~/nishihost). Composes nx_bodyatlas + nx_isosurf + nx_trimesh + nx_png + nx_apng_write -- zero foreign code.
8// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
9import "nx_syscalls.nx"
10import "nx_png.nx"
11import "nx_trimesh.nx"
12import "nx_isosurf.nx"
13import "nx_bodyatlas.nx"
14import "nx_apng_write.nx"
15const NB_MAGIC_1024: i64 = 1024
16const NB_MAGIC_2400: i64 = 2400
17const NB_MAGIC_1500: i64 = 1500
18const NB_MAGIC_2600: i64 = 2600
19
20const NB_W: i64 = 360
21const NB_H: i64 = 552
22const TT_W: i64 = 240
23const TT_H: i64 = 368
24const TT_FRAMES: i64 = 18
25const NB_BG: i64 = 24 + 26*256 + 34*65536
26const NB_MAGIC_65536: i64 = 65536
27const NB_ZFAR: i64 = 1999999999
28const NB_EDGE: i64 = 45
29const NB_LINE: i64 = 20 + 22*256 + 28*65536
30const NB_SKIN: i64 = 234 + 192*256 + 170*65536
31const NB_YAW: i64 = 450
32const NB_PITCH: i64 = 0-150
33const NB_CAMZ: i64 = 2600
34const NB_FOCAL: i64 = 780
35const NB_CIRCLE: i64 = 6283
36// dense grid: SAME extents as nx_gltf_scene_gate (origin -288/-990/-180, span 576x1980x360), HALF the cell size
37const GX: i64 = 64
38const GY: i64 = 220
39const GZ: i64 = 40
40const GC: i64 = 9
41const OX: i64 = 0-288
42const OY: i64 = 0-990
43const OZ: i64 = 0-180
44static GRID: i64
45
46func bs_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
47func bs_num(v: i64) -> i64 {
48 let b: *u8 = sys_mmap(32)
49 var x: i64 = v; var ng: i64 = 0
50 if x < 0 { ng = 1; x = 0-x }
51 var i: i64 = 31
52 if x == 0 { b[i]=48 as u8; i=i-1 }
53 while x > 0 { b[i]=(48+x%10) as u8; x=x/10; i=i-1 }
54 if ng == 1 { b[i]=45 as u8; i=i-1 }
55 sys_write(1,(b as i64+i+1) as *u8,31-i)
56 return 0
57}
58
59func fill_grid(mask: i64) -> i64 {
60 let g: *i64 = GRID as *i64
61 var i: i64 = 0
62 while i <= GX { var jj: i64=0; while jj<=GY { var k: i64=0; while k<=GZ { g[(i*(GY+1)+jj)*(GZ+1)+k] = ba_sdf(OX+i*GC, OY+jj*GC, OZ+k*GC, mask); k=k+1 } jj=jj+1 } i=i+1 }
63 return 0
64}
65// uniform SKIN albedo -- one believable tone, let the LIGHT do the talking. Per-part colors are for the
66// anatomy peel views; on the outer skin they read as random patches (measured by eye on the first cut,
67// and the noise albedo posterized into camo under the cel pass).
68func bs_skin_paint() -> i64 {
69 var i: i64 = 0
70 let nv: i64 = tm_nv()
71 let skr: i64 = 234
72 let skg: i64 = 192
73 let skb: i64 = 170
74 let sk: i64 = skr + skg*256 + skb*NB_MAGIC_65536
75 bs_w("const-direct=" as *u8); bs_num(NB_SKIN); bs_w(" local=" as *u8); bs_num(sk); bs_w("\n" as *u8)
76 while i < nv { tm_vcol(i, NB_SKIN); i=i+1 }
77 return 0
78}
79
80// ★the cel pass: 4-band posterize on model pixels + dark lines on depth discontinuities and the silhouette.
81// Works on the fb/zb pair alone -- the rasterizer is untouched (the toon look is a POST-projection of the same render).
82func bs_toon(fb: *i64, zb: *i64, W: i64, H: i64) -> i64 {
83 // cel v2: quantize BRIGHTNESS into bands against the known flat albedo, then recolor -- per-channel
84 // posterize drifted hue (bands crossed at different points per channel -> pink/green patches, seen on cut 1).
85 var i: i64 = 0
86 while i < W*H {
87 if zb[i] < NB_ZFAR {
88 let px: i64 = fb[i]
89 let r: i64 = px&255
90 let g: i64 = (px>>8)&255
91 let b: i64 = (px>>16)&255
92 let sum: i64 = r + g + b
93 var band: i64 = 440
94 if sum > 300 { band = 760 }
95 if sum > 640 { band = NB_MAGIC_1024 }
96 var r2: i64 = 234*band/NB_MAGIC_1024
97 var g2: i64 = 192*band/NB_MAGIC_1024
98 var b2: i64 = 170*band/NB_MAGIC_1024
99 if sum > 820 { r2 = 250; g2 = 240; b2 = 232 }
100 fb[i] = r2 + g2*256 + b2*NB_MAGIC_65536
101 }
102 i = i + 1
103 }
104 var y: i64 = 1
105 while y < H {
106 var x: i64 = 1
107 while x < W {
108 let idx: i64 = y*W + x
109 var edge: i64 = 0
110 let z0: i64 = zb[idx]
111 let zl: i64 = zb[idx-1]
112 let zu: i64 = zb[idx-W]
113 var on0: i64 = 0
114 if z0 < NB_ZFAR { on0 = 1 }
115 var onl: i64 = 0
116 if zl < NB_ZFAR { onl = 1 }
117 var onu: i64 = 0
118 if zu < NB_ZFAR { onu = 1 }
119 if on0 != onl { edge = 1 }
120 if on0 != onu { edge = 1 }
121 if on0 == 1 { if onl == 1 { var d: i64 = z0-zl; if d < 0 { d = 0-d } if d > NB_EDGE { edge = 1 } } }
122 if on0 == 1 { if onu == 1 { var d2: i64 = z0-zu; if d2 < 0 { d2 = 0-d2 } if d2 > NB_EDGE { edge = 1 } } }
123 if edge == 1 { fb[idx] = NB_LINE }
124 x = x + 1
125 }
126 y = y + 1
127 }
128 return 0
129}
130
131func main() -> i64 {
132 bs_w("=== nx_being_showcase -- dense colored lit being -> still + toon + turntable (all-native chain) ===\n" as *u8)
133 atlas_build(0)
134 GRID = sys_mmap((GX+1)*(GY+1)*(GZ+1)*8) as i64
135 fill_grid(1)
136 tm_reset()
137 surface_nets(GRID as *i64, GX, GY, GZ, OX, OY, OZ, GC, 0, 200+200*256+200*NB_MAGIC_65536)
138 bs_skin_paint()
139 bs_w("vcol0=" as *u8); bs_num(tm_getvcol(0)); bs_w("\n" as *u8)
140 bs_w("skin verts=" as *u8); bs_num(tm_nv()); bs_w(" tris=" as *u8); bs_num(tm_nt()); bs_w(" ovf=" as *u8); bs_num(tm_ovf()); bs_w("\n" as *u8)
141 if tm_ovf() != 0 { bs_w("FAIL: mesh truncated at capacity -- refusing to render a wrong-looking body (never silently shrink)\n" as *u8); sys_exit(1); return 1 }
142
143 tm_set_spec(110)
144 tm_set_sun(0-900, NB_MAGIC_2400, 0-NB_MAGIC_1500)
145 tm_shadow_bake()
146 tm_set_shadow(1)
147
148 let npx: i64 = NB_W * NB_H
149 let fb: *i64 = sys_mmap(npx * 8) as *i64
150 let zb: *i64 = sys_mmap(npx * 8) as *i64
151 var i: i64 = 0
152
153 // 1) the lit still: SSAA, 3/4 view like their portrait
154 i = 0
155 while i < npx { fb[i] = NB_BG; i = i + 1 }
156 trimesh_render_aa(fb, NB_W, NB_H, NB_YAW, NB_PITCH, NB_CAMZ, NB_FOCAL, 2)
157 write_png(fb, NB_W, NB_H, "sites/nishifamily/compare/koikatsu/nishi_native_still.png" as *u8)
158 bs_w("WROTE nishi_native_still.png (lit, SSAA, uniform skin albedo, shadowed)\n" as *u8)
159
160 // 2) the toon still: same view through the cel post-pass (the R-rung witness)
161 i = 0
162 while i < npx { fb[i] = NB_BG; i = i + 1 }
163 trimesh_zclear(zb, npx)
164 trimesh_render(fb, zb, NB_W, NB_H, NB_YAW, NB_PITCH, NB_CAMZ, NB_FOCAL, 2)
165 bs_toon(fb, zb, NB_W, NB_H)
166 write_png(fb, NB_W, NB_H, "sites/nishifamily/compare/koikatsu/nishi_native_toon.png" as *u8)
167 bs_w("WROTE nishi_native_toon.png (posterize + z-edge cel pass)\n" as *u8)
168
169 // 3) the lit turntable APNG (noise albedo OFF to hold bytes under the 8MiB edge serve cap)
170 tm_set_tex(0)
171 let tpx: i64 = TT_W * TT_H
172 let tfb: *i64 = sys_mmap(tpx * 8) as *i64
173 let tzb: *i64 = sys_mmap(tpx * 8) as *i64
174 let rgb: *u8 = sys_mmap(tpx * 3 + 16)
175 let st_raw: *u8 = sys_mmap(NX_APNG_STATE_BYTES)
176 let st: *ApngState = st_raw as *ApngState
177 if apng_open(st, "sites/nishifamily/compare/koikatsu/nishi_native_turntable.png" as *u8, TT_W, TT_H, TT_FRAMES, 6, 100) != 0 {
178 bs_w("FAIL: apng open\n" as *u8); sys_exit(1); return 1
179 }
180 var f: i64 = 0
181 while f < TT_FRAMES {
182 i = 0
183 while i < tpx { tfb[i] = NB_BG; i = i + 1 }
184 trimesh_zclear(tzb, tpx)
185 let yaw: i64 = f * NB_CIRCLE / TT_FRAMES
186 trimesh_render(tfb, tzb, TT_W, TT_H, yaw, 0-200, NB_MAGIC_2600, 520, 2)
187 i = 0
188 while i < tpx {
189 let px: i64 = tfb[i]
190 rgb[i*3] = (px & 255) as u8
191 rgb[i*3+1] = ((px >> 8) & 255) as u8
192 rgb[i*3+2] = ((px >> 16) & 255) as u8
193 i = i + 1
194 }
195 apng_frame(st, rgb)
196 f = f + 1
197 }
198 apng_close(st)
199 bs_w("WROTE nishi_native_turntable.png (" as *u8); bs_num(TT_FRAMES)
200 bs_w(" frames, lit+shadowed+colored, native chain)\n" as *u8)
201 sys_exit(0)
202 return 0
203}