Docs: Bathynaut helmet Synty-match + in-game body-swap session log + cookbook 14-E

Session log for the 07-24 character work. Adds cookbook 14-E: the per-instance _BaseColor override
gotcha (hit-flash sets URPMaterialPropertyBaseColor=(1,1,1) on player/enemy render children, replacing
the material _BaseColor -> flat null-map materials render cream; color via a solid _BaseColorMap texture).
Corrects the older 'clear the map -> uses _BaseColor' note.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 14:59:20 -07:00
parent 9f9c3b07b9
commit 749aedfbde
2 changed files with 64 additions and 0 deletions
@@ -335,3 +335,5 @@ Tie any emissive to the **ontology** (the helmet porthole = teal glass, faint gl
**D. Judge cohesion in-engine, at game scale, next to the existing Synty assets.** A generated mesh that looks fine solo can still clash beside the low-poly body — the only true test is a Play capture with the character next to its neighbours (the suit, an enemy) at the real game framing (§9). The Blender render confirms the mesh is clean; the *style match* is an in-engine, next-to-siblings call.
Recipe verified on the Mark-V: 4 hand-model attempts failed → Rodin generate → clean-decimate 23k→1.1k (0 holes) → drop the copper photoreal map → flat `M_Diver_Brass`/`HelmetMetal` + a teal `M_Diver_Porthole` + flat-shade → reads as one cohesive Synty diver (operator-approved). GLB 1.7 MB → 736 KB (texture dropped).
**E. ★ Coloring on the GAMEPLAY (deformation) rig ≠ staging — flat `_BaseColor` FAILS.** A static staging mesh takes flat colour from the material `_BaseColor` (plain Principled / the `Skinned-Palette` graph). But the animated player/enemy render entities carry a **per-instance `URPMaterialPropertyBaseColor` override** (driven by the hit-flash system, set to `(1,1,1)` at rest) which **REPLACES** the material's `_BaseColor` — so a flat-`_BaseColor` material with `_BaseColorMap = null` renders **white/cream** (null map samples white × instance-white). (This corrects the older "clear `_BaseColorMap` → uses `_BaseColor` directly" note — that only holds for entities WITHOUT the per-instance override.) Fix: drive colour from `_BaseColorMap` — either UV the piece to a `PaletteAtlas` band, or assign a **solid-colour texture** (an 8×8 PNG of the target colour) as `_BaseColorMap` and leave `_BaseColor` white; the instance override then just multiplies (and the flash still tints correctly). Diagnose by reading the live entity: `EntityManager.HasComponent<URPMaterialPropertyBaseColor>` on the `LinkedEntityGroup` render children → if present and `(1,1,1)`, the material `_BaseColor` is dead, use a map. Per-submesh colour (e.g. the Mark-V's brass/gunmetal/glass) = one material per submesh, each with its own solid `_BaseColorMap`. Verified live: `M_Diver_*_Skinned` + `DiverTex/T_Diver_*.png` on `Player.prefab`.