code wiki / _hdl_build / nx_retarget_showcase.nx
nx_retarget_showcase.nx source
↩ module page · 208 lines · 8867 B
1// nx_retarget_showcase.nx -- NATIVE-TIER emit of the RETARGETED being (debt 1785902400: capability emits from nishi, not JS) 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_1231: i64 = 1231
16const NB_MAGIC_1403: i64 = 1403
17const NB_MAGIC_1067: i64 = 1067
18const NB_MEASURED_CALF_1179: i64 = 1179 // theirs/ours fx1024 via the converged-thigh derivation (see nx_retarget_emit)
19const NB_MAGIC_1024: i64 = 1024
20const NB_MAGIC_2400: i64 = 2400
21const NB_MAGIC_1500: i64 = 1500
22const NB_MAGIC_2600: i64 = 2600
23
24const NB_W: i64 = 360
25const NB_H: i64 = 552
26const TT_W: i64 = 240
27const TT_H: i64 = 368
28const TT_FRAMES: i64 = 18
29const NB_BG: i64 = 24 + 26*256 + 34*65536
30const NB_MAGIC_65536: i64 = 65536
31const NB_ZFAR: i64 = 1999999999
32const NB_EDGE: i64 = 45
33const NB_LINE: i64 = 20 + 22*256 + 28*65536
34const NB_SKIN: i64 = 234 + 192*256 + 170*65536
35const NB_YAW: i64 = 450
36const NB_PITCH: i64 = 0-150
37const NB_CAMZ: i64 = 2600
38const NB_FOCAL: i64 = 780
39const NB_CIRCLE: i64 = 6283
40// dense grid: SAME extents as nx_gltf_scene_gate (origin -288/-990/-180, span 576x1980x360), HALF the cell size
41const GX: i64 = 64
42const GY: i64 = 220
43const GZ: i64 = 40
44const GC: i64 = 9
45const OX: i64 = 0-288
46const OY: i64 = 0-990
47const OZ: i64 = 0-180
48static GRID: i64
49
50func 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 }
51func bs_num(v: i64) -> i64 {
52 let b: *u8 = sys_mmap(32)
53 var x: i64 = v; var ng: i64 = 0
54 if x < 0 { ng = 1; x = 0-x }
55 var i: i64 = 31
56 if x == 0 { b[i]=48 as u8; i=i-1 }
57 while x > 0 { b[i]=(48+x%10) as u8; x=x/10; i=i-1 }
58 if ng == 1 { b[i]=45 as u8; i=i-1 }
59 sys_write(1,(b as i64+i+1) as *u8,31-i)
60 return 0
61}
62
63func fill_grid(mask: i64) -> i64 {
64 let g: *i64 = GRID as *i64
65 var i: i64 = 0
66 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 }
67 return 0
68}
69// uniform SKIN albedo -- one believable tone, let the LIGHT do the talking. Per-part colors are for the
70// anatomy peel views; on the outer skin they read as random patches (measured by eye on the first cut,
71// and the noise albedo posterized into camo under the cel pass).
72func bs_skin_paint() -> i64 {
73 var i: i64 = 0
74 let nv: i64 = tm_nv()
75 let skr: i64 = 234
76 let skg: i64 = 192
77 let skb: i64 = 170
78 let sk: i64 = skr + skg*256 + skb*NB_MAGIC_65536
79 bs_w("const-direct=" as *u8); bs_num(NB_SKIN); bs_w(" local=" as *u8); bs_num(sk); bs_w("\n" as *u8)
80 while i < nv { tm_vcol(i, NB_SKIN); i=i+1 }
81 return 0
82}
83
84// ★the cel pass: 4-band posterize on model pixels + dark lines on depth discontinuities and the silhouette.
85// Works on the fb/zb pair alone -- the rasterizer is untouched (the toon look is a POST-projection of the same render).
86func bs_toon(fb: *i64, zb: *i64, W: i64, H: i64) -> i64 {
87 // cel v2: quantize BRIGHTNESS into bands against the known flat albedo, then recolor -- per-channel
88 // posterize drifted hue (bands crossed at different points per channel -> pink/green patches, seen on cut 1).
89 var i: i64 = 0
90 while i < W*H {
91 if zb[i] < NB_ZFAR {
92 let px: i64 = fb[i]
93 let r: i64 = px&255
94 let g: i64 = (px>>8)&255
95 let b: i64 = (px>>16)&255
96 let sum: i64 = r + g + b
97 var band: i64 = 440
98 if sum > 300 { band = 760 }
99 if sum > 640 { band = NB_MAGIC_1024 }
100 var r2: i64 = 234*band/NB_MAGIC_1024
101 var g2: i64 = 192*band/NB_MAGIC_1024
102 var b2: i64 = 170*band/NB_MAGIC_1024
103 if sum > 820 { r2 = 250; g2 = 240; b2 = 232 }
104 fb[i] = r2 + g2*256 + b2*NB_MAGIC_65536
105 }
106 i = i + 1
107 }
108 var y: i64 = 1
109 while y < H {
110 var x: i64 = 1
111 while x < W {
112 let idx: i64 = y*W + x
113 var edge: i64 = 0
114 let z0: i64 = zb[idx]
115 let zl: i64 = zb[idx-1]
116 let zu: i64 = zb[idx-W]
117 var on0: i64 = 0
118 if z0 < NB_ZFAR { on0 = 1 }
119 var onl: i64 = 0
120 if zl < NB_ZFAR { onl = 1 }
121 var onu: i64 = 0
122 if zu < NB_ZFAR { onu = 1 }
123 if on0 != onl { edge = 1 }
124 if on0 != onu { edge = 1 }
125 if on0 == 1 { if onl == 1 { var d: i64 = z0-zl; if d < 0 { d = 0-d } if d > NB_EDGE { edge = 1 } } }
126 if on0 == 1 { if onu == 1 { var d2: i64 = z0-zu; if d2 < 0 { d2 = 0-d2 } if d2 > NB_EDGE { edge = 1 } } }
127 if edge == 1 { fb[idx] = NB_LINE }
128 x = x + 1
129 }
130 y = y + 1
131 }
132 return 0
133}
134
135func main() -> i64 {
136 bs_w("=== nx_being_showcase -- dense colored lit being -> still + toon + turntable (all-native chain) ===\n" as *u8)
137 ba_set_axes(363, NB_MAGIC_1231, NB_MAGIC_1403, NB_MAGIC_1067, NB_MEASURED_CALF_1179) // MEASURED Seed-san vector (shw/hipw/arm/thigh/calf)
138 atlas_build(0)
139 GRID = sys_mmap((GX+1)*(GY+1)*(GZ+1)*8) as i64
140 fill_grid(1)
141 tm_reset()
142 surface_nets(GRID as *i64, GX, GY, GZ, OX, OY, OZ, GC, 0, 200+200*256+200*NB_MAGIC_65536)
143 bs_skin_paint()
144 bs_w("vcol0=" as *u8); bs_num(tm_getvcol(0)); bs_w("\n" as *u8)
145 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)
146 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 }
147
148 tm_set_spec(110)
149 tm_set_sun(0-900, NB_MAGIC_2400, 0-NB_MAGIC_1500)
150 tm_shadow_bake()
151 tm_set_shadow(1)
152
153 let npx: i64 = NB_W * NB_H
154 let fb: *i64 = sys_mmap(npx * 8) as *i64
155 let zb: *i64 = sys_mmap(npx * 8) as *i64
156 var i: i64 = 0
157
158 // 1) the lit still: SSAA, 3/4 view like their portrait
159 i = 0
160 while i < npx { fb[i] = NB_BG; i = i + 1 }
161 trimesh_render_aa(fb, NB_W, NB_H, NB_YAW, NB_PITCH, NB_CAMZ, NB_FOCAL, 2)
162 write_png(fb, NB_W, NB_H, "sites/nishifamily/exceed/vrm/nishi_seedsan_native.png" as *u8)
163 bs_w("WROTE nishi_native_still.png (lit, SSAA, uniform skin albedo, shadowed)\n" as *u8)
164
165 // 2) the toon still: same view through the cel post-pass (the R-rung witness)
166 i = 0
167 while i < npx { fb[i] = NB_BG; i = i + 1 }
168 trimesh_zclear(zb, npx)
169 trimesh_render(fb, zb, NB_W, NB_H, NB_YAW, NB_PITCH, NB_CAMZ, NB_FOCAL, 2)
170 bs_toon(fb, zb, NB_W, NB_H)
171 write_png(fb, NB_W, NB_H, "sites/nishifamily/exceed/vrm/nishi_seedsan_toon.png" as *u8)
172 bs_w("WROTE nishi_native_toon.png (posterize + z-edge cel pass)\n" as *u8)
173
174 // 3) the lit turntable APNG (noise albedo OFF to hold bytes under the 8MiB edge serve cap)
175 tm_set_tex(0)
176 let tpx: i64 = TT_W * TT_H
177 let tfb: *i64 = sys_mmap(tpx * 8) as *i64
178 let tzb: *i64 = sys_mmap(tpx * 8) as *i64
179 let rgb: *u8 = sys_mmap(tpx * 3 + 16)
180 let st_raw: *u8 = sys_mmap(NX_APNG_STATE_BYTES)
181 let st: *ApngState = st_raw as *ApngState
182 if apng_open(st, "sites/nishifamily/exceed/vrm/nishi_seedsan_turntable.png" as *u8, TT_W, TT_H, TT_FRAMES, 6, 100) != 0 {
183 bs_w("FAIL: apng open\n" as *u8); sys_exit(1); return 1
184 }
185 var f: i64 = 0
186 while f < TT_FRAMES {
187 i = 0
188 while i < tpx { tfb[i] = NB_BG; i = i + 1 }
189 trimesh_zclear(tzb, tpx)
190 let yaw: i64 = f * NB_CIRCLE / TT_FRAMES
191 trimesh_render(tfb, tzb, TT_W, TT_H, yaw, 0-200, NB_MAGIC_2600, 520, 2)
192 i = 0
193 while i < tpx {
194 let px: i64 = tfb[i]
195 rgb[i*3] = (px & 255) as u8
196 rgb[i*3+1] = ((px >> 8) & 255) as u8
197 rgb[i*3+2] = ((px >> 16) & 255) as u8
198 i = i + 1
199 }
200 apng_frame(st, rgb)
201 f = f + 1
202 }
203 apng_close(st)
204 bs_w("WROTE nishi_native_turntable.png (" as *u8); bs_num(TT_FRAMES)
205 bs_w(" frames, lit+shadowed+colored, native chain)\n" as *u8)
206 sys_exit(0)
207 return 0
208}