Raise the NPC character budget to 24k and refine the prototype neck

This commit is contained in:
zwitschi committed 2026-11-05 19:37:19 +01:00
1 parent f0d4b81239
commit 79224c5acf
19 files changed
+128 -56

No files matched your search

+1 -1
View File
@@ -193,7 +193,7 @@ capture). Pass conditions:
### Contract (both, every prototype)
- 16,000 triangles / 16,000 glTF vertices per character; gear stays at 1,500.
- 24,000 triangles / 24,000 glTF vertices per character; gear stays at 1,500.
- Optional extra bones are allowed; the required 13 core bones and their rest positions must not
move; the `npc_base` mesh node name and the five tint slots stay unchanged.
+1 -1
View File
@@ -4,7 +4,7 @@ This folder holds the project documentation, visual references and generated QA
## Current priorities
1. [Blender NPC model overhaul](../TODO.md#blender-npc-model-overhaul-top-priority) — part-based head/face/hands pipeline and 16,000-budget contract.
1. [Blender NPC model overhaul](../TODO.md#blender-npc-model-overhaul-top-priority) — part-based head/face/hands pipeline and 24,000-budget contract.
2. [MakeHuman and 3D model/map improvements](../TODO.md#makehuman-character-pipeline) — body intake, asset re-evaluation and local map reconstruction.
3. [0.10.0 release candidate](../TODO.md#milestone-0100--3d-model-and-map-improvements-minor) — versioned release hardening after the unversioned development tracks.
+42
View File
@@ -0,0 +1,42 @@
# ADR-0016: 24,000-triangle character budget
- **Status:** Accepted
- **Date:** 2026-11-05
## Context
ADR-0015 raised the character contract to 16,000 triangles / 16,000 glTF
vertices for the MakeHuman head, hands and crowd variety. The local MPFB
full-body prototype now uses that head, project hands and shoes, and a fused
neck: it measures 19,747 triangles before any clothing variation. The 16,000 cap
leaves no room for the firefighter and hoodie gear, and it forces the body and
neck into a low decimation that produces visible facets.
## Decision
Raise the character contract to **24,000 triangles / 24,000 glTF vertices** per
character (`CHAR_MAX_TRIS`/`CHAR_MAX_VERTS`, `npc_pipeline.MAX_TRIANGLES`/
`MAX_VERTICES`, and the `adapt` defaults). The 13 core bones, five tint slots,
front orientation, grounding and single `npc_base` skinned mesh are unchanged.
Gear stays at 1,500 triangles and props at 4,000.
## Consequences
- The MPFB body, accepted head and neck fit with headroom for the 12 clothing
variants and future jacket/hoodie detail.
- The 24-NPC and Web frame-time budgets must be re-measured before shipping any
variant built at the new cap; the extra geometry is not free.
- The procedural generator and the low-poly `npc_base` fallback remain valid;
they are not required to use the new headroom.
- MPFB stays a local development tool. Production must bake a committed source
GLB; CI and the build must not depend on MPFB.
- Historical reviews and measurements that state 16,000 remain accurate for the
date they were recorded; current contract documents state 24,000.
## Alternatives
- **Keep 16,000 and decimate the MPFB body further:** rejected because the neck
and shoulder already show facets and the clothing variants would exceed the
cap.
- **Separate caps for the MPFB prototype and the shipped characters:** rejected
because it creates a second contract and makes the rollout ambiguous.
+1
View File
@@ -19,3 +19,4 @@ Each ADR records the context, decision, consequences and alternatives for a dura
- [0013-blender-authored-npc-characters](0013-blender-authored-npc-characters.md)
- [0014-runtime-image-root](0014-runtime-image-root.md)
- [0015-npc-model-variety-sourcing](0015-npc-model-variety-sourcing.md)
- [0016-npc-character-budget-24k](0016-npc-character-budget-24k.md)
+3 -3
View File
@@ -139,7 +139,7 @@ The runtime NPC contract is intentionally narrow. It is enforced by
| Core bones | `Head`, `HipL/R`, `KneeL/R`, `ShoulderL/R`, `ElbowL/R`, `HandL/R`, `Spine`, `Neck` at the frozen rest positions. Optional extra bones (fingers, face, toes) are allowed if they do not move the core rest positions or break `NpcAvatar` proxies. |
| Tint slots | `skin`, `cloth`, `pants`, `accessory`, `hair`; fixed detail materials keep their authored colours. |
| Orientation | Blender −Y / Godot +Z front, feet grounded near `y = 0`, metre scale. |
| Budget | 16,000 triangles / 16,000 glTF vertices per character; 1,500 per gear piece; 4,000 per prop. The low-poly `npc_base` remains a fallback, not a second contract. |
| Budget | 24,000 triangles / 24,000 glTF vertices per character; 1,500 per gear piece; 4,000 per prop. The low-poly `npc_base` remains a fallback, not a second contract. |
| Textures | 256² albedo + normal + packed ORM per slot; cloth/pants use the 4× `NPC_FABRIC_UV_SCALE` and skip per-character baked AO, while skin/hair/gear keep AO. |
| Gear attach | Authored in attach-point space: head `Rig/Head` (0, 1.62, 0), back (0, 1.10, 0), chest (0, 1.30, 0), hand (±0.27, 0.78, 0.02); grip 5 cm below the origin. `GEAR_OFFSETS` and `HAND_ITEM_FORWARD` are runtime fit corrections, not authored-geometry changes. |
| Fallback chain | Library variant → `npc_base.glb` → procedural `NpcAvatar` mesh. Committed GLBs and maps must keep CI offline and Blender-free. |
@@ -217,8 +217,8 @@ GLBs and maps.
| Tool | Role | Committed artifact | Verification gate |
| --- | --- | --- | --- |
| `tools/npc_pipeline.py` | Builds the skinned base avatar, five-slot material maps, palette and AI-fabric preparation (`prepare`/`palette`) | `npc_base.glb`, `assets/textures/npc/*_{albedo,normal,orm}.png`, `palette.json` | `audit_glb` against the 16,000-triangle / 16,000-vertex base contract (13 core bones required; extras allowed) |
| `tools/blender_assets.py` | Builds/renders the library: 8 characters, 18 gear pieces, 20 props, plus `manifest.json`; stdlib `audit`/`fit`/`sheet`/`list` | `assets/models/blender/{npc,npc_gear,props}/*.glb` | Character cap 16,000 tris / 16,000 verts, 1,500 per gear, 4,000 per prop; grounding, UV, degenerate-triangle, attach-fit and manifest coverage checks |
| `tools/npc_pipeline.py` | Builds the skinned base avatar, five-slot material maps, palette and AI-fabric preparation (`prepare`/`palette`) | `npc_base.glb`, `assets/textures/npc/*_{albedo,normal,orm}.png`, `palette.json` | `audit_glb` against the 24,000-triangle / 24,000-vertex base contract (13 core bones required; extras allowed) |
| `tools/blender_assets.py` | Builds/renders the library: 8 characters, 18 gear pieces, 20 props, plus `manifest.json`; stdlib `audit`/`fit`/`sheet`/`list` | `assets/models/blender/{npc,npc_gear,props}/*.glb` | Character cap 24,000 tris / 24,000 verts, 1,500 per gear, 4,000 per prop; grounding, UV, degenerate-triangle, attach-fit and manifest coverage checks |
| `tools/bake_ao.py` | Bakes per-asset AO maps | `<asset>_ao.png` (256²) | Wired through `Materials.apply_ao()`/`SurfaceMaterials`; cloth/pants opt out (see below) |
| `tools/npc_proportions.py` | Measures exported GLB rest pose (height, head, shoulders, hips, torso, limbs, feet) against the stylized guide | report / JSON in `docs/npc-visual-review.md#proportion-audit` | All eight variants must stay inside the guide after a body change |
| `tools/npc_baseline.py` | Assembles neutral-baseline sheets and before/after comparisons | `docs/blender_previews/sheet_npc_baseline*.jpg` | Human review against `docs/npc-visual-review.md` |
+2 -2
View File
@@ -200,8 +200,8 @@ flatpak run org.blender.Blender --background \
--python "$PWD/tools/blender_assets.py" -- adapt \
--file "$PWD/tmp/npc-research/makehuman_base.glb" \
--out "$PWD/tmp/npc-research/makehuman_adapted.glb" \
--target-tris 16000
# prints: adapted makehuman_adapted.glb: 36972 -> 16000 tris (bones=N, meshes=1)
--target-tris 24000
# prints: adapted makehuman_adapted.glb: 36972 -> 24000 tris (bones=N, meshes=1)
```
Run `inspect` on the adapted GLB before and after, and keep the procedural
+2 -2
View File
@@ -141,7 +141,7 @@ render about 2.5 min.
All library variants share the [character and gear asset contract](architecture.md#character-and-gear-asset-contract):
`npc_base` mesh node, required 13 core bones (optional extras allowed), five
tint slots, +Z visual front, 16,000/16,000 character budget and the same 256²
tint slots, +Z visual front, 24,000/24,000 character budget and the same 256²
slot-map/AO rules. Role selection and look notes:
| Character | `layer_for()` / look | Suggested roles | Preview gear |
@@ -200,7 +200,7 @@ carry baked AO and the shared neutral material maps described above.
- `python3 tools/blender_assets.py audit`: container, `POSITION`/`NORMAL`/
`TEXCOORD_0`, UVs in [0, 1], no zero-area triangles (Godot warns about them
during LOD generation), budgets (characters 16000/16000, gear 1500, props 4000
during LOD generation), budgets (characters 24000/24000, gear 1500, props 4000
triangles), grounding, and an editable `.blend`. For characters it also
checks skinning, bones, slots, the `npc_base` mesh node and the height.
- `tools/tests/test_blender_assets.py`: catalogue and contract consistency with
+9 -7
View File
@@ -8,7 +8,7 @@ remain references or local prototypes unless a later ADR accepts them.
The library needs variety beyond the original eight silhouettes while preserving
the `npc_base` contract: mesh node, 13 required core bones (optional extras
allowed), five tint slots, −Y/+Z front, grounded feet and the 16,000/16,000
allowed), five tint slots, −Y/+Z front, grounded feet and the 24,000/24,000
character budget.
| Source | Licence | Result |
@@ -55,14 +55,16 @@ The MakeHuman body should reuse the approved local head/hand parts rather than f
a second face implementation.
The current local MPFB full-body prototype (`tmp/npc-research/build_mpfb_npc.py`) assembles the
accepted head on an MPFB 2.0.18 body at **15,317 / 16,000 tris**, 1.810 m, 14 bones and 10
accepted head on an MPFB 2.0.18 body at **19,747 / 24,000 tris**, 1.810 m, 14 bones and 10
materials, with project hands, bevelled shoe shells with inset soles and tongues, pant cuffs,
cloth sleeve cuffs and flat slot colours. The torso is radially inflated by 12% through z 0.72–1.40
to loosen the shirt. It is a review candidate, not a shipped asset. The neck is a radial cut
of the decimated column bridged by a four-ring, 20-segment lathe (lower rings painted cloth,
reading as a crew neck); the ankles are hidden by 0.11 m shoe shells and 0.08 m pant cuffs, and a
light smoothing pass softens the closed thigh/hip region. The neck skin test is guarded to z >
1.35 so it cannot paint the crotch. Remaining polish: the crotch hollow still reads as a V under
to loosen the shirt. It is a review candidate, not a shipped asset. The neck is a boolean-cut
circular bore bridged by a smooth lathe; the accepted head is trimmed at the narrow neck (z 1.55)
so its wide flat cut brim is discarded, and the lathe flares to cover the bore, then tucks inside
the jaw. This removed the square collar, dark notches and wide brim; a thin jaw crease and a hard
shirt-shoulder point in three-quarter view remain. The ankles are hidden by 0.11 m shoe shells and
0.08 m pant cuffs, and a light smoothing pass softens the closed thigh/hip region. The neck skin
test is guarded to z > 1.35 so it cannot paint the crotch. Remaining polish: the crotch hollow still reads as a V under
the shirt hem, a partly loosened shirt and angular thigh facets; a separate loose shirt shell is
the fix. Lowering the hem to z 0.80, tilting it up at the front and a 13% hem flare were rejected
as a unitard, high-cut swimwear and a peplum respectively. A quick open, flared solidified tube
+2 -2
View File
@@ -71,8 +71,8 @@ The criteria below are for the stylized target, not photorealism. A change must
pass every applicable item before a library rebuild is accepted.
1. **Asset contract:** `npc_base` mesh node, the required bones, five tint slots,
front +Z, feet within 3 cm of y=0, 1.6–2.1 m height, at most 16,000 triangles
and 16,000 glTF vertices per character. The required 13 core bones stay fixed;
front +Z, feet within 3 cm of y=0, 1.6–2.1 m height, at most 24,000 triangles
and 24,000 glTF vertices per character. The required 13 core bones stay fixed;
optional extra bones are allowed. Gear remains at most 1,500 triangles.
2. **Proportion and silhouette:** head, neck, shoulders, torso, hips, limbs and
feet read as one body; front/three-quarter/profile silhouettes agree with the