code wiki / _hdl_build / nx_faceanat_texbake_gate.nx
nx_faceanat_texbake_gate.nx source
↩ module page · 161 lines · 8171 B
1// nx_faceanat_texbake_gate.nx -- ★B-R7 TEXTURE BAKE (operator: toward photoreal VR). Bake the A-R2 reference
2// photo onto our OWN emitted base mesh as per-vertex COLOR_0 -> a photo-textured, VR/VRM-loadable head with NO
3// UV unwrap. Each mesh vertex samples the hi-res reference at its projected (u,v) IF front-facing (SDF-gradient
4// nz<0, same test as the shader) AND inside the mid-face band; back/side verts keep the procedural skin tone.
5// = the DAZ texture-stack idea (baked maps), sovereign, generated.
6// T1 the bake carries real photo texture: a healthy count of face verts got a projected (non-default) colour
7// T2 ★the baked colours MATCH the reference region (mean baked band-colour ~ mean reference face-skin) AND are
8// TEXTURED not flat (spread > a floor) -- real photo detail on the mesh, measured
9// T3 valid COLOURED glTF (magic 'glTF' + COLOR_0/normalized-ubyte accessor in the JSON) = VR-loadable
10// T4 watertight preserved (nv/nf unchanged vs the plain mesh) + determinism
11// license_tier: ORIGINAL expect_exit: 0
12import "nx_syscalls.nx"
13import "nx_jpeg_ascii.nx"
14import "nx_faceanat.nx"
15import "nx_meshgen.nx"
16import "nx_gltf_export.nx"
17
18func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
19func 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 }
20
21const P_UC: i64 = 256
22const P_VC: i64 = 329
23const P_SU: i64 = 333
24const P_SV: i64 = 350
25const P_VLO: i64 = 240
26const P_VHI: i64 = 440
27
28func main() -> i64 {
29 hw("=== nx_faceanat_texbake_gate -- bake the reference photo onto our base mesh (VR texture rung) ===\n" as *u8)
30 var fails: i64 = 0
31
32 let base: i64 = sys_mmap(sdf_bytes()) as i64
33 let F: *i64 = sys_mmap((MG_N + 1) * (MG_N + 1) * (MG_N + 1) * 8) as *i64
34 let cubevi: *i64 = sys_mmap(MG_N * MG_N * MG_N * 8) as *i64
35 let vbuf: *i64 = sys_mmap(MG_MAXV * 3 * 8) as *i64
36 let fbuf: *i64 = sys_mmap(MG_MAXF * 3 * 8) as *i64
37 let out: *i64 = sys_mmap(16) as *i64
38
39 faceanat_build(base)
40 mg_build(base, F, cubevi, vbuf, fbuf, out)
41 let nv: i64 = out[0]
42 let nf: i64 = out[1]
43 hw(" base mesh verts="); pn(nv); hw(" tris="); pn(nf); hw("\n" as *u8)
44
45 // decode the hi-res reference
46 let szp: *i64 = sys_mmap(16) as *i64
47 let jpeg: *u8 = sys_read_file("knowledge/elara_face_hi.jpg" as *u8, szp)
48 if (jpeg as i64) == 0 { hw("no reference jpg\n" as *u8); return 1 }
49 let rgbp: *i64 = sys_mmap(8) as *i64
50 let twp: *i64 = sys_mmap(8) as *i64
51 let thp: *i64 = sys_mmap(8) as *i64
52 if nx_jpeg_decode_rgb(jpeg, szp[0], rgbp, twp, thp) != NX_JPEG_ASCII_OK { hw("decode failed\n" as *u8); return 1 }
53 let rgb: *u8 = rgbp[0] as *u8
54 let tw: i64 = twp[0]
55 let th: i64 = thp[0]
56
57 // BAKE per-vertex colour
58 let cbuf: *i64 = sys_mmap(nv * 3 * 8) as *i64
59 var painted: i64 = 0
60 var sumR: i64 = 0
61 var sumG: i64 = 0
62 var sumB: i64 = 0
63 var sumR2: i64 = 0 // for spread
64 var vi: i64 = 0
65 while vi < nv {
66 let x: i64 = vbuf[vi*3]
67 let y: i64 = vbuf[vi*3+1]
68 let z: i64 = vbuf[vi*3+2]
69 // procedural skin default
70 var cr: i64 = 236
71 var cg: i64 = 180
72 var cb: i64 = 156
73 // front-facing test via SDF gradient z (same as the shader: surface normal points -z toward camera)
74 let e: i64 = 12
75 let gz: i64 = sdf_eval(base, x, y, z + e) - sdf_eval(base, x, y, z - e)
76 if gz < 0 - 2 {
77 let u: i64 = P_UC + x * P_SU / 1024
78 let v: i64 = P_VC - y * P_SV / 1024
79 if v >= P_VLO { if v < P_VHI { if u >= 1 { if u < tw - 1 { if v < th - 1 {
80 let o: i64 = (v * tw + u) * 3
81 cr = (rgb[o] as i64) & 255
82 cg = (rgb[o+1] as i64) & 255
83 cb = (rgb[o+2] as i64) & 255
84 painted = painted + 1
85 sumR = sumR + cr; sumG = sumG + cg; sumB = sumB + cb
86 sumR2 = sumR2 + cr * cr
87 } } } } }
88 }
89 cbuf[vi*3] = cr; cbuf[vi*3+1] = cg; cbuf[vi*3+2] = cb
90 vi = vi + 1
91 }
92 hw(" baked: "); pn(painted); hw(" verts carry reference photo colour (of "); pn(nv); hw(")\n" as *u8)
93
94 // T1 real texture coverage
95 var t1: i64 = 0
96 if painted > 200 { t1 = 1 }
97 if t1 == 1 { hw("T1 PASS the base mesh carries real photo texture (per-vertex reference colour)\n" as *u8) }
98 else { fails=fails+1; hw("T1 FAIL too few painted verts\n" as *u8) }
99
100 // T2 colours match the reference face region + are textured (spread), measured
101 var t2: i64 = 0
102 if painted > 0 {
103 let mR: i64 = sumR / painted
104 let mG: i64 = sumG / painted
105 let mB: i64 = sumB / painted
106 // reference face-skin mean (sample a 40x40 patch at the cheek, photo ~(150,350))
107 var rR: i64 = 0
108 var rG: i64 = 0
109 var rB: i64 = 0
110 var rn: i64 = 0
111 var py: i64 = 330
112 while py < 370 { var px: i64 = 130; while px < 170 { let o: i64 = (py*tw+px)*3; rR=rR+(rgb[o] as i64); rG=rG+(rgb[o+1] as i64); rB=rB+(rgb[o+2] as i64); rn=rn+1; px=px+1 } py=py+1 }
113 rR = rR / rn; rG = rG / rn; rB = rB / rn
114 // spread of baked red (variance proxy): E[r^2]-E[r]^2
115 let varR: i64 = sumR2 / painted - mR * mR
116 hw(" baked mean RGB=("); pn(mR); hw(","); pn(mG); hw(","); pn(mB); hw(") ref cheek RGB=("); pn(rR); hw(","); pn(rG); hw(","); pn(rB); hw(") red-var="); pn(varR); hw("\n" as *u8)
117 var dR: i64 = mR - rR; if dR < 0 { dR = 0 - dR }
118 var dG: i64 = mG - rG; if dG < 0 { dG = 0 - dG }
119 var dB: i64 = mB - rB; if dB < 0 { dB = 0 - dB }
120 if dR < 45 { if dG < 45 { if dB < 45 { if varR > 15 { t2 = 1 } } } } // matches skin + textured (not flat)
121 }
122 if t2 == 1 { hw("T2 PASS baked colours match the reference face skin AND are textured (real photo detail, not flat)\n" as *u8) }
123 else { fails=fails+1; hw("T2 FAIL colour match/spread\n" as *u8) }
124
125 // T3 valid coloured glTF
126 let glblen: i64 = write_glb_colored(vbuf, fbuf, cbuf, nv, nf, "knowledge/faceanat_tex.glb" as *u8)
127 hw(" wrote knowledge/faceanat_tex.glb ("); pn(glblen); hw(" bytes)\n" as *u8)
128 let rd: *i64 = sys_mmap(16) as *i64
129 let glb: *u8 = sys_read_file("knowledge/faceanat_tex.glb" as *u8, rd)
130 var magic_ok: i64 = 0
131 if (glb as i64) != 0 { if glb[0]==103 as u8 { if glb[1]==108 as u8 { if glb[2]==84 as u8 { if glb[3]==70 as u8 { magic_ok = 1 } } } } }
132 // scan the JSON for COLOR_0
133 var col_ok: i64 = 0
134 let glen: i64 = rd[0]
135 var si: i64 = 0
136 while si < glen - 7 {
137 if glb[si]==67 as u8 { if glb[si+1]==79 as u8 { if glb[si+2]==76 as u8 { if glb[si+3]==79 as u8 { if glb[si+4]==82 as u8 { col_ok = 1; si = glen } } } } } // "COLOR"
138 si = si + 1
139 }
140 var t3: i64 = 0
141 if glblen > 0 { if magic_ok == 1 { if col_ok == 1 { t3 = 1 } } }
142 if t3 == 1 { hw("T3 PASS valid COLOURED glTF (magic + COLOR_0 attribute) -- a photo-textured VR head\n" as *u8) }
143 else { fails=fails+1; hw("T3 FAIL glTF magic="); pn(magic_ok); hw(" color="); pn(col_ok); hw(" len="); pn(glblen); hw("\n" as *u8) }
144
145 // T4 watertight preserved + determinism
146 let out2: *i64 = sys_mmap(16) as *i64
147 faceanat_build(base)
148 mg_build(base, F, cubevi, vbuf, fbuf, out2)
149 let expect_v: i64 = nf / 2 + 2
150 var dv: i64 = nv - expect_v
151 if dv < 0 { dv = 0 - dv }
152 var t4: i64 = 0
153 if out2[0] == nv { if out2[1] == nf { if dv < nf / 16 { t4 = 1 } } }
154 if t4 == 1 { hw("T4 PASS watertight (V=F/2+2) preserved + deterministic\n" as *u8) }
155 else { fails=fails+1; hw("T4 FAIL watertight/determinism\n" as *u8) }
156
157 if fails == 0 { hw("FACEANAT-TEXBAKE-GATE 4/4 GREEN -- our OWN base mesh, PHOTO-TEXTURED from the reference, watertight, coloured-glTF exported = a VR-loadable photoreal-track head\n" as *u8); sys_exit(0); return 0 }
158 hw("FACEANAT-TEXBAKE-GATE RED fails="); pn(fails); hw("\n" as *u8)
159 sys_exit(1)
160 return 1
161}