File size: 8,692 Bytes
39ff632
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37e3d5a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Procedural Three.js Object Patterns

Use this reference only when implementing a model.

## Geometry Choices

- box: flat machinery, furniture, panels, blockout masses
- sphere/ellipsoid: fruit, knobs, organic joints, rounded stones
- cylinder/cone/capsule: trunks, pipes, limbs, handles, bottles, rockets
- torus: rings, tires, loops, trim, cable coils
- shape extrude: logos, flat ornamental plates, blades, keys, leaves
- lathe: vases, bottles, bowls, lamps, wheels
- tube along curve: cables, roots, branches, straps, hoses
- instanced mesh: screws, rivets, leaves, needles, scales, pebbles, repeated ornaments
- plane cards: thin leaves, feathers, labels, cloth strips, decals

## Material Recipes

- wood: brown base, vertical grain normal, roughness variation, darker creases, lighter worn edges
- stone: mottled albedo, high roughness, bump/normal noise, lichen/dirt patches
- metal: lower roughness, metalness, edge scratches, anisotropic-looking streaks via texture
- plastic: controlled roughness, subtle color variation, bevels to catch highlights
- leaf/plant: alpha cards or thin shape geometry, green hue variation, central vein, translucent-ish bright rim
- water/glass: transparent material only if needed; add environment/reflection cues or it reads as a flat sheet

## Material Layer Fields

For each material, prefer a layered description:

- `baseColor`: dominant sampled color.
- `colorVariation`: palette, mottling pattern, amplitude, regional masks.
- `roughness`: base value, variation amount, map/pattern source.
- `metalness`: base value and local changes.
- `normal`: procedural pattern, strength, scale.
- `bump`: amplitude and scale for small tactile relief.
- `displacement`: only for silhouette-visible or close-up relief.
- `wear`: edge wear, scratches, chips, polish, exposed underlayer.
- `dirt`: amount, cavity bias, color, vertical streaking, contact staining.
- `localOverrides`: named regions where color/roughness/bump differs from the base.

Local overrides should answer: where, what changes, how strong, and which image evidence supports it.

## Local Feature Types

Use `component.localFeatures` for details that matter to recognizability:

- raised ridge
- recessed groove
- seam line
- screw or rivet
- chip or dent
- scratch cluster
- stain or dirt patch
- decal or label area
- hole or socket
- bevel highlight
- fabric stitch
- leaf vein or serrated edge

Each feature should include placement, approximate size, orientation, material effect, geometry effect, and confidence.

## Detail Recipes

Concrete Three.js material/geometry approach per `detailInventory` kind. Cross-reference
`grimoire/intake/detail_inventory.md` for the full taxonomy and the evidence/mapping rule.

- gloss: `MeshPhysicalMaterial` with a low-`roughness` localOverride (0.05-0.2) sized to the
  hotspot region; use `clearcoat`/`clearcoatRoughness` for a lacquer layer over a rougher
  base, `anisotropy`/`anisotropyRotation` for brushed/streaked highlights.
- bevel: real geometry, not a normal map - `edgeTreatment.type = chamfer`, `bevelRadius`
  object-relative (0.02-0.08), `segments` 2-4 for a soft catch-light rim, 1 for a hard edge.
- fastener: `InstancedMesh` for the repeated part; `count` + spacing pattern (linear, radial,
  grid) + head shape (hemisphere/flat/hex) + recess (raised vs countersunk); low-roughness
  metal material on the head crown.
- linework: pick engraved groove (real recessed geometry along a path, catches shadow),
  painted line/decal (canvas-texture localOverride, color contrast only, no relief), or
  panel-line (thin dark AO/roughness localOverride along a seam, no depth) - match whichever
  the reference evidence shows; do not default to decal for something that casts a shadow.
- stain: `material.localOverrides` region with `dirtAmount`, `cavityBias` (concentrate in
  crevices), `streak` (directional, usually gravity-down), `patinaColor` for oxidation hue
  shift, or a `fadedMask` (lighter, desaturated) for sun-bleaching - the inverse of dirt.

## Character Geometry And Material Recipes

Use these when `objectClass.primaryDomain` is `character` or `hybrid`. Pair with
`grimoire/character/reconstruction.md` for proportion/landmark data.

