Second garment-only render pass per view at the identical paused animation time; the analyzer intersects so body-key pixels split into exposed_skin (no garment behind — informational: collars, sleeveless arms) vs clip_through (garment behind — gating). Highlights differ: lime exposed, red clip. Peasant re-run: 72 captures, 56 clip-through flags — real collar micro-clips under crouch/walk plus suspected 1px boundary artifacts; gate threshold + garment-mask dilation are the tuning knobs, to be calibrated against the first real modern garments. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2.4 KiB
garment-qa — chromakey garment-clipping QA (T-1089)
Automatically detects clothing clip-through with a two-pass depth-proximity
chromakey. Per view (clips × sampled frames × 4 camera yaws), the capture scene renders
the SAME frozen animation frame twice: pass A paints the body segments a garment
claims to cover (coverage.json hides) flat unshaded magenta, garment + head/hands
normal; pass B is identical except the garment is flat cyan and every garment
vertex is nudged clip_epsilon_m (default 3 cm) toward the camera. A body-key pixel
that is magenta in A but cyan in B means the ε-shifted cloth now covers it — the body sat
within ε in front of the cloth = poking through. This separates a true clip from a limb
merely crossing in front of the torso, an open collar, or a bare arm over background
(all of which stay magenta because the cloth behind them is > ε away).
Run: tooling/garment-qa/run-garment-qa [config.json] (defaults to
configs/peasant.json). It launches Godot (~/bin/godot4, opengl3, xvfb-run when
headless) on the capture scene, then runs the analyzer.
Config (path passed to the scene via GARMENT_QA_CONFIG): garments
({item_id,slot} catalogue items, or {glb,covers[]} for a raw WIP garment),
body_types, clips, frames_per_clip, yaws, head_id/hair_id/eyebrow_id/skin_tone,
out_dir.
Read the report: <out_dir>/report.json — the same summary prints to stdout. Two
metrics per capture:
clip_through_pixels/largest_clip_component— key pixels the ε-shifted cloth covers (skin ≤ ε in front of cloth). This is the real defect and it gates: a capturefails when its largest connected clip blob ≥--min-pixels(default 8, tolerating AA edges).clip_through_failures+ theby_groupclipfail/worstClipcolumns roll it up.exposed_skin_pixels— key pixels the shift did NOT cover (skin well in front of any cloth: collar/sleeve/ankle gaps, a limb crossing the torso). Informational; does not gate.
Tune sensitivity with clip_epsilon_m in the config (smaller = only tighter pokes count)
and --min-pixels on the analyzer. Failing/flagged frames are copied to
<out_dir>/failures/*_HL.png with exposed_skin lime, clip_through filled red, and
each clip blob boxed.
Note: the Godot scene lives at client/tools/garment_qa/chromakey_scene.gd (not here)
because Godot res:// paths cannot leave the client project root.