code wiki / _hdl_build / nx_anat_sov.nx
nx_anat_sov.nx source
↩ module page · 866 lines · 48728 B
1// nx_anat_sov.nx -- ★SOVEREIGN NishiLang render of the 8-layer anatomical being (NXMSH2), the PRODUCT half of
2// GX-11: the integer twin of the CUDA benchmark (/world/anatomy_gpu). 100% integer, own f32 decoder, own
3// barycentric z-buffer rasterizer, own PNG -- NO CUDA, NO GPU, NO 3rd-party. Measured against the CUDA
4// reference by the SAME invariants: intact occludes the interior, explode shows all 8 systems, stereo has
5// horizontal disparity. Stereo is OFF-AXIS (parallel, convergence at the model) -- an UPGRADE over the
6// benchmark's toe-in (no keystone). Reads knowledge/being_full.nxmesh; writes a PNG + a JSON stats line.
7// nx_anat_sov <mesh> <intact|explode|skin|layerN> <C|L|R> <W> <H> <out.png>
8// license_tier: ORIGINAL expect_exit: 0
9import "nx_syscalls.nx"
10import "nx_png.nx"
11const AS_MAGIC_40500: i64 = 40500
12const AS_MAGIC_8388607: i64 = 8388607
13const AS_MAGIC_8388608: i64 = 8388608
14const AS_MAGIC_73856093: i64 = 73856093
15const AS_MAGIC_19349663: i64 = 19349663
16const AS_MAGIC_83492791: i64 = 83492791
17const AS_MAGIC_2147483647: i64 = 2147483647
18const AS_MAGIC_15731: i64 = 15731
19const AS_MAGIC_789221: i64 = 789221
20const AS_MAGIC_1376312589: i64 = 1376312589
21const AS_MAGIC_65536: i64 = 65536
22const AS_MAGIC_2000000000: i64 = 2000000000
23const AS_MAGIC_5423: i64 = 5423
24const AS_MAGIC_9487: i64 = 9487
25const AS_MAGIC_12206: i64 = 12206
26const AS_MAGIC_10160: i64 = 10160
27const AS_MAGIC_4064: i64 = 4064
28const AS_MAGIC_12190: i64 = 12190
29const AS_MAGIC_1280: i64 = 1280
30const AS_MAGIC_1024: i64 = 1024
31
32// ★seq630 ROOT FIX: positions were decoded to WHOLE model units (mul=1), so any mesh authored in metres
33// rather than millimetres collapsed EVERY coordinate to 0 -> degenerate AABB -> rad=0 -> smE=0 -> integer
34// divide-by-zero -> SIGFPE. (Found on Vh-f-heart, whose coords all lie within +-0.5.) Decoding positions at
35// posq sub-units keeps sub-unit meshes alive; the renderer auto-frames, so absolute scale is irrelevant
36// and only precision matters. Texture lookups divide back to model units so texel size is unchanged.
37const AS_POSQ0: i64 = 4096
38const AS_TARGET: i64 = 200000
39const AS_ZFAR: i64 = 2000000000
40const AS_Q14: i64 = 16384
41
42func as_streq(a: *u8, b: *u8) -> i64 {
43 var i: i64 = 0
44 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 }
45 if b[i] != (0 as u8) { return 0 }
46 return 1
47}
48func as_satoi(s: *u8) -> i64 {
49 var i: i64 = 0; var n: i64 = 0; var sg: i64 = 1
50 if s[0] == (45 as u8) { sg = 0 - 1; i = 1 }
51 while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c >= 48 { if c <= 57 { n = n*10 + (c-48) } } i = i + 1 }
52 return n*sg
53}
54func as_hw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n+1 } sys_write(1, s, n); return 0 }
55func as_pn(v: i64) -> i64 {
56 let b: *u8 = sys_mmap(32); var x: i64 = v; var ng: i64 = 0
57 if x < 0 { ng = 1; x = 0 - x }
58 var i: i64 = 31
59 if x == 0 { b[i] = 48 as u8; i = i - 1 }
60 while x > 0 { b[i] = (48 + x%10) as u8; x = x/10; i = i - 1 }
61 if ng == 1 { b[i] = 45 as u8; i = i - 1 }
62 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i); return 0
63}
64func as_rdbits(b: *u8, o: i64) -> i64 {
65 return (b[o] as i64) | ((b[o+1] as i64)<<8) | ((b[o+2] as i64)<<16) | ((b[o+3] as i64)<<24)
66}
67// decode IEEE-754 float32 at byte offset o, return round(value * mul) as integer
68func as_f32mul(b: *u8, o: i64, mul: i64) -> i64 {
69 let bits: i64 = as_rdbits(b, o)
70 let sign: i64 = (bits>>31) & 1
71 let exp: i64 = (bits>>23) & 255
72 let mant: i64 = bits & AS_MAGIC_8388607
73 if exp == 0 { return 0 }
74 let m: i64 = (mant | AS_MAGIC_8388608) * mul
75 var e: i64 = exp - 127 - 23
76 var v: i64 = 0
77 if e >= 0 { v = m << e } else { let sh: i64 = 0 - e; v = (m + (1 << (sh-1))) >> sh }
78 if sign == 1 { v = 0 - v }
79 return v
80}
81func as_isqrt(v: i64) -> i64 { if v <= 0 { return 0 } var x: i64 = v; var y: i64 = (x+1)/2; while y < x { x = y; y = (x + v/x)/2 } return x }
82// ---- GX-13 integer texture engine: lattice value-noise FBM over WORLD position ----
83// The hardened grader (ns_assess2) names scale (multi-scale detail) + MSCN as our weak axes; real surfaces
84// carry detail at every octave. 4 octaves of smooth value noise = coherent (NOT white noise) so the
85// coherence gate is respected by construction.
86func tx_h3(ix: i64, iy: i64, iz: i64) -> i64 {
87 var v: i64 = (ix*AS_MAGIC_73856093) ^ (iy*AS_MAGIC_19349663) ^ (iz*AS_MAGIC_83492791)
88 v = v & AS_MAGIC_2147483647
89 v = (v * (v*v*AS_MAGIC_15731 + AS_MAGIC_789221) + AS_MAGIC_1376312589) & AS_MAGIC_2147483647
90 return (v >> 16) & 255
91}
92func tx_floordiv(x: i64, s: i64) -> i64 { var q: i64 = x/s; if x < 0 { if x % s != 0 { q = q - 1 } } return q }
93func tx_lerp(a: i64, b: i64, t8: i64) -> i64 { return a + (b-a)*t8/256 }
94func tx_vnoise(x: i64, y: i64, z: i64, s: i64) -> i64 {
95 let lx: i64 = tx_floordiv(x,s); let ly: i64 = tx_floordiv(y,s); let lz: i64 = tx_floordiv(z,s)
96 var fx: i64 = (x - lx*s)*256/s; var fy: i64 = (y - ly*s)*256/s; var fz: i64 = (z - lz*s)*256/s
97 fx = fx*fx*(768 - 2*fx)/AS_MAGIC_65536; fy = fy*fy*(768 - 2*fy)/AS_MAGIC_65536; fz = fz*fz*(768 - 2*fz)/AS_MAGIC_65536
98 let c000: i64 = tx_h3(lx,ly,lz); let c100: i64 = tx_h3(lx+1,ly,lz)
99 let c010: i64 = tx_h3(lx,ly+1,lz); let c110: i64 = tx_h3(lx+1,ly+1,lz)
100 let c001: i64 = tx_h3(lx,ly,lz+1); let c101: i64 = tx_h3(lx+1,ly,lz+1)
101 let c011: i64 = tx_h3(lx,ly+1,lz+1); let c111: i64 = tx_h3(lx+1,ly+1,lz+1)
102 let a0: i64 = tx_lerp(tx_lerp(c000,c100,fx), tx_lerp(c010,c110,fx), fy)
103 let a1: i64 = tx_lerp(tx_lerp(c001,c101,fx), tx_lerp(c011,c111,fx), fy)
104 return tx_lerp(a0, a1, fz)
105}
106func tx_fbm(x: i64, y: i64, z: i64) -> i64 {
107 let n1: i64 = tx_vnoise(x,y,z,128)
108 let n2: i64 = tx_vnoise(x,y,z,40)
109 let n3: i64 = tx_vnoise(x,y,z,12)
110 let n4: i64 = tx_vnoise(x,y,z,4)
111 return (n1*3 + n2*3 + n3*2 + n4*2) / 10
112}
113// ★MULTI-VIEW judge support: Bhaskara-I degree sine, Q14, exact at 0/30/90/150/180. A single view is blind
114// to depth-axis error entirely -- body THICKNESS never appears in a front silhouette -- so the judge must be
115// able to turn the model. Our own integer trig, no float, no lookup-table literals.
116func as_sin_fill(t: *i64) -> i64 {
117 var d: i64 = 0
118 while d < 180 { let P: i64 = d*(180-d); t[d] = AS_Q14*4*P/AS_MAGIC_40500; t[d+180] = 0-t[d]; d = d+1 }
119 return 0
120}
121func as_wrap(d: i64) -> i64 { var x: i64 = d % 360; if x < 0 { x = x + 360 } return x }
122func as_min(a: i64, b: i64) -> i64 { if a < b { return a } return b }
123func as_max(a: i64, b: i64) -> i64 { if a > b { return a } return b }
124
125// ---- GX-39 piece 2: SCREEN-SPACE AMBIENT OCCLUSION over the finished z-buffer (contact darkening) ----
126// PORTED from nx_swgpu sg_ssao (the opposite-pairs design) per the debt row -- port, not rewrite.
127// Why pairs: a naive "is my neighbour nearer" test darkens every receding plane (the classic SSAO false
128// positive that greys floors). In a genuine cavity BOTH opposite samples are nearer; on a plane or slope
129// one is nearer and the other farther, so it scores zero. No normal buffer, nothing added to the raster
130// inner loop -- a pure post-pass, so it cannot regress the rasterizer.
131// SCALE-FREE bounds (bounds are DERIVED, never taste): the bias (depth-noise floor) and far cutoff
132// (a distant surface is a DIFFERENT object, not an occluder -- this is what stops silhouettes being
133// ringed with false shadow) derive from the MEASURED body depth range of the frame (lb>=0 pixels only,
134// so the receding floor cannot inflate the windows), and the ring radii derive from H, so one code path
135// grounds any mesh scale at any render size. AO still APPLIES to floor pixels -- that is exactly what
136// plants the feet (contact darkening where body meets ground).
137// Runs ONLY on the shaded path (never nmap: the mechanistic shape-judge input stays pure geometry), so
138// the geometric bench cannot move BY CONSTRUCTION -- and it is proven anyway by byte-identical
139// nx_bodybench output before/after.
140const AS_AO_STRENGTH: i64 = 140 // occ 8/8 attenuates to (256-140)/256 before the floor below
141const AS_AO_ATT_FLOOR: i64 = 64 // never crush a cavity to black (the donor's floor, kept)
142
143// separable integer box blur over an N x N grid (edge-clamped) -- the soft-shadow field builder
144func as_boxblur(src: *i64, tmp: *i64, dst: *i64, N: i64, r: i64) -> i64 {
145 let span: i64 = 2*r + 1
146 var z4: i64 = 0
147 while z4 < N {
148 var x4: i64 = 0
149 while x4 < N {
150 var acc: i64 = 0
151 var k4: i64 = 0 - r
152 while k4 <= r {
153 var xx: i64 = x4 + k4
154 if xx < 0 { xx = 0 }
155 if xx >= N { xx = N - 1 }
156 acc = acc + src[z4*N + xx]
157 k4 = k4 + 1
158 }
159 tmp[z4*N + x4] = acc/span
160 x4 = x4 + 1
161 }
162 z4 = z4 + 1
163 }
164 z4 = 0
165 while z4 < N {
166 var x4: i64 = 0
167 while x4 < N {
168 var acc: i64 = 0
169 var k4: i64 = 0 - r
170 while k4 <= r {
171 var zz: i64 = z4 + k4
172 if zz < 0 { zz = 0 }
173 if zz >= N { zz = N - 1 }
174 acc = acc + tmp[zz*N + x4]
175 k4 = k4 + 1
176 }
177 dst[z4*N + x4] = acc/span
178 x4 = x4 + 1
179 }
180 z4 = z4 + 1
181 }
182 return 0
183}
184func as_ssao(fb: *i64, zb: *i64, lb: *i64, W2: i64, H2: i64) -> i64 {
185 let npx2: i64 = W2*H2
186 var zmn: i64 = AS_ZFAR; var zmx: i64 = 0
187 var q2: i64 = 0
188 while q2 < npx2 {
189 if lb[q2] >= 0 {
190 let d0: i64 = zb[q2]
191 if d0 < zmn { zmn = d0 }
192 if d0 > zmx { zmx = d0 }
193 }
194 q2 = q2 + 1
195 }
196 let rng: i64 = zmx - zmn
197 if rng < 128 { return 0 } // degenerate/flat frame: nothing meaningful to occlude
198 let bias: i64 = rng/128 // below ~0.8pct of body depth it is depth noise, not a cavity
199 let far2: i64 = rng/6 // beyond ~17pct of body depth it is a different surface
200 var r1: i64 = H2/128; if r1 < 2 { r1 = 2 } // tight ring: contact seams
201 var rw: i64 = H2/56; if rw < 4 { rw = 4 } // wide ring: broad cavities
202 let d1r: i64 = r1*707/1000 + 1
203 let dwr: i64 = rw*707/1000 + 1
204 let ax: *i64 = sys_mmap(16*8) as *i64
205 let ay: *i64 = sys_mmap(16*8) as *i64
206 // 8 opposite pairs: entries s and s+8 are mirrors (the donor's layout, radii derived above)
207 ax[0]=r1; ay[0]=0; ax[1]=d1r; ay[1]=d1r; ax[2]=0; ay[2]=r1; ax[3]=0-d1r; ay[3]=d1r
208 ax[4]=rw; ay[4]=0; ax[5]=dwr; ay[5]=dwr; ax[6]=0; ay[6]=rw; ax[7]=0-dwr; ay[7]=dwr
209 ax[8]=0-r1; ay[8]=0; ax[9]=0-d1r; ay[9]=0-d1r; ax[10]=0; ay[10]=0-r1; ax[11]=d1r; ay[11]=0-d1r
210 ax[12]=0-rw; ay[12]=0; ax[13]=0-dwr; ay[13]=0-dwr; ax[14]=0; ay[14]=0-rw; ax[15]=dwr; ay[15]=0-dwr
211 var y3: i64 = 0
212 while y3 < H2 {
213 var x3: i64 = 0
214 while x3 < W2 {
215 let idx3: i64 = y3*W2 + x3
216 let d: i64 = zb[idx3]
217 if d < AS_ZFAR {
218 var occ: i64 = 0
219 var s: i64 = 0
220 while s < 8 {
221 var near1: i64 = 0
222 var near2: i64 = 0
223 let x1: i64 = x3 + ax[s]
224 let y1: i64 = y3 + ay[s]
225 if x1 >= 0 { if x1 < W2 { if y1 >= 0 { if y1 < H2 {
226 let dd1: i64 = zb[y1*W2 + x1]
227 if dd1 < AS_ZFAR { let df: i64 = d - dd1; if df > bias { if df < far2 { near1 = 1 } } }
228 }}}}
229 let x2: i64 = x3 + ax[s+8]
230 let y2: i64 = y3 + ay[s+8]
231 if x2 >= 0 { if x2 < W2 { if y2 >= 0 { if y2 < H2 {
232 let dd2: i64 = zb[y2*W2 + x2]
233 if dd2 < AS_ZFAR { let df2: i64 = d - dd2; if df2 > bias { if df2 < far2 { near2 = 1 } } }
234 }}}}
235 if near1 == 1 { if near2 == 1 { occ = occ + 1 } } // BOTH sides nearer = a real cavity
236 s = s + 1
237 }
238 if occ > 0 {
239 var att: i64 = 256 - occ*AS_AO_STRENGTH/8
240 if att < AS_AO_ATT_FLOOR { att = AS_AO_ATT_FLOOR }
241 let v: i64 = fb[idx3]
242 let r: i64 = (v % 256)*att/256
243 let g: i64 = ((v/256) % 256)*att/256
244 let b: i64 = ((v/AS_MAGIC_65536) % 256)*att/256
245 fb[idx3] = r + g*256 + b*AS_MAGIC_65536
246 }
247 }
248 x3 = x3 + 1
249 }
250 y3 = y3 + 1
251 }
252 return 0
253}
254
255// ---- GX-39 piece 4: DEPTH OF FIELD keyed on the finished z-buffer ----
256// The last light-transport piece the debt names. Photographic focus: the BODY (the measured lb>=0
257// depth band) stays sharp; floor and backdrop blur with distance from the focus plane, radius derived
258// from H and the measured body depth range (bounds-derived, never taste). Gather guard: a sample only
259// contributes if ITS OWN circle of confusion reaches the target pixel, so the sharp subject can never
260// smear into the background (the classic DoF halo artifact, foreclosed by construction). Shaded path
261// only -- the nmap shape-judge input stays pure geometry.
262func as_dof(fb: *i64, zb: *i64, lb: *i64, W2: i64, H2: i64) -> i64 {
263 let npx2: i64 = W2*H2
264 var zmn: i64 = AS_ZFAR; var zmx: i64 = 0; var zsum: i64 = 0; var zn: i64 = 0
265 var q2: i64 = 0
266 while q2 < npx2 {
267 if lb[q2] >= 0 {
268 let d0: i64 = zb[q2]
269 if d0 < zmn { zmn = d0 }
270 if d0 > zmx { zmx = d0 }
271 zsum = zsum + d0; zn = zn + 1
272 }
273 q2 = q2 + 1
274 }
275 if zn < 1 { return 0 }
276 let rng: i64 = zmx - zmn
277 if rng < 128 { return 0 }
278 let focus: i64 = zsum/zn
279 var maxr: i64 = H2/192; if maxr < 2 { maxr = 2 }
280 let cocb: *i64 = sys_mmap(npx2*8) as *i64 // circle of confusion per pixel (0 = in focus)
281 let srcb: *i64 = sys_mmap(npx2*8) as *i64 // blur reads the unmodified frame
282 q2 = 0
283 while q2 < npx2 {
284 srcb[q2] = fb[q2]
285 var dz: i64 = zb[q2] - focus
286 if dz < 0 { dz = 0 - dz }
287 var coc: i64 = 0
288 if dz > rng/2 { coc = (dz - rng/2)*maxr/(rng*2) }
289 if coc > maxr { coc = maxr }
290 cocb[q2] = coc
291 q2 = q2 + 1
292 }
293 var y3: i64 = 0
294 while y3 < H2 {
295 var x3: i64 = 0
296 while x3 < W2 {
297 let idx3: i64 = y3*W2 + x3
298 let c0: i64 = cocb[idx3]
299 if c0 >= 1 {
300 var ar: i64 = 0; var ag: i64 = 0; var ab: i64 = 0; var an: i64 = 0
301 var dy6: i64 = 0 - c0
302 while dy6 <= c0 {
303 var dx6: i64 = 0 - c0
304 while dx6 <= c0 {
305 let x6: i64 = x3 + dx6
306 let y6: i64 = y3 + dy6
307 if x6 >= 0 { if x6 < W2 { if y6 >= 0 { if y6 < H2 {
308 let si: i64 = y6*W2 + x6
309 var rr: i64 = dx6; if rr < 0 { rr = 0 - rr }
310 var r7: i64 = dy6; if r7 < 0 { r7 = 0 - r7 }
311 if r7 > rr { rr = r7 }
312 if cocb[si] >= rr {
313 let v: i64 = srcb[si]
314 ar = ar + (v % 256)
315 ag = ag + ((v/256) % 256)
316 ab = ab + ((v/AS_MAGIC_65536) % 256)
317 an = an + 1
318 }
319 }}}}
320 dx6 = dx6 + 1
321 }
322 dy6 = dy6 + 1
323 }
324 if an > 0 { fb[idx3] = ar/an + (ag/an)*256 + (ab/an)*AS_MAGIC_65536 }
325 }
326 x3 = x3 + 1
327 }
328 y3 = y3 + 1
329 }
330 return 0
331}
332
333func main(argc: i64, argv: *i64) -> i64 {
334 let meshp: *u8 = argv[1] as *u8
335 let mode: *u8 = argv[2] as *u8
336 // argv[7]=="nmap" -> emit a NORMAL MAP instead of a shaded image (mechanistic shape-judge input)
337 var nmap: i64 = 0
338 if argc > 7 { let np7: *u8 = argv[7] as *u8; if np7[0] == (110 as u8) { nmap = 1 } }
339 // argv[8] = yaw degrees about the vertical axis (multi-view judge)
340 var yawd: i64 = 0
341 if argc > 8 { yawd = as_satoi(argv[8] as *u8) }
342 // argv[9]=="fit" -> height-only framing (fair, scale-normalised comparison for the judges)
343 var fith: i64 = 0
344 if argc > 9 { let f9: *u8 = argv[9] as *u8; if f9[0] == (102 as u8) { fith = 1 } }
345 let sinT: *i64 = sys_mmap(400*8) as *i64
346 as_sin_fill(sinT)
347 let ysin: i64 = sinT[as_wrap(yawd)]
348 let ycos: i64 = sinT[as_wrap(yawd+90)]
349 let eye: *u8 = argv[3] as *u8
350 let W: i64 = as_satoi(argv[4] as *u8)
351 let H: i64 = as_satoi(argv[5] as *u8)
352 let outp: *u8 = argv[6] as *u8
353
354 let lenp: *i64 = sys_mmap(16) as *i64
355 let mb: *u8 = sys_read_file(meshp, lenp)
356 if (mb as i64) == 0 { as_hw("{\x22error\x22:\x22cannot read mesh\x22}\n" as *u8); return 2 }
357 // header
358 let nlayers: i64 = as_rdbits(mb, 8)
359 let ntris: i64 = as_rdbits(mb, 12)
360 // layer table: name16 off4 cnt4 ; tris base after it
361 let triBase: i64 = 16 + nlayers*24
362 let lidBase: i64 = triBase + ntris*84
363 // per-layer visibility + explode offset (x)
364 let vis: *i64 = sys_mmap(nlayers*8) as *i64
365 let loffx: *i64 = sys_mmap(nlayers*8) as *i64
366 var L0: i64 = 0
367 while L0 < nlayers { vis[L0] = 1; loffx[L0] = 0; L0 = L0 + 1 }
368 var only: i64 = 0 - 1
369 if as_streq(mode, "skin" as *u8) == 1 { only = 0 }
370 if mode[0] == (108 as u8) { if mode[1] == (97 as u8) { only = as_satoi((mode as i64 + 5) as *u8) } } // "layerN"
371 if only >= 0 { var i: i64 = 0; while i < nlayers { vis[i] = 0; i = i + 1 } vis[only] = 1 }
372
373 // ★seq630 pass 0: MEASURE the mesh at a fixed high precision, then choose the working precision so the
374 // model always spans ~AS_TARGET integer units. A metre-scale mesh and a millimetre-scale mesh then get
375 // the SAME effective resolution -- scale-invariant by construction instead of assuming millimetres.
376 var q0mn: i64 = AS_MAGIC_2000000000
377 var q0mx: i64 = 0-AS_MAGIC_2000000000
378 var t0: i64 = 0
379 while t0 < ntris {
380 let o0: i64 = triBase + t0*84
381 var c0: i64 = 0
382 while c0 < 3 {
383 let vq: i64 = as_f32mul(mb, o0 + c0*4, AS_POSQ0)
384 if vq < q0mn { q0mn = vq }
385 if vq > q0mx { q0mx = vq }
386 c0 = c0 + 1
387 }
388 t0 = t0 + 1
389 }
390 var span0: i64 = q0mx - q0mn
391 if span0 < 1 { span0 = 1 }
392 var posq: i64 = AS_POSQ0 * AS_TARGET / span0
393 if posq < 1 { posq = 1 }
394
395 // pass 1: full AABB over all verts -> centroid + radius
396 var mnx: i64 = AS_MAGIC_2000000000; var mny: i64 = AS_MAGIC_2000000000; var mnz: i64 = AS_MAGIC_2000000000
397 var mxx: i64 = 0-AS_MAGIC_2000000000; var mxy: i64 = 0-AS_MAGIC_2000000000; var mxz: i64 = 0-AS_MAGIC_2000000000
398 var t: i64 = 0
399 while t < ntris {
400 var v: i64 = 0
401 while v < 3 {
402 let o: i64 = triBase + t*84 + v*12
403 let x: i64 = as_f32mul(mb, o, posq); let y: i64 = as_f32mul(mb, o+4, posq); let z: i64 = as_f32mul(mb, o+8, posq)
404 if x < mnx { mnx = x } if x > mxx { mxx = x }
405 if y < mny { mny = y } if y > mxy { mxy = y }
406 if z < mnz { mnz = z } if z > mxz { mxz = z }
407 v = v + 1
408 }
409 t = t + 1
410 }
411 let cx0: i64 = (mnx+mxx)/2; let cy0: i64 = (mny+mxy)/2; let cz0: i64 = (mnz+mxz)/2
412 var rad: i64 = (mxx-mnx)/2
413 if (mxy-mny)/2 > rad { rad = (mxy-mny)/2 }
414 if (mxz-mnz)/2 > rad { rad = (mxz-mnz)/2 }
415 if rad < 1 { rad = 1 } // seq630: a degenerate mesh must never reach a divisor
416 // explode offsets (fan along X), step 0.62*rad, centered
417 if as_streq(mode, "explode" as *u8) == 1 {
418 let step: i64 = (rad*62)/100
419 var i: i64 = 0
420 while i < nlayers { loffx[i] = (i*2 - (nlayers-1)) * step / 2; i = i + 1 }
421 }
422
423 // pass 2: visible AABB (centered + offset) -> framing
424 var vmnx: i64 = AS_MAGIC_2000000000; var vmny: i64 = AS_MAGIC_2000000000; var vmnz: i64 = AS_MAGIC_2000000000
425 var vmxx: i64 = 0-AS_MAGIC_2000000000; var vmxy: i64 = 0-AS_MAGIC_2000000000; var vmxz: i64 = 0-AS_MAGIC_2000000000
426 t = 0
427 while t < ntris {
428 let L: i64 = as_rdbits(mb, lidBase + t*4) & 255
429 if vis[L] == 1 {
430 var v: i64 = 0
431 while v < 3 {
432 let o: i64 = triBase + t*84 + v*12
433 let x: i64 = as_f32mul(mb,o,posq) - cx0 + loffx[L]
434 let y: i64 = as_f32mul(mb,o+4,posq) - cy0
435 let z: i64 = as_f32mul(mb,o+8,posq) - cz0
436 if x < vmnx { vmnx = x } if x > vmxx { vmxx = x }
437 if y < vmny { vmny = y } if y > vmxy { vmxy = y }
438 if z < vmnz { vmnz = z } if z > vmxz { vmxz = z }
439 v = v + 1
440 }
441 }
442 t = t + 1
443 }
444 let halfW: i64 = (vmxx-vmnx)/2; let halfH: i64 = (vmxy-vmny)/2
445 let vcx: i64 = (vmnx+vmxx)/2; let vcy: i64 = (vmny+vmxy)/2
446 let FOCAL: i64 = H // tan(halffov_v)=0.5
447 var dist: i64 = 2*halfH
448 let dw: i64 = 2*halfW*H/W
449 if dw > dist { dist = dw }
450 dist = dist*118/100 + (vmxz-vmnz)/2
451 // ★FAIR-RULER FIX: auto-framing that depends on WIDTH or DEPTH silently rescales the render, so a change
452 // to body thickness moved the camera and shrank the figure -- the front silhouette score fell 834->624 from
453 // a depth edit that cannot affect a front outline. That was the RULER moving, not the shape. 'fit' frames
454 // on HEIGHT ALONE, so two meshes of the same stature render at the same scale and IoU measures shape only.
455 if fith == 1 { dist = 2*halfH*118/100 }
456 if dist < 1 { dist = 1 } // seq630: never divide by a degenerate framing distance
457 // off-axis (parallel) stereo eye offset in X
458 var ex: i64 = 0
459 if eye[0] == (76 as u8) { ex = 0 - (dist*32)/1000 } // 'L'
460 if eye[0] == (82 as u8) { ex = (dist*32)/1000 } // 'R'
461
462 // framebuffers
463 let npx: i64 = W*H
464 let fb: *i64 = sys_mmap(npx*8) as *i64
465 let zb: *i64 = sys_mmap(npx*8) as *i64
466 let lb: *i64 = sys_mmap(npx*8) as *i64
467 var p: i64 = 0
468 while p < npx {
469 let py: i64 = p / W
470 let px1: i64 = p % W
471 // smooth full-precision vertical gradient (the old 10-level g caused visible BANDING -- eyeball-found)
472 // + subtle backdrop grain (paper-texture scale, +-4 levels; coherent value noise, not white noise)
473 let bgt: i64 = tx_vnoise(px1*4, py*4, 17, 24) / 32 - 4
474 var br: i64 = 34 + (56*(H-py))/H + bgt
475 var bgc: i64 = 41 + (69*(H-py))/H + bgt
476 var bbl: i64 = 56 + (94*(H-py))/H + bgt
477 if br<0 {br=0} if bgc<0 {bgc=0} if bbl<0 {bbl=0}
478 fb[p] = br + bgc*256 + bbl*AS_MAGIC_65536
479 zb[p] = AS_ZFAR; lb[p] = 0 - 1; p = p + 1
480 }
481
482 // lights (Q14 unit)
483 let l1x: i64 = 0-AS_MAGIC_5423; let l1y: i64 = AS_MAGIC_9487; let l1z: i64 = AS_MAGIC_12206
484 let l2x: i64 = AS_MAGIC_10160; let l2y: i64 = 0-AS_MAGIC_4064; let l2z: i64 = AS_MAGIC_12190
485 let cxh: i64 = W/2; let cyh: i64 = H/2
486 // half-vector for specular (headlight view (0,0,1)), computed ONCE
487 var hx: i64 = l1x; var hy: i64 = l1y; var hz: i64 = l1z + AS_Q14
488 let hl: i64 = as_isqrt(hx*hx + hy*hy + hz*hz)
489 hx = hx*AS_Q14/hl; hy = hy*AS_Q14/hl; hz = hz*AS_Q14/hl
490
491 // ---- GX-15 rung A: GROUND PLANE + PROJECTED CONTACT SHADOW (the floating-figure fix) ----
492 // Real geometry-derived shadow: every visible triangle is projected along light L1 onto the floor
493 // plane y=floorY and splatted into a floor-space mask; floor pixels darken where masked.
494 let floorY: i64 = vmny
495 let smN: i64 = 192
496 var smE: i64 = rad*3
497 if smE < 1 { smE = 1 } // seq630: fail-safe -- the shadow grid divides by 2*smE
498 let sm: *i64 = sys_mmap(smN*smN*8) as *i64
499 let qgx: *i64 = sys_mmap(64) as *i64
500 let qgz: *i64 = sys_mmap(64) as *i64
501 let qgy: *i64 = sys_mmap(64) as *i64
502 t = 0
503 while t < ntris {
504 let L: i64 = as_rdbits(mb, lidBase + t*4) & 255
505 if vis[L] == 1 {
506 let ob: i64 = triBase + t*84
507 var v: i64 = 0
508 while v < 3 {
509 let o: i64 = ob + v*12
510 let px3: i64 = as_f32mul(mb,o,posq) - cx0 + loffx[L]
511 let py3: i64 = as_f32mul(mb,o+4,posq) - cy0
512 let pz3: i64 = as_f32mul(mb,o+8,posq) - cz0
513 let sx3: i64 = px3 - (py3 - floorY)*l1x/l1y
514 let sz3: i64 = pz3 - (py3 - floorY)*l1z/l1y
515 qgx[v] = (sx3 + smE)*smN/(2*smE)
516 qgz[v] = (sz3 + smE)*smN/(2*smE)
517 qgy[v] = py3 - floorY
518 v = v + 1
519 }
520 var a2: i64 = (qgx[1]-qgx[0])*(qgz[2]-qgz[0]) - (qgx[2]-qgx[0])*(qgz[1]-qgz[0])
521 var sg2: i64 = 1
522 if a2 < 0 { sg2 = 0 - 1 }
523 if a2 != 0 {
524 var gxmn: i64 = as_max(0, as_min(qgx[0], as_min(qgx[1], qgx[2])))
525 var gxmx: i64 = as_min(smN-1, as_max(qgx[0], as_max(qgx[1], qgx[2])))
526 var gzmn: i64 = as_max(0, as_min(qgz[0], as_min(qgz[1], qgz[2])))
527 var gzmx: i64 = as_min(smN-1, as_max(qgz[0], as_max(qgz[1], qgz[2])))
528 var gz: i64 = gzmn
529 while gz <= gzmx {
530 var gx: i64 = gxmn
531 while gx <= gxmx {
532 let f0: i64 = ((qgx[2]-qgx[1])*(gz-qgz[1]) - (qgz[2]-qgz[1])*(gx-qgx[1]))*sg2
533 let f1: i64 = ((qgx[0]-qgx[2])*(gz-qgz[2]) - (qgz[0]-qgz[2])*(gx-qgx[2]))*sg2
534 let f2: i64 = ((qgx[1]-qgx[0])*(gz-qgz[0]) - (qgz[1]-qgz[0])*(gx-qgx[0]))*sg2
535 if f0 >= 0 { if f1 >= 0 { if f2 >= 0 {
536 // GX-39 piece 3: store MAX OCCLUDER HEIGHT per cell (was a 1-bit mask) so
537 // the penumbra can grow with height like a real area light
538 var hrel: i64 = qgy[0]
539 if qgy[1] > hrel { hrel = qgy[1] }
540 if qgy[2] > hrel { hrel = qgy[2] }
541 if hrel < 1 { hrel = 1 }
542 if hrel > sm[gz*smN+gx] { sm[gz*smN+gx] = hrel }
543 }}}
544 gx = gx + 1
545 }
546 gz = gz + 1
547 }
548 }
549 }
550 t = t + 1
551 }
552 // ---- GX-39 piece 3: SOFT AREA SHADOW fields ----
553 // sm now stores MAX OCCLUDER HEIGHT per cell (0 = unshadowed). Two separable integer box blurs of
554 // the coverage build a SHARP field (kills grid-cell blockiness only) and a WIDE field (the
555 // penumbra); each floor pixel blends between them by the LOCAL occluder height -- feet stay crisply
556 // planted while the head's shadow feathers wide, the real area-light signature. nmap renders keep
557 // the legacy hard 4-tap lookup so the mechanistic shape-judge input stays bit-stable.
558 let smc: i64 = smN*smN
559 let cov: *i64 = sys_mmap(smc*8) as *i64
560 let bt1: *i64 = sys_mmap(smc*8) as *i64
561 let bs1: *i64 = sys_mmap(smc*8) as *i64
562 let bs2: *i64 = sys_mmap(smc*8) as *i64
563 var ci: i64 = 0
564 while ci < smc { if sm[ci] > 0 { cov[ci] = AS_MAGIC_1024 } ci = ci + 1 }
565 as_boxblur(cov, bt1, bs1, smN, 1)
566 as_boxblur(cov, bt1, bs2, smN, 4)
567
568 // analytic floor pass: per-pixel ray/plane, textured, shadow-masked, distance-faded to bg
569 var fp: i64 = 0
570 while fp < npx {
571 let py2: i64 = fp / W
572 let px2: i64 = fp % W
573 let rdy: i64 = cyh - py2
574 if rdy < 0 {
575 let t16: i64 = floorY*AS_MAGIC_65536/rdy
576 let wx: i64 = ex + t16*(px2-cxh)/AS_MAGIC_65536
577 let wz: i64 = dist + t16*(0-FOCAL)/AS_MAGIC_65536
578 if wx > 0-smE { if wx < smE { if wz > 0-smE { if wz < smE {
579 let depth: i64 = dist - wz
580 if depth > 0 {
581 let tv: i64 = tx_fbm(wx/posq, floorY/posq, wz/posq)
582 let f: i64 = 928 + tv/2
583 var fr: i64 = 118*f/AS_MAGIC_1024; var fg: i64 = 110*f/AS_MAGIC_1024; var fbv: i64 = 101*f/AS_MAGIC_1024
584 let gx: i64 = (wx + smE)*smN/(2*smE)
585 let gz: i64 = (wz + smE)*smN/(2*smE)
586 var dk: i64 = AS_MAGIC_1024
587 if nmap == 0 {
588 // soft area shadow: blend sharp->wide by local occluder height (3x3 max so the
589 // penumbra field has no holes), then darken by the blended coverage
590 var hL: i64 = 0
591 var dz5: i64 = 0 - 1
592 while dz5 <= 1 {
593 var dx5: i64 = 0 - 1
594 while dx5 <= 1 {
595 let gx5: i64 = gx + dx5
596 let gz5: i64 = gz + dz5
597 if gx5 >= 0 { if gx5 < smN { if gz5 >= 0 { if gz5 < smN {
598 if sm[gz5*smN+gx5] > hL { hL = sm[gz5*smN+gx5] }
599 }}}}
600 dx5 = dx5 + 1
601 }
602 dz5 = dz5 + 1
603 }
604 // a shadow cast from a third of stature up is fully soft (height-derived, not taste)
605 var hpen: i64 = (vmxy - vmny)/3
606 if hpen < 1 { hpen = 1 }
607 var wgt: i64 = hL*AS_MAGIC_1024/hpen
608 if wgt > AS_MAGIC_1024 { wgt = AS_MAGIC_1024 }
609 let sv: i64 = (bs1[gz*smN+gx]*(AS_MAGIC_1024-wgt) + bs2[gz*smN+gx]*wgt)/AS_MAGIC_1024
610 dk = AS_MAGIC_1024 - sv*44/100
611 } else {
612 // legacy hard 4-tap, bit-stable for the shape-judge floor (sm holds heights now,
613 // so count occupied cells rather than summing raw values)
614 var sh: i64 = 0
615 if sm[gz*smN+gx] > 0 { sh = sh + 1 }
616 if gx+1 < smN { if sm[gz*smN+gx+1] > 0 { sh = sh + 1 } }
617 if gz+1 < smN { if sm[(gz+1)*smN+gx] > 0 { sh = sh + 1 } }
618 if gx > 0 { if sm[gz*smN+gx-1] > 0 { sh = sh + 1 } }
619 dk = AS_MAGIC_1024 - sh*110
620 }
621 fr = fr*dk/AS_MAGIC_1024; fg = fg*dk/AS_MAGIC_1024; fbv = fbv*dk/AS_MAGIC_1024
622 // distance fade toward the backdrop colour
623 let dxtra: i64 = t16/AS_MAGIC_65536
624 let ff: i64 = smE*AS_MAGIC_1024/(smE + dxtra*3)
625 let obr: i64 = 34 + (56*(H-py2))/H
626 let obg: i64 = 41 + (69*(H-py2))/H
627 let obb: i64 = 56 + (94*(H-py2))/H
628 fr = (fr*ff + obr*(AS_MAGIC_1024-ff))/AS_MAGIC_1024
629 fg = (fg*ff + obg*(AS_MAGIC_1024-ff))/AS_MAGIC_1024
630 fbv = (fbv*ff + obb*(AS_MAGIC_1024-ff))/AS_MAGIC_1024
631 if fr>255 {fr=255} if fg>255 {fg=255} if fbv>255 {fbv=255}
632 fb[fp] = fr + fg*256 + fbv*AS_MAGIC_65536
633 zb[fp] = depth
634 }
635 }}}}
636 }
637 fp = fp + 1
638 }
639
640 // pass 3: rasterize
641 t = 0
642 while t < ntris {
643 let L: i64 = as_rdbits(mb, lidBase + t*4) & 255
644 if vis[L] == 1 {
645 let ob: i64 = triBase + t*84
646 // 3 verts: centered pos + offset ; normal Q14 ; color 0..255 (per-vertex, we use v0's colour = flat)
647 let rx0v: i64 = as_f32mul(mb,ob,posq) - cx0 + loffx[L]; let y0: i64 = as_f32mul(mb,ob+4,posq) - cy0; let rz0v: i64 = as_f32mul(mb,ob+8,posq) - cz0
648 let rx1v: i64 = as_f32mul(mb,ob+12,posq)- cx0 + loffx[L]; let y1: i64 = as_f32mul(mb,ob+16,posq)- cy0; let rz1v: i64 = as_f32mul(mb,ob+20,posq)- cz0
649 let rx2v: i64 = as_f32mul(mb,ob+24,posq)- cx0 + loffx[L]; let y2: i64 = as_f32mul(mb,ob+28,posq)- cy0; let rz2v: i64 = as_f32mul(mb,ob+32,posq)- cz0
650 // multi-view: yaw about the vertical axis so the judge can inspect the depth axis a front view hides
651 let x0: i64 = (rx0v*ycos + rz0v*ysin)/AS_Q14; let z0: i64 = (rz0v*ycos - rx0v*ysin)/AS_Q14
652 let x1: i64 = (rx1v*ycos + rz1v*ysin)/AS_Q14; let z1: i64 = (rz1v*ycos - rx1v*ysin)/AS_Q14
653 let x2: i64 = (rx2v*ycos + rz2v*ysin)/AS_Q14; let z2: i64 = (rz2v*ycos - rx2v*ysin)/AS_Q14
654 // depths from camera (looking -z, camera at +z=dist)
655 let d0: i64 = dist - z0; let d1: i64 = dist - z1; let d2: i64 = dist - z2
656 if d0 > 0 { if d1 > 0 { if d2 > 0 {
657 // project (off-axis stereo)
658 let conv: i64 = ex*FOCAL/dist
659 let sx0: i64 = cxh + ((x0-ex)*FOCAL)/d0 + conv; let sy0: i64 = cyh - (y0*FOCAL)/d0
660 let sx1: i64 = cxh + ((x1-ex)*FOCAL)/d1 + conv; let sy1: i64 = cyh - (y1*FOCAL)/d1
661 let sx2: i64 = cxh + ((x2-ex)*FOCAL)/d2 + conv; let sy2: i64 = cyh - (y2*FOCAL)/d2
662 var area: i64 = (sx1-sx0)*(sy2-sy0) - (sx2-sx0)*(sy1-sy0)
663 if area != 0 {
664 // GX-15 rung B: per-VERTEX normals decoded once per tri, interpolated per PIXEL (kills faceting)
665 let q0x: i64 = as_f32mul(mb,ob+36,AS_Q14); let n0y: i64 = as_f32mul(mb,ob+40,AS_Q14); let q0z: i64 = as_f32mul(mb,ob+44,AS_Q14)
666 let q1x: i64 = as_f32mul(mb,ob+48,AS_Q14); let n1y: i64 = as_f32mul(mb,ob+52,AS_Q14); let q1z: i64 = as_f32mul(mb,ob+56,AS_Q14)
667 let q2x: i64 = as_f32mul(mb,ob+60,AS_Q14); let n2y: i64 = as_f32mul(mb,ob+64,AS_Q14); let q2z: i64 = as_f32mul(mb,ob+68,AS_Q14)
668 // normals must yaw with the geometry, or lighting/normal-maps detach from the surface
669 let n0x: i64 = (q0x*ycos + q0z*ysin)/AS_Q14; let n0z: i64 = (q0z*ycos - q0x*ysin)/AS_Q14
670 let n1x: i64 = (q1x*ycos + q1z*ysin)/AS_Q14; let n1z: i64 = (q1z*ycos - q1x*ysin)/AS_Q14
671 let n2x: i64 = (q2x*ycos + q2z*ysin)/AS_Q14; let n2z: i64 = (q2z*ycos - q2x*ysin)/AS_Q14
672 let cr: i64 = as_f32mul(mb,ob+72,255); let cg: i64 = as_f32mul(mb,ob+76,255); let cbb: i64 = as_f32mul(mb,ob+80,255)
673 // bbox
674 var bxmn: i64 = as_max(0, as_min(sx0, as_min(sx1,sx2)))
675 var bxmx: i64 = as_min(W-1, as_max(sx0, as_max(sx1,sx2)))
676 var bymn: i64 = as_max(0, as_min(sy0, as_min(sy1,sy2)))
677 var bymx: i64 = as_min(H-1, as_max(sy0, as_max(sy1,sy2)))
678 var sgn: i64 = 1
679 if area < 0 { sgn = 0 - 1 }
680 let aabs: i64 = area*sgn
681 var py2: i64 = bymn
682 while py2 <= bymx {
683 var px2: i64 = bxmn
684 while px2 <= bxmx {
685 let e0: i64 = ((sx2-sx1)*(py2-sy1) - (sy2-sy1)*(px2-sx1))*sgn
686 let e1: i64 = ((sx0-sx2)*(py2-sy2) - (sy0-sy2)*(px2-sx2))*sgn
687 let e2: i64 = ((sx1-sx0)*(py2-sy0) - (sy1-sy0)*(px2-sx0))*sgn
688 if e0 >= 0 { if e1 >= 0 { if e2 >= 0 {
689 let depth: i64 = (e0*d0 + e1*d1 + e2*d2)/aabs
690 let idx: i64 = py2*W + px2
691 if depth < zb[idx] {
692 // per-pixel WORLD position -> multi-octave texture (GX-13)
693 let wx: i64 = (e0*x0 + e1*x1 + e2*x2)/aabs
694 let wy: i64 = (e0*y0 + e1*y1 + e2*y2)/aabs
695 let wz: i64 = (e0*z0 + e1*z1 + e2*z2)/aabs
696 let tv: i64 = tx_fbm(wx/posq, wy/posq, wz/posq)
697 let f: i64 = 896 + tv
698 // GX-15 rung B: smooth interpolated normal per pixel
699 var nx: i64 = (e0*n0x + e1*n1x + e2*n2x)/aabs
700 var ny: i64 = (e0*n0y + e1*n1y + e2*n2y)/aabs
701 var nz: i64 = (e0*n0z + e1*n1z + e2*n2z)/aabs
702 var nl: i64 = as_isqrt(nx*nx + ny*ny + nz*nz)
703 if nl < 1 { nl = 1 }
704 nx = nx*AS_Q14/nl; ny = ny*AS_Q14/nl; nz = nz*AS_Q14/nl
705 if nz < 0 { nx = 0-nx; ny = 0-ny; nz = 0-nz }
706 // ★SKIN MICRO-BUMP: perturb the shading normal by a high-frequency noise
707 // gradient over world position -- pore/wrinkle-scale relief that catches
708 // light, so skin stops reading as smooth plastic. Renderer-only (the mesh
709 // and the bench are untouched); two octaves for skin, coarser everywhere.
710 if L == 0 {
711 let mx: i64 = wx/posq; let my: i64 = wy/posq; let mz: i64 = wz/posq
712 let gx1: i64 = tx_vnoise(mx+1,my,mz,3) - tx_vnoise(mx-1,my,mz,3)
713 let gy1: i64 = tx_vnoise(mx,my+1,mz,3) - tx_vnoise(mx,my-1,mz,3)
714 let gx2: i64 = tx_vnoise(mx+2,my,mz,7) - tx_vnoise(mx-2,my,mz,7)
715 let gy2: i64 = tx_vnoise(mx,my+2,mz,7) - tx_vnoise(mx,my-2,mz,7)
716 nx = nx + (gx1*16 + gx2*10)/10 // fine micro-relief only -- subtle, not mottled
717 ny = ny + (gy1*16 + gy2*10)/10
718 var nl2: i64 = as_isqrt(nx*nx + ny*ny + nz*nz)
719 if nl2 < 1 { nl2 = 1 }
720 nx = nx*AS_Q14/nl2; ny = ny*AS_Q14/nl2; nz = nz*AS_Q14/nl2
721 }
722 let dot1: i64 = (nx*l1x + ny*l1y + nz*l1z)/AS_Q14
723 var d1l: i64 = as_max(0, dot1)
724 // GX-15 rung C: SKIN responds like flesh -- wrap diffuse (SSS signature, proven Gx rung)
725 if L == 0 {
726 d1l = (dot1 + 4*AS_Q14/10)*717/AS_MAGIC_1024
727 if d1l < 0 { d1l = 0 }
728 }
729 let d2l: i64 = as_max(0, (nx*l2x + ny*l2y + nz*l2z)/AS_Q14)
730 // ★ENVIRONMENT AMBIENT (GX-38). The ambient term was the CONSTANT 225 --
731 // every surface got the same fill regardless of which way it faced, which
732 // is the single strongest reason these renders read as CG on a backdrop.
733 // Real ambient is a hemisphere: a surface facing up sees sky, one facing
734 // down sees only the dim bounce off the ground. This is the cosine-weighted
735 // sky-visibility term of an environment light, integer and sovereign --
736 // shading only, so it cannot move the geometric bench by construction.
737 let skyw: i64 = (AS_Q14 + ny)/2
738 let ambi: i64 = 96 + 258*skyw/AS_Q14
739 var lit: i64 = ambi + 676*d1l/AS_Q14 + 256*d2l/AS_Q14
740 // soft FRONT FILL for skin: camera-facing surfaces get a gentle lift so
741 // downward/shadowed features (the mouth, under-chin) don't crush to black.
742 if L == 0 { lit = lit + 210*nz/AS_Q14 }
743 if lit > AS_MAGIC_1280 { lit = AS_MAGIC_1280 }
744 var r2: i64 = cr*lit*f/(AS_MAGIC_1024*AS_MAGIC_1024)
745 var g2: i64 = cg*lit*f/(AS_MAGIC_1024*AS_MAGIC_1024)
746 var b2: i64 = cbb*lit*f/(AS_MAGIC_1024*AS_MAGIC_1024)
747 // PER-CHANNEL ENVIRONMENT (GX-39). The hemisphere above is a SCALAR, so it
748 // brightens up-facing surfaces but cannot carry what actually reads as real
749 // light: sky is COOL and ground bounce is WARM, so a real body is subtly blue
750 // toward the top and orange underneath. Applied as a fraction of the surface
751 // colour itself, so it is scale-free and tints rather than washes out.
752 // Shading only, so the geometric bench must not move.
753 let gndw: i64 = AS_Q14 - skyw
754 let warm: i64 = (gndw*90 - skyw*25)/AS_Q14
755 let cool: i64 = (skyw*95 - gndw*30)/AS_Q14
756 r2 = r2 + r2*warm/1000
757 g2 = g2 + g2*(warm/3 + cool/4)/1000
758 b2 = b2 + b2*cool/1000
759 // ★SUBSURFACE SCATTERING (skin=layer0): light scatters INSIDE flesh and red
760 // penetrates deepest, so the terminator and the shadowed side glow warm/red
761 // instead of going dead-grey -- the single biggest "skin not clay" signature.
762 // sss rises smoothly as the surface turns away from the key light.
763 if L == 0 {
764 var sss: i64 = AS_Q14*55/100 - dot1
765 if sss < 0 { sss = 0 }
766 if sss > AS_Q14 { sss = AS_Q14 }
767 r2 = r2 + cr*sss*46/(AS_Q14*100) // red bleed (deepest) -- strong
768 g2 = g2 + cg*sss*14/(AS_Q14*100) // a little green
769 b2 = b2 - cbb*sss*10/(AS_Q14*100) // pull blue -> warmer shadows
770 // ★real skin is EVEN, not blotchy: only a whisper of fine grain (the coarse
771 // blotch variation read as diseased mottling at body scale = a regression, removed)
772 let cf: i64 = tx_vnoise(wx*3/posq, wy*3/posq, wz*3/posq, 5)
773 r2 = r2 + (cf-128)*4/255
774 g2 = g2 + (cf-128)*2/255
775 // ★SUBCUTANEOUS VEINS shown THROUGH skin translucency (blue-green: flesh
776 // absorbs red). A domain-warped LEVEL-SET = branching wavy lines, gated by
777 // a low-freq THIN-SKIN mask so veins only surface in patches (forearms/
778 // chest/hands), not everywhere. Inside-out -- real vasculature under the
779 // skin, which Infinigen's single-surface creatures cannot show.
780 let vmx: i64 = wx/posq; let vmy: i64 = wy/posq; let vmz: i64 = wz/posq
781 // coarse + x-COMPRESSED (vein LINES run lengthwise along the limb/torso) +
782 // strong domain warp so the contour meanders -> long thin veins, not speckle
783 let warp: i64 = (tx_vnoise(vmx, vmy, vmz, 26) - 128)*3
784 let vf: i64 = tx_vnoise(vmx*3 + warp, vmy + warp/3, vmz, 40)
785 var ridge: i64 = vf - 128; if ridge < 0 { ridge = 0-ridge }
786 let thin: i64 = tx_vnoise(vmx, vmy, vmz, 80)
787 if ridge < 10 { if thin > 140 {
788 let vein: i64 = (10 - ridge)*(thin - 140)/10
789 r2 = r2 - vein*20/100
790 g2 = g2 - vein*4/100
791 b2 = b2 + vein*15/100
792 }}
793 }
794 // subtle Blinn specular sheen (half-vector precomputed)
795 let ndh: i64 = as_max(0, (nx*hx + ny*hy + nz*hz)/AS_Q14)
796 let s2s: i64 = ndh*ndh/AS_Q14
797 let s4s: i64 = s2s*s2s/AS_Q14
798 let s8s: i64 = s4s*s4s/AS_Q14
799 var spq: i64 = s8s*52/AS_Q14
800 if L == 0 { spq = s8s*80/AS_Q14 }
801 r2 = r2 + spq; g2 = g2 + spq; b2 = b2 + spq
802 if r2>255 {r2=255} if g2>255 {g2=255} if b2>255 {b2=255}
803 if r2<0 {r2=0} if g2<0 {g2=0} if b2<0 {b2=0}
804 // ★MECHANISTIC SHAPE JUDGE (no VLM): 'nmap' writes the surface NORMAL as
805 // colour instead of shading it. Silhouette IoU is provably blind to depth
806 // and to surface shape -- two bodies with identical outlines can have
807 // completely different surfaces. Comparing normal FIELDS measures the shape
808 // itself, mechanically, with no learned model anywhere in the loop.
809 if nmap == 1 {
810 r2 = (nx + AS_Q14)*255/(2*AS_Q14)
811 g2 = (ny + AS_Q14)*255/(2*AS_Q14)
812 b2 = (nz + AS_Q14)*255/(2*AS_Q14)
813 }
814 zb[idx] = depth; fb[idx] = r2 + g2*256 + b2*AS_MAGIC_65536; lb[idx] = L
815 }
816 }}}
817 px2 = px2 + 1
818 }
819 py2 = py2 + 1
820 }
821 }
822 }}}
823 }
824 t = t + 1
825 }
826
827 // GX-39 piece 2: contact-darkening AO post-pass -- shaded path ONLY (the nmap shape-judge input
828 // must stay pure geometry, which is also why the geometric bench cannot move)
829 if nmap == 0 { as_ssao(fb, zb, lb, W, H) }
830 // GX-39 piece 4: depth of field -- photographic focus on the body; floor/backdrop blur by distance
831 if nmap == 0 { as_dof(fb, zb, lb, W, H) }
832
833 write_png(fb, W, H, outp)
834
835 // stats
836 let lpx: *i64 = sys_mmap(nlayers*8) as *i64
837 var i2: i64 = 0
838 while i2 < nlayers { lpx[i2] = 0; i2 = i2 + 1 }
839 var bg: i64 = 0; var fg: i64 = 0; var cxs: i64 = 0
840 var dmn: i64 = AS_ZFAR; var dmx: i64 = 0; var dsm: i64 = 0
841 var q: i64 = 0
842 while q < npx {
843 let L: i64 = lb[q]
844 if L < 0 { bg = bg + 1 } else {
845 lpx[L] = lpx[L] + 1; fg = fg + 1; cxs = cxs + (q % W)
846 let d: i64 = zb[q]
847 if d < dmn { dmn = d } if d > dmx { dmx = d } dsm = dsm + d
848 }
849 q = q + 1
850 }
851 var cxv: i64 = 0 - 1; var dmean: i64 = 0 - 1
852 if fg > 0 { cxv = cxs/fg; dmean = dsm/fg }
853 as_hw("{\x22impl\x22:\x22sovereign-nishilang-integer\x22,\x22mode\x22:\x22" as *u8); as_hw(mode)
854 as_hw("\x22,\x22eye\x22:\x22" as *u8); as_hw(eye)
855 as_hw("\x22,\x22W\x22:" as *u8); as_pn(W); as_hw(",\x22H\x22:" as *u8); as_pn(H)
856 as_hw(",\x22ntris\x22:" as *u8); as_pn(ntris)
857 as_hw(",\x22bg_frac_permil\x22:" as *u8); as_pn(bg*1000/npx)
858 as_hw(",\x22fg_pix\x22:" as *u8); as_pn(fg)
859 as_hw(",\x22centroid_x\x22:" as *u8); as_pn(cxv)
860 as_hw(",\x22depth_min\x22:" as *u8); as_pn(dmn); as_hw(",\x22depth_mean\x22:" as *u8); as_pn(dmean); as_hw(",\x22depth_max\x22:" as *u8); as_pn(dmx)
861 as_hw(",\x22layer_pix\x22:[" as *u8)
862 var k: i64 = 0
863 while k < nlayers { if k > 0 { as_hw("," as *u8) } as_pn(lpx[k]); k = k + 1 }
864 as_hw("]}\n" as *u8)
865 return 0
866}