- head: sphere or ellipsoid scaled to the measured head-unit, then displaced/tapered toward
  the reference face shape (jaw width, chin point, cheek fullness) rather than left spherical.
- limbs: capsule or tapered cylinder per segment (upper arm, forearm, thigh, shin); taper
  ratio and length come from `anatomy.proportions`; capsules keep joints visually continuous.
- hands: simplified capsule-cluster (palm block + finger capsules) at low segment count;
  do not attempt per-knuckle detail unless the reference is close-up and complexity is ultra.
- hair: hair cards (alpha-mapped planes layered in clumps) for stylized/low-complexity, or a
  tube-along-curve per lock for wavy/flowing hair with visible strand structure; prefer cards
  by default - hair is the classic single-image failure mode, so favor legible clumps over
  many thin strands that swim or alias.
- face feature placement: position eyes, brows, nose, mouth using `anatomy.faceLandmarks`
  normalized coordinates (eyeLine, eyeSpacing, noseBase, mouthLine, hairline); never eyeball
  placement freehand once landmarks exist.
- eyes: glossy sphere (low roughness, slight clearcoat) plus an iris decal/texture; a correct
  catchlight (small bright localOverride matching the key light) sells more realism than
  extra geometry.
- clothing: extrude or plane panels per garment piece, with fold normals (a normal-map or
  displacement pattern following expected gravity/pose creases) rather than a flat shell;
  reuse Track A detail machinery (seam, stitch, decal, stain) for prints, buttons, wear.
- skin: approximate subsurface scattering, not true SSS - warm base albedo, soft/lower
  roughness variation (skin is not uniformly matte), and a rim or backlight to fake light
  passing through thin tissue (ears, nose edge). Avoid pure-Lambertian flat skin.

## Verification Cues

A procedural object is usually failing when:

- silhouette reads wrong even before material
- every edge is perfectly sharp or perfectly smooth
- material has one flat color and no roughness variation
- lighting hides the form instead of explaining it
- repeated details are too evenly spaced
- close-up details add triangles but not recognizability

---

## Hard-won patterns — real-object reconstructions (2026-07: BMX bike + M9 bayonet)

**Tube-network > single sweep for framed/tubular subjects.** A bike frame, knife-handle grip, fork, handlebar are *networks of straight members*. Model each member as a component with `attachment.localStart`/`localEnd` (+`baseRadius`) — the generator emits an oriented cylinder (quaternion Y→dir). A single closed `curve-sweep` CatmullRom-smooths into a teardrop blob. (BMX frame was a teardrop until rebuilt as a tube-network.)

**Blockout must contain every silhouette-defining macro part.** A bike blockout with the frame but no wheels does not read as a bike, and coarse silhouette-IoU won't catch the omission. Put wheels/blade/major masses in at `level: macro`.

**Root/container `transform.scale` MUST be `[1,1,1]`.** Children parent to the root node and inherit its transform — a `0.02` "hide" scale shrinks the whole model to a speck. Hide the container with a transparent material (`opacity:0`), never with scale.

**Cloned components inherit `actionProfile.animationRole` — reset it.** Cloning a seeded root carries `animationRole:"root"`, and `root` ∈ ATTACHMENT_ROLES, so every part trips the structural attachment gate. Set a sensible per-part `animationRole` (e.g. `"static-part"`); keep roles like `handle` off non-appendage parts.

**Curve the small details.** Serrations/scallops/teeth as straight boxes look wrong. Use `ellipsoid` (or slightly canted primitives, alternating ±angle) for rounded scallop teeth. Each detail with its own small cant reads as a hand-ground edge.

**Grip / friction texture = geometric ridge segments.** For a knurled/wrapped/segmented grip, model raised barrel bands: a thin core cylinder + N short attachment-tube segments (radius just *proud* of the core, small groove gaps). Size them barely larger than the core — oversized tori read as a coil/spring, not a grip. Material texture alone (no geometry) reads as smooth/"thô".

**`invisibleRoot`/container material is still subject to the material-pass PBR gate.** Give the container a *complete* material (roughness map, frequency bands, textureResolution) — copy a proven one — or it fails "needs usable referencePbr / roughness map" even though it never renders.