@bitmagic/cli 0.1.66-dev.6 → 0.1.66-dev.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -1
- package/assets/character-skin-authoring/SKILL.md +43 -0
- package/assets/character-skin-authoring/references/exporters.md +134 -0
- package/assets/character-skin-authoring/references/eyes.md +215 -0
- package/assets/character-skin-authoring/references/materials.md +115 -0
- package/assets/character-skin-authoring/references/playground.md +78 -0
- package/assets/character-skin-authoring/references/profiles.md +97 -0
- package/assets/character-skin-authoring/references/projection.md +190 -0
- package/assets/character-skin-authoring/references/regional-detail.md +72 -0
- package/assets/character-skin-authoring/scripts/assemble_character.py +205 -0
- package/assets/character-skin-authoring/scripts/authored_detail.py +47 -0
- package/assets/character-skin-authoring/scripts/authored_surface_patch.py +83 -0
- package/assets/character-skin-authoring/scripts/brow_groom.py +62 -0
- package/assets/character-skin-authoring/scripts/build_face_detail.py +107 -0
- package/assets/character-skin-authoring/scripts/build_surface_candidate.py +28 -0
- package/assets/character-skin-authoring/scripts/canthus_wall.py +57 -0
- package/assets/character-skin-authoring/scripts/character_build.py +54 -0
- package/assets/character-skin-authoring/scripts/eye_assets.py +333 -0
- package/assets/character-skin-authoring/scripts/eye_opening.py +114 -0
- package/assets/character-skin-authoring/scripts/eye_texture.py +35 -0
- package/assets/character-skin-authoring/scripts/eyelid_detail.py +34 -0
- package/assets/character-skin-authoring/scripts/eyelid_morph.py +171 -0
- package/assets/character-skin-authoring/scripts/eyelid_patch.py +173 -0
- package/assets/character-skin-authoring/scripts/face_atlas.py +51 -0
- package/assets/character-skin-authoring/scripts/geometry_repair.py +112 -0
- package/assets/character-skin-authoring/scripts/glb_arrays.py +13 -0
- package/assets/character-skin-authoring/scripts/glb_output.py +21 -0
- package/assets/character-skin-authoring/scripts/inspect_skin_point.py +66 -0
- package/assets/character-skin-authoring/scripts/normal_patch_height.py +38 -0
- package/assets/character-skin-authoring/scripts/prepare_face_reference.py +23 -0
- package/assets/character-skin-authoring/scripts/regional_atlas.py +51 -0
- package/assets/character-skin-authoring/scripts/select_preview.py +90 -0
- package/assets/character-skin-authoring/scripts/skin_views.py +267 -0
- package/assets/character-skin-authoring/scripts/surface_pbr_maps.py +46 -0
- package/assets/character-skin-authoring/scripts/texture_repair.py +98 -0
- package/assets/character-skin-authoring/scripts/vertex_detail_support.py +80 -0
- package/assets/character-skin-authoring/scripts/vision_blend_materials.py +74 -0
- package/assets/character-skin-authoring/scripts/vision_materials.py +276 -0
- package/assets/character-skin-authoring/scripts/workspace_paths.py +18 -0
- package/assets/metahuman/src/work/metahuman/MetaHumanActor.ts +580 -0
- package/assets/metahuman/src/work/metahuman/MetaHumanLabHooks.ts +122 -0
- package/assets/metahuman/src/work/metahuman/MetaHumanMaterials.ts +500 -0
- package/assets/metahuman/src/work/metahuman/MetaHumanSpeech.ts +242 -0
- package/assets/metahuman/src/work/metahuman/StudioEnvironment.ts +142 -0
- package/assets/metahuman/tools/lipsync/make_line.py +181 -0
- package/assets/metahuman/tools/metahuman/README.md +21 -0
- package/assets/metahuman/tools/metahuman/e2e/eval.mjs +34 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/arm-pose-check.js +32 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/bone-displacement.js +26 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/clip-shoulder.js +41 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/grafted-bones.js +11 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/helper-follow-descent.js +38 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/helper-follow-sweep.js +31 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/helper-joints-inspect.js +10 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/outfit-bad-vertices.js +26 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/outfit-body-material.js +7 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/outfit-own-skeleton.js +8 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/shirt-bone-ownership.js +25 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/shirt-edge-stretch.js +26 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/shirt-long-edges.js +23 -0
- package/assets/metahuman/tools/metahuman/e2e/probes/walk-sampler.js +105 -0
- package/assets/metahuman/tools/metahuman/e2e/shot.mjs +125 -0
- package/assets/metahuman/tools/metahuman/e2e/walk-probe.mjs +43 -0
- package/assets/metahuman/tools/metahuman/merge-skeletons.mjs +69 -0
- package/assets/metahuman/tools/metahuman/package.json +13 -0
- package/assets/metahuman/tools/metahuman/prepare.sh +25 -0
- package/assets/metahuman/tools/metahuman/reorder-body-first.mjs +20 -0
- package/assets/metahuman/tools/metahuman/smooth-outfit-weights.mjs +48 -0
- package/assets/metahuman/tools/metahuman/strip-draco.mjs +32 -0
- package/assets/metahuman/tools/metahuman/transfer-skin-weights.mjs +90 -0
- package/dist/commands/generate.d.ts +49 -0
- package/dist/commands/generate.js +168 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/generate/audio-file.d.ts +6 -0
- package/dist/generate/audio-file.js +42 -0
- package/dist/generate/audio-file.js.map +1 -0
- package/dist/generate/music.d.ts +4 -3
- package/dist/generate/music.js +6 -23
- package/dist/generate/music.js.map +1 -1
- package/dist/generate/stream.d.ts +13 -0
- package/dist/generate/stream.js +14 -1
- package/dist/generate/stream.js.map +1 -1
- package/dist/scaffold/asset-pipeline-skill-files.js +2 -0
- package/dist/scaffold/asset-pipeline-skill-files.js.map +1 -1
- package/dist/scaffold/character-skin-skill-files.d.ts +2 -0
- package/dist/scaffold/character-skin-skill-files.js +49 -0
- package/dist/scaffold/character-skin-skill-files.js.map +1 -0
- package/dist/scaffold/metahuman-skill-files.d.ts +21 -0
- package/dist/scaffold/metahuman-skill-files.js +306 -0
- package/dist/scaffold/metahuman-skill-files.js.map +1 -0
- package/dist/scaffold/project-files.js +4 -4
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/project.js +4 -0
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/skill-files.js +3 -1
- package/dist/scaffold/skill-files.js.map +1 -1
- package/dist/tools/bundles.js +8 -0
- package/dist/tools/bundles.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -217,7 +217,7 @@ browser reloads itself on every change and the assets panel shows each generatio
|
|
|
217
217
|
| `bitmagic trailer publish <file.mp4> [--no-attach]` | Upload a trailer (`.mp4`/`.webm`, ≤ 200 MiB, header-checked so a renamed image is refused before upload) to the CDN under `game-media/<gameId>/` and put it at the front of the game page gallery. Re-running replaces the previous trailer (remembered in `.bitmagic/trailer/published.json`); the page is capped at 12 media items. Works before the first publish — the page goes live on the first `bitmagic publish --visibility public`. `--no-attach` uploads only. |
|
|
218
218
|
| `bitmagic forge --prompt "..." [--city\|--dungeon\|--platformer\|--freeform] [--name <name>] [--resume <jobId>]` | Design and bake a whole playable level into `world.json`. Costs sparks, and takes many minutes — the bake alone can take twenty. `--resume <jobId>` picks a failed run back up from the last step that finished, rather than redoing the whole thing. |
|
|
219
219
|
| `bitmagic forge --edit "..." [--level <id or name>]` | Change a detail of a level this project forged — a door style, the light fixtures, a prop — without re-forging it. The stored design is patched and only what the change touches is re-made; the level is replaced in place. See [Editing a forged level](#editing-a-forged-level). |
|
|
220
|
-
| `bitmagic tools <list\|path\|install> [bundle]` | The script bundles the CLI ships for skills that drive Blender or
|
|
220
|
+
| `bitmagic tools <list\|path\|install> [bundle]` | The script bundles the CLI ships for skills that drive Blender, Python or Node (`blender-level`, `unity-import`, `metahuman`): what they are, where this install keeps them, and `install` to copy one into the project's `tools/`. Local, no network, no sparks. |
|
|
221
221
|
| `bitmagic levels <list\|add\|rename\|set-start\|remove> ...` | Manage the levels `forge` creates: which one boots, their names, registering a bake you already have, deleting one. Local, no network, no sparks. See **Managing levels** below. |
|
|
222
222
|
|
|
223
223
|
Every command exits non-zero on failure with a single-line message (no stack trace) and, where a
|
|
@@ -531,6 +531,32 @@ before. Without a prior user gesture the browser blocks autoplay, and the engine
|
|
|
531
531
|
immediately — so the cutscene silently does not run. `engine/agent-docs/video-cutscenes.md` covers
|
|
532
532
|
that and what to freeze while a cutscene plays.
|
|
533
533
|
|
|
534
|
+
## Spoken lines
|
|
535
|
+
|
|
536
|
+
`bitmagic generate speech --text "Halt, traveler. You shall not pass."` speaks a line, writes it
|
|
537
|
+
into `world.json` as an audio asset, and prints the `engine.playSound("<id>")` call that plays it.
|
|
538
|
+
Unlike a music bed it is registered as a **one-shot, not a loop** — dialogue plays when something
|
|
539
|
+
triggers it.
|
|
540
|
+
|
|
541
|
+
`--voice` picks who says it: `narrator` (the default), `male`, `female`, or a raw Eleven Labs
|
|
542
|
+
`voice_id` if you have cloned one of your own. `--model` switches model, and `--stability`,
|
|
543
|
+
`--similarity-boost`, `--style` and `--speed` are passed through to Eleven Labs when you want them;
|
|
544
|
+
leave them alone and Eleven Labs' own defaults apply.
|
|
545
|
+
|
|
546
|
+
It is **billed per second of audio produced**, not per character of text. A sentence costs about a
|
|
547
|
+
spark. The estimate charged up front comes from the length of the text; what you actually pay comes
|
|
548
|
+
from the finished audio.
|
|
549
|
+
|
|
550
|
+
Like `generate music`, it can write a file instead of a game asset:
|
|
551
|
+
|
|
552
|
+
```bash
|
|
553
|
+
bitmagic generate speech --text "Halt, traveler." --out line.mp3 --no-world
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
`--out` saves the MP3, `--no-world` leaves `world.json` untouched. That pair is the input to the
|
|
557
|
+
MetaHuman lip-sync tool (`tools/lipsync/make_line.py --audio line.mp3`), where a spoken line is
|
|
558
|
+
cut into mouth cues rather than played as-is. Use `--out` on its own to keep both.
|
|
559
|
+
|
|
534
560
|
## Reference image
|
|
535
561
|
|
|
536
562
|
When a game has a strong setting — a tropical island, a neon city — one accepted concept image can
|
|
@@ -1306,6 +1332,15 @@ by the engine's `MeshLevel`. The scaffolded `building-levels-in-blender` skill w
|
|
|
1306
1332
|
its first section says when that path applies (a frontier model, and Blender installed) and sends
|
|
1307
1333
|
everything else to `bitmagic forge`.
|
|
1308
1334
|
|
|
1335
|
+
## Importing a MetaHuman
|
|
1336
|
+
|
|
1337
|
+
An Epic MetaHuman (a UE 5.7 glTF export from the smorchj/metahuman-to-glb pipeline) can be the
|
|
1338
|
+
game's playable high-res character without voxelization. The scaffolded `importing-metahumans` skill
|
|
1339
|
+
carries the whole path — `bitmagic tools install metahuman` lands the GLB preparation scripts, the
|
|
1340
|
+
runtime module (`src/work/metahuman/`), the lip-sync tool and a headless verification rig — and names
|
|
1341
|
+
each failure a raw export produces (arms crossed into the chest, a torn shirt, hair left behind by a
|
|
1342
|
+
head turn, tinted skin, black eyes) with the fix that resolved it.
|
|
1343
|
+
|
|
1309
1344
|
## Art style
|
|
1310
1345
|
|
|
1311
1346
|
A 3D game is voxel-built unless `src/work/game.json` says otherwise:
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: character-skin-authoring
|
|
3
|
+
description: Use vision to author and review exposed-skin maps on textured 3D characters, including faces, hands and bodies. Prepare exact model views, annotate visible anatomy, project evidence into UV space, and review skin detail placement. Eye construction is a separate workflow.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Vision-led character skin authoring
|
|
7
|
+
|
|
8
|
+
The local agent makes anatomical/material decisions from images. Do not replace those decisions with RGB thresholds, world-height cutoffs, race/name rules, or another automated classifier. Deterministic tools handle projection and bookkeeping. The creator's existing agent subscription supplies vision; this workflow requires no hosted segmentation service.
|
|
9
|
+
|
|
10
|
+
## Establish evidence
|
|
11
|
+
|
|
12
|
+
Locate the model, its physical height, materials, texture resolution and rig. Keep the original immutable and write a separate material revision. Inspect the original generated image when available, but make the **actual mesh and its textures** authoritative: the generated mesh may differ from that image.
|
|
13
|
+
|
|
14
|
+
Use the local `scripts/skin_views.py` helper to create unlit, occlusion-correct views with their UV correspondences. Read [the projection contract](references/projection.md) for commands and formats. It requires local Blender and a Python environment with NumPy/Pillow. The helper performs no semantic recognition. Verify orientation from the resulting images; its axes are not anatomical labels.
|
|
15
|
+
|
|
16
|
+
Start with a full-body survey from opposite directions. Then frame each exposed region closely enough to see its boundaries. Inspect the face from front and both sides; inspect both hands from palm and dorsal sides and oblique angles showing finger webs. Inspect ears, neck, chest, arms, legs, feet or any other exposed region actually present. Add cameras when existing views cannot show a surface. Do not infer a hidden palm from a dorsal hand image or project a front silhouette through to the back.
|
|
17
|
+
|
|
18
|
+
## Author the maps using vision
|
|
19
|
+
|
|
20
|
+
For each viewed surface, annotate pixel polygons as `skin`, `dorsal_hand`, `palm`, `sole`, `lips`, `eyes`, `hair`, `nails`, or `non_skin`. `unknown` is explicit unresolved evidence. Use separate polygons for exclusions, ordered after enclosing polygons. Do not give an indistinct nail facial pores merely because the rest of the hand is clear. Record why a boundary is ambiguous; obtain a closer/different view before resolving it. Scars, freckles, tattoos and makeup usually remain skin with appearance annotations, not separate non-skin regions. Tight cloth is still cloth; green skin is still skin. If garment colour spills onto anatomically visible skin in the source albedo, record a texture defect separately from the semantic mask. A correct skin label cannot repair that colour.
|
|
21
|
+
|
|
22
|
+
Review the colored annotation overlay on the **same source image**, then review the **baked atlas reprojected onto every prepared view**, including unannotated side views. Use the dense visibility bake at a resolution appropriate to the source atlas; sparse splatting is a diagnostic, not a finished mask. Include the filename, image dimensions and source hash with every annotation set. If a tool displays a resized image, convert coordinates back to the recorded dimensions. Never claim to have visually reviewed an image you have not opened.
|
|
23
|
+
|
|
24
|
+
The helper deliberately leaves unobserved UV texels unknown and reports contradictory labels. Do not grow a skin mask across unknown areas to make a coverage statistic look good. Get additional views, increase sampling resolution, or use a reviewed Blender texture-paint correction. Mirrored/overlapping UVs can make conflicting anatomical labels impossible in one atlas: document that and create separate material/UV regions rather than average the labels.
|
|
25
|
+
|
|
26
|
+
## Apply region-appropriate detail
|
|
27
|
+
|
|
28
|
+
For material application and engine integration, read [material application](references/materials.md). The [installed exporters](references/exporters.md) assemble reviewed inputs in an explicit external workspace. After coverage passes review, register landmarks and surface scale for each detail patch. Use licensed exemplars and retain attribution and modification provenance. The b3662 face pilot in this repository demonstrates registered scan detail; its coordinates are **not** a universal face template.
|
|
29
|
+
|
|
30
|
+
- Face: region-specific pores, fine relief, oiliness and pigment. Exclude eye surfaces, lashes, brows, lips and facial hair from the ordinary pore layer; preserve actual folds and identity.
|
|
31
|
+
- Dorsal hands/fingers: knuckle folds, tendons and finer hand texture. Nails receive their own response.
|
|
32
|
+
- Palms/soles: glabrous skin with appropriate creases/ridges and roughness; do not stamp facial follicles onto it.
|
|
33
|
+
- Neck, torso, limbs, ears: use suitable regional detail and scale. Preserve the character's natural variation; do not transplant a donor's beard, identity marks or complexion.
|
|
34
|
+
|
|
35
|
+
Blend patch boundaries in surface space and check physical scale. A silhouette or clothing boundary needs a coverage edge; two adjacent skin patches need a continuous transition. Keep skin nonmetallic and preserve clothing/armor materials. Use the existing registered detail/SSS renderer where available; do not invent new renderer hooks or claim the projection helper installs materials by itself.
|
|
36
|
+
|
|
37
|
+
## Review and handoff
|
|
38
|
+
|
|
39
|
+
Inspect colored material regions and final shaded results separately. Use fixed cameras under diffuse, specular, side, studio and back lighting. Check full-body, face-sized and close detail views, plus a representative pose when the model is rigged. Confirm both hands, finger webs, nails, ears and every other exposed area; inspect clothing edges without revisiting unrelated deferred edits.
|
|
40
|
+
|
|
41
|
+
Record results per character and region: `reviewed`, `needs_view`, `conflict`, or `needs_detail_asset`. Archive source hashes, views, annotations, projected labels, atlas registration, licenses and review images together. Only call a character complete when its exposed regions are reviewed and the **applied** maps have been inspected. A parseable annotation file or a successful bake is not semantic validation.
|
|
42
|
+
|
|
43
|
+
Review the face and ocular exclusion before eye geometry/shading work; use the separate [optical-eye workflow](references/eyes.md) when that work is requested. Eye progress does not mark unresolved body skin as complete. This workflow is maintained in the GDK CLI assets and installed into supported agent skill directories from the same source. Keep per-character evidence and candidates outside those refreshed directories.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Installed character exporters
|
|
2
|
+
|
|
3
|
+
The skill now includes the tested offline skin, optical-eye and rig-assembly helpers.
|
|
4
|
+
Run `scripts/character_build.py` with an explicit `--workspace`; character assets live
|
|
5
|
+
outside the skill so refreshes do not erase them. Python needs NumPy, Pillow and SciPy.
|
|
6
|
+
Exact visibility recovery also needs Blender on PATH or `BITMAGIC_BLENDER`. These tools
|
|
7
|
+
perform deterministic assembly of the agent's reviewed inputs, never semantic recognition.
|
|
8
|
+
|
|
9
|
+
The retained workspace convention is:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
characters/ID/high/v1/
|
|
13
|
+
source/hy31pro.glb immutable source (name is a convention)
|
|
14
|
+
output/viewer-profile.json {"height": physical height in metres}
|
|
15
|
+
materials/body-detail-profile.json optional designed regional creases
|
|
16
|
+
materials/surface-patch-profile.json optional licensed regional patches
|
|
17
|
+
materials/repair-profile.json optional separately reviewed source defects
|
|
18
|
+
materials/v2/ registered face inputs and intermediate maps
|
|
19
|
+
materials/v4/ mixed-surface GLB and report
|
|
20
|
+
eyes/v1/ independent fitted optical-eye revision
|
|
21
|
+
output/character.glb optional existing bound body mesh
|
|
22
|
+
rig-report.json optional validated rig provenance
|
|
23
|
+
runtime/v1/ combined surface/eye/body variants
|
|
24
|
+
highquality/materials/faces/ID.json character-specific landmark registration
|
|
25
|
+
highquality/references/ licensed immutable exemplar files
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Evidence/masks/eye profiles can be anywhere supplied explicitly. Relative command paths
|
|
29
|
+
are workspace-relative. Keep their source/image hashes and projection receipts intact.
|
|
30
|
+
Paths inside authored JSON retain their documented conventions; relocating evidence may
|
|
31
|
+
require updating its source path without changing source bytes or camera contracts.
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
Use [the profile schemas](profiles.md) for independently authored landmarks, exclusions,
|
|
36
|
+
scale and optical dimensions. After preparing the facial profile:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
python scripts/character_build.py --workspace /path/to/assets --id CHARACTER --stage face
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The current face adapter uses the Lee Perry-Smith reference: `LeePerrySmith.glb`,
|
|
43
|
+
`Infinite-Level_02_Disp_NoSmoothUV-4096.jpg` and `Map-COL.jpg` in
|
|
44
|
+
`highquality/references/lee-perry-smith/`. Obtain the licensed originals explicitly and
|
|
45
|
+
retain CC BY 3.0 attribution; the skill does not download them. The adapter writes its
|
|
46
|
+
modification notice and hashes. Its calibrated relief amplitude is an authoring estimate,
|
|
47
|
+
not measured capture scale. It does not transfer donor face geometry.
|
|
48
|
+
|
|
49
|
+
After reviewing the dense semantic bake:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
python scripts/character_build.py --workspace /path/to/assets --id CHARACTER \
|
|
53
|
+
--evidence evidence/CHARACTER --masks masks/CHARACTER
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This preserves source geometry and writes mixed skin/hair/lip/nail materials plus the
|
|
57
|
+
registered detail binding. The adapter currently requires one source mesh primitive,
|
|
58
|
+
embedded textures, normals and non-overlapping anatomical UV ownership. It fails unsupported
|
|
59
|
+
layouts rather than flattening them automatically. Multiple-material adapters remain work.
|
|
60
|
+
`--check` validates required input presence without building; full geometry/hash contracts
|
|
61
|
+
are checked by the exporters themselves. Neither check is visual acceptance.
|
|
62
|
+
|
|
63
|
+
For eyes, first follow [the eye fitting workflow](eyes.md), then:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
python scripts/character_build.py --workspace /path/to/assets --id CHARACTER \
|
|
67
|
+
--stage eyes --eyes-profile profiles/CHARACTER-eyes.json
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The current optical texture adapter uses `blue_eye.png` and `LICENSE.md` from the CC0
|
|
71
|
+
MakeHuman eye reference in `highquality/references/makehuman-eyes/`. Its source registration
|
|
72
|
+
is specific to that donor atlas. Character opening contours, dimensions and fitting remain
|
|
73
|
+
individually authored. Existing skinned cut edges/full facial rigs are not supported by
|
|
74
|
+
this prototype; preserve them and use a suitable topology adapter.
|
|
75
|
+
|
|
76
|
+
For a previously validated body binding:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
python scripts/character_build.py --workspace /path/to/assets --id CHARACTER \
|
|
80
|
+
--stage assemble --input eyes/v1/character.glb --variant eyes
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The assembler consumes the existing bound mesh and `rig-report.json`, verifies the output
|
|
84
|
+
hash and negligible geometry displacement, then retains materials and eye layers while
|
|
85
|
+
adding the body skin. It does not invent bones, fit a skeleton or simulate cloth. The
|
|
86
|
+
playground's shared Blender rig fitting remains separate from this installed exporter.
|
|
87
|
+
Use the project's existing rigging workflow to produce compatible inputs.
|
|
88
|
+
|
|
89
|
+
A surfaces run can also take `--eyes-profile` and `--assemble` to execute the same stages
|
|
90
|
+
in order. Each stage stops on failure and leaves a review candidate, never `viewerReady`.
|
|
91
|
+
Review every changed region and both rendering backends before selecting a local preview.
|
|
92
|
+
|
|
93
|
+
## Detail-binding seams
|
|
94
|
+
|
|
95
|
+
Unused UV texels are not reliable vertex visibility samples at split seams. The exporter
|
|
96
|
+
uses exact source-geometry rays for those vertices, then samples the same reviewed image
|
|
97
|
+
annotations. It leaves occupied unknown/conflicted samples untouched and never changes
|
|
98
|
+
fragment coverage. Geometric caches include source, cameras, positions, normals and
|
|
99
|
+
algorithm version; annotation labels are re-read. Adjacent zero-weight triangle corners
|
|
100
|
+
still receive coherent patch coordinates so interpolation cannot sample another atlas
|
|
101
|
+
region. If an artifact persists, inspect coverage, geometry normals and source color
|
|
102
|
+
separately before changing skin strength.
|
|
103
|
+
|
|
104
|
+
Eye rest fitting retains `_BIND_SOURCE_POSITION` before moving source eyelid vertices.
|
|
105
|
+
The assembly exporter consumes this authoring attribute for weight correspondence and
|
|
106
|
+
removes it from the runtime attributes. Original vertices use their exact bound match;
|
|
107
|
+
clipped vertices use a verified rigid-head field or closest-triangle barycentric weights.
|
|
108
|
+
Points outside the bound surface tolerance fail rather than inheriting a nearby limb.
|
|
109
|
+
The rendered fitted positions and morphs retain their shape during this transfer.
|
|
110
|
+
|
|
111
|
+
Local preview selection now copies the exact reviewed GLB, render receipt, visual
|
|
112
|
+
verdict and inspected images into a content-addressed `.previews` snapshot beside
|
|
113
|
+
the candidate. An atomic `*.selected.json` pointer names that snapshot. Rebuilding
|
|
114
|
+
the candidate or its review images does not mutate the selected preview. A failed
|
|
115
|
+
review leaves the previous pointer intact. Engine consumers should resolve the
|
|
116
|
+
selected snapshot for ordinary preview and use explicit candidate paths for QA.
|
|
117
|
+
These snapshots remain local previews with recorded issues, not whole-character
|
|
118
|
+
acceptance or a publication step.
|
|
119
|
+
|
|
120
|
+
An explicitly authored `materials/geometry-repair-profile.json` can correct a local
|
|
121
|
+
source defect during the mixed surface build. Select the defect center and clean
|
|
122
|
+
support annulus from the exact evidence view; supply a bounded depth interval and
|
|
123
|
+
maximum displacement. The quadratic patch follows surrounding curvature and feathers
|
|
124
|
+
into unchanged geometry. Never infer that a painted marking should be removed:
|
|
125
|
+
record the user's intent and preserve the source. Optional clean skin color donors
|
|
126
|
+
and a painted dot replace the source's baked bump shading. Evidence UVs use Blender's
|
|
127
|
+
bottom-left convention; decoded texture rows use top-left. The exporter converts
|
|
128
|
+
this explicitly and pads only adjacent unused UV gutters.
|
|
129
|
+
|
|
130
|
+
The repair keeps topology, UVs and `_BIND_SOURCE_POSITION`; subsequent eye fitting
|
|
131
|
+
must preserve that attribute, and assembly uses it for the original rig weights.
|
|
132
|
+
Rebuild both eyes and runtime assemblies after a repair. Inspect front and oblique
|
|
133
|
+
views and both renderer backends before selecting the new snapshots. A displacement
|
|
134
|
+
receipt alone does not prove that old normal-map or pigment shading is gone.
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Optical eyes after reviewed ocular exclusions
|
|
2
|
+
|
|
3
|
+
This is an independent, opt-in asset revision. A working eye pilot does not certify the
|
|
4
|
+
skin maps or body rig. Preserve the source, material revision and existing animation.
|
|
5
|
+
The current adapter supports a single, unskinned source mesh and two eyes; it refuses
|
|
6
|
+
existing facial morphs and skinned cut edges. Do not silently flatten a rig to bypass it.
|
|
7
|
+
|
|
8
|
+
## Availability
|
|
9
|
+
|
|
10
|
+
The [installed exporter runner](exporters.md) now includes the optical-eye builder and
|
|
11
|
+
its dependencies. Supply an explicit workspace and independently authored fit; exemplar
|
|
12
|
+
textures remain external licensed inputs. The playground browser review harness is still
|
|
13
|
+
separate. Confirm the installed engine supports the optical-eye contract before adoption.
|
|
14
|
+
|
|
15
|
+
## Vision fit
|
|
16
|
+
|
|
17
|
+
Prepare exact close front and both oblique source views with `skin_views.py prepare`.
|
|
18
|
+
Use enough pixels to distinguish the iris, visible eye opening, inner corner and lids.
|
|
19
|
+
Record each iris center/radius, an ordered convex opening contour and the lower contour
|
|
20
|
+
indices on the original image. Record anatomical left/right explicitly; image orientation
|
|
21
|
+
is not a side label. Do not reuse another character's target pixels or eye centers.
|
|
22
|
+
|
|
23
|
+
Write a profile following `highquality/materials/eyes/b3843.json`. Source and evidence
|
|
24
|
+
hashes are mandatory. Globe radius, corneal bulge, pupil ratio, pigment and depth offset
|
|
25
|
+
are authored estimates in metres. Verify those estimates against side views and physical
|
|
26
|
+
character height. An opening wider than the globe requires corner tissue; moving the
|
|
27
|
+
eyeball forward until it fills the hole is not a valid substitute.
|
|
28
|
+
|
|
29
|
+
Run `python highquality/src/eye_assets.py --profile PROFILE`. The builder ray-fits each
|
|
30
|
+
eye against source geometry and writes `characters/ID/high/v1/eyes/v1/`. It clips openings
|
|
31
|
+
at the reviewed contour with barycentric attribute interpolation. It creates separate
|
|
32
|
+
sclera, recessed iris, pupil, cornea, orbital mucosa, lid contact and tear meniscus surfaces.
|
|
33
|
+
It adds actual eyelid position/normal morphs and gaze/blink clips. Inspect the closed lids:
|
|
34
|
+
the builder's deformation is a starting fit, not an anatomically validated universal rig.
|
|
35
|
+
|
|
36
|
+
## Shared rendering and control contract
|
|
37
|
+
|
|
38
|
+
- Eye nodes have `extras.characterEye=true` and `forwardAxis=+Z`; local +Y is up.
|
|
39
|
+
- `CharacterEyeController` applies local yaw/pitch relative to the authored rest fit and
|
|
40
|
+
drives `eyeBlinkLeft`/`eyeBlinkRight`. It never scales the eyeballs or changes body bones.
|
|
41
|
+
Give these channels one owner: either this controller or an AnimationMixer clip.
|
|
42
|
+
- Corneal transmission/IOR use standard glTF physical-material extensions on both backends.
|
|
43
|
+
Source ocular textures are not a replacement for a clear cornea and recessed iris.
|
|
44
|
+
- The MakeHuman eye source is CC0; retain its license, immutable source hash and adaptation
|
|
45
|
+
record. The current texture uses reviewed planar atlas registration and authored pigment.
|
|
46
|
+
It is not a captured iris of the generated character and has finite source resolution.
|
|
47
|
+
|
|
48
|
+
## Review gate
|
|
49
|
+
|
|
50
|
+
Use the viewer's **Optical eyes · fit preview** option; toggling must preserve the camera.
|
|
51
|
+
Inspect front, both three-quarter views and profile; then gaze in both directions, half
|
|
52
|
+
blink, independent winks and full closure. Play the exported clip as well as testing sliders.
|
|
53
|
+
Check upper-lid contact, inner/outer corners, tear edge, iris parallax, refraction, texture
|
|
54
|
+
orientation, eyeball penetration and closed-lid normals. Check WebGL and WebGPU.
|
|
55
|
+
|
|
56
|
+
`highquality/tests/eye_fit_smoke.mjs` exercises the local viewer and writes screenshots.
|
|
57
|
+
Read those images: zero renderer errors does not establish good optical fit. Keep
|
|
58
|
+
`optical_fit_review_required` until visual checks pass. Next production work includes
|
|
59
|
+
regional scleral scattering, richer iris relief, fitting across characters, refined lid shape and composition with a complete facial/body rig. Do not call this MetaHuman
|
|
60
|
+
parity based on the presence of corneal transmission alone.
|
|
61
|
+
|
|
62
|
+
## Separate source defects from optical defects
|
|
63
|
+
|
|
64
|
+
If a closed eyelid shows bright fragments, hide all generated optical layers temporarily.
|
|
65
|
+
If the fragments remain, inspect the original unlit face and material-region evidence.
|
|
66
|
+
Do not keep moving the eyeball to compensate for source albedo, normals or incorrect lid
|
|
67
|
+
labels. A bright painted streak and a geometric hole require different corrections.
|
|
68
|
+
|
|
69
|
+
A narrowly authored source-albedo defect can use a separate UV selection and
|
|
70
|
+
`texture_repair.py`: harmonic interpolation in linear light changes only selected texels,
|
|
71
|
+
with outside pixels byte-identical. Keep that selection separate from anatomical labels,
|
|
72
|
+
archive its projection evidence and inspect the repair. It does not reconstruct eyelid
|
|
73
|
+
geometry, lashes or missing detail. The djinn trial still requires eyelid surface work.
|
|
74
|
+
Eye profiles explicitly choose `skinRevision` so a later skin build cannot silently change
|
|
75
|
+
an already-reviewed eye fit. The current adapter accepts v2/v3/v4 and keeps output hashes.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
Orbital backing must remain behind the recessed iris and pupil at every blink and gaze angle. Do not reuse the corneal-envelope eyelid deformation for backing tissue: even a small inset can still place it ahead of the iris. Validate partial blinks and isolate optical layers when diagnosing occlusion. Current prototype keeps its dense backing head-fixed. Continue its recessed depth envelope beyond the globe at the canthi too; retaining source-surface depth outside the globe can leave a visible triangle ahead of the closing lid.
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
Before generating blink targets, inspect the neutral lid/globe intersection. The playground
|
|
82
|
+
can opt into `conformOpenLids` to push intersecting tissue outside the explicitly fitted
|
|
83
|
+
globe. This is geometry fitting around authored landmarks, not automatic anatomical
|
|
84
|
+
recognition. Do not pull the surrounding orbital skin inward merely to follow a sphere;
|
|
85
|
+
keep a smooth support band and stationary canthi. Inspect partial and full closure anew.
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
The playground now exports gaze-follow lid targets as well as blink targets. The engine
|
|
89
|
+
uses `eyeLidLookUpLeft/Right` and `eyeLidLookDownLeft/Right` at ±0.35 radians pitch;
|
|
90
|
+
full closure suppresses gaze follow independently for each eye. Inspect both directions,
|
|
91
|
+
partial blinks and winks. A controller test validates channel ownership, not the surface fit.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## Reconstructed lid bands (experimental playground option)
|
|
95
|
+
|
|
96
|
+
When the source eye margin is damaged, explicitly author a paired `outerLidPx` contour
|
|
97
|
+
around the existing `openingPx`. The outer contour must contain the aperture. The builder
|
|
98
|
+
ray-samples the original boundary and reconstructs only the intervening strip, preserving
|
|
99
|
+
its outer position/normal and following the fitted optical envelope at its inner edge.
|
|
100
|
+
This is designed topology and needs neutral, oblique, partial and full-blink inspection.
|
|
101
|
+
It does not recover missing anatomy automatically.
|
|
102
|
+
|
|
103
|
+
Source albedo can contain painted eye shadows or highlights. Stretching those into a
|
|
104
|
+
closed lid is a source-color defect. Optional `lidSkinSamplesPx` records at least three
|
|
105
|
+
explicitly reviewed clean skin donors in the same exact evidence view. Their linear colors
|
|
106
|
+
supply invented inner-lid pigment, blended to the sampled outer edge. Inspect the join;
|
|
107
|
+
never label this as scan-derived detail. The djinn trial still has outer-transition and
|
|
108
|
+
corner limitations. Keep this feature opt-in until its fit is acceptable.
|
|
109
|
+
|
|
110
|
+
For geometry diagnostics, hide cornea, sclera, iris, pupil, contact, tear and lashes, but
|
|
111
|
+
retain reconstructed `eyelid-skin`. Hiding that skin too produces an intentional hole and
|
|
112
|
+
invalidates the closure diagnostic. Inspect unlit albedo separately from geometry normals.
|
|
113
|
+
The playground regression now renders front, both obliques, profile, both yaw directions, and an oblique full blink. Eye review receipts must identify the exact selected output hash, including assembled
|
|
114
|
+
variants; a previous screenshot cannot validate an output rebuilt afterward.
|
|
115
|
+
|
|
116
|
+
## Authored brow strands (playground option)
|
|
117
|
+
|
|
118
|
+
A painted brow can retain its color but still lack visible strand depth. The optional
|
|
119
|
+
`browGroom` on each fitted eye accepts an independently reviewed `polygonPx`, at least
|
|
120
|
+
two `combGuidesPx` start/end pairs in that same exact view, `strandCount`, `seed`,
|
|
121
|
+
`radiusM`, `lengthRangeM` and `colorLinear`. The local `brow_groom.py` ray-projects roots
|
|
122
|
+
onto the nearest visible source surface and projects the authored comb directions into
|
|
123
|
+
its tangent plane. It constructs tapered short fibers; it performs no hair recognition.
|
|
124
|
+
Do not classify a dark supraorbital shadow as a brow without inspecting the source.
|
|
125
|
+
|
|
126
|
+
Record these as designed hairs, inspect both sides and profile, and preserve the underlying
|
|
127
|
+
source. The strands attach to the head; they do not yet follow expressive brow morphs.
|
|
128
|
+
Fine strands can alias without temporal antialiasing or a filtered hair LOD. This prototype
|
|
129
|
+
is not a replacement for a production groom/simulation system. The b5359 trial uses a
|
|
130
|
+
separate medial-corner tissue surface too; review its fit during closure independently.
|
|
131
|
+
A reconstructed lid-band trial on b5359 was rejected because its pale angular transition
|
|
132
|
+
looked worse. Do not assume that enabling every optional reconstruction improves a fit.
|
|
133
|
+
|
|
134
|
+
## Corner lining
|
|
135
|
+
|
|
136
|
+
A deep backing disk can leave a dark gap between the globe and the medial lid opening.
|
|
137
|
+
The optional `canthusWalls` profile lists explicit upper/corner/lower `contourIndices`
|
|
138
|
+
and a designed `colorLinear`. The narrow lining joins those reviewed source-lid points
|
|
139
|
+
to a recessed globe rim. Only the lid edge follows blink/gaze targets; the globe edge stays
|
|
140
|
+
fixed, outside the iris envelope over the reviewed ±0.35 radian gaze range. Do not apply
|
|
141
|
+
the corneal closure deformation to the whole socket. Inspect partial closure and both
|
|
142
|
+
obliques after fitting; source corners and dimensions differ between characters.
|
|
143
|
+
This is designed lining, not transferred scan anatomy. The CC0 MakeHuman topology was
|
|
144
|
+
visually inspected as an anatomical reference; no donor mesh is embedded by this option.
|
|
145
|
+
When a reconstructed lid band replaces the source margin, set its lining's
|
|
146
|
+
`contactMethod: "reconstructed-lid-v1"` to use the same aperture depth calculation.
|
|
147
|
+
Otherwise the lining can follow a removed source surface and protrude below the new
|
|
148
|
+
lid. This joins the support consistently; it does not supply a realistic caruncle or
|
|
149
|
+
make an oversized authored corner anatomical. Inspect those separately.
|
|
150
|
+
|
|
151
|
+
If a source has no separately classified ocular material, inspect the exact eye views
|
|
152
|
+
and explicitly set `openingAuthority: "reviewed-contours"`. The adapter then uses the
|
|
153
|
+
authored contours to remove the source surface. It still verifies source/image hashes
|
|
154
|
+
and rejects a cut that removes no interior triangles. Never infer the opening from
|
|
155
|
+
skin color or copy another character's contour; narrow hooded lids need their own fit.
|
|
156
|
+
|
|
157
|
+
Eyelid normal targets transport the imported shading normals with the shortest rotation
|
|
158
|
+
between the rest and deformed geometric normals. This preserves the imported normal's
|
|
159
|
+
angle to the surface while the lid moves. The neutral mesh retains its authored normals;
|
|
160
|
+
unused vertices keep their original normals. Inspect both the neutral and fully closed
|
|
161
|
+
pose after changing a fit, since valid normals cannot correct a poor anatomical shape.
|
|
162
|
+
|
|
163
|
+
Review each eye at eye-sized framing as well as face-sized framing. Inspect a neutral
|
|
164
|
+
eye and an oblique fully closed eye separately. A smooth globe can hide a polygonal
|
|
165
|
+
opening at face scale; a successful blink protocol does not establish anatomical quality.
|
|
166
|
+
In the playground, `CLOSE_EYES=1` adds these views and `REVIEW_SUFFIX` keeps experiments
|
|
167
|
+
separate. Use `SELECTED_EYES=1` to compare with the reviewed snapshot, rather than the
|
|
168
|
+
latest candidate. Explicitly unset `BACKEND` for a complete two-backend review.
|
|
169
|
+
|
|
170
|
+
An optional `contourRefinement` with `method: "convex-quadratic-v1"` and
|
|
171
|
+
`samplesPerLandmark: 8` rounds the segments between reviewed landmarks, staying inside
|
|
172
|
+
the original convex opening and preserving the two shared upper/lower eye corners.
|
|
173
|
+
For a reconstructed band, set `outerBoundary: "preserve-authored"` to retain every
|
|
174
|
+
segment of the reviewed outer source cut. Rounding that cut inward can leave pieces of
|
|
175
|
+
the damaged original eye margin behind. Paired outer points are then subdivided without
|
|
176
|
+
changing the cut; only the visible inner aperture is rounded. The older `rounded` outer
|
|
177
|
+
mode remains available for reproducibility, and requires its own review.
|
|
178
|
+
Indexed tissue chains are refined together. The fitted output
|
|
179
|
+
records the original points and maximum inset; it is safe to rebuild without applying
|
|
180
|
+
the refinement twice. This is a geometric interpolation of the agent's landmarks, not
|
|
181
|
+
an inferred anatomical contour. Inspect the result before selecting it: rounding alone
|
|
182
|
+
does not fix tissue depth, color, contact or deformation.
|
|
183
|
+
|
|
184
|
+
`outerEdgeSampling: "source-intersections-v1"` on an eye adds the original triangle-edge
|
|
185
|
+
crossings to the paired lid-band sampling. Its outer rim then follows the piecewise
|
|
186
|
+
source surface rather than bridging over small source ridges between uniform samples.
|
|
187
|
+
It preserves the authored cut and adds no anatomical selection. Keep checking the
|
|
188
|
+
closed pose: normal continuity and an actual eyelid fold need their own review.
|
|
189
|
+
|
|
190
|
+
If a designed `caruncle` is hidden behind an authored lining, its optional
|
|
191
|
+
`support: "corner-lining-v1"` positions it on the corresponding lining depth. It must
|
|
192
|
+
reference a corner in exactly one `canthusWalls` chain. The helper rejects centers
|
|
193
|
+
outside that lining's supported interval and rejects a tissue footprint that intersects
|
|
194
|
+
the iris envelope over the reviewed gaze range. Medial tissue may overlap peripheral
|
|
195
|
+
sclera; forcing it behind the entire sphere would hide it again and distort its shape.
|
|
196
|
+
The dimensions, placement and color remain explicit authored choices. This construction
|
|
197
|
+
is a prototype anatomical insert, not a scanned tear duct or a proof of eye realism.
|
|
198
|
+
|
|
199
|
+
For a reconstructed band that produces radial fan creases, `fairLidDepth: true`
|
|
200
|
+
uses harmonic depth fairing across the whole projected strip mesh. Both authored
|
|
201
|
+
rims remain fixed; projected columns interpolate the paired contours directly,
|
|
202
|
+
preventing independent Hermite tangents from bunching them at the canthi. The
|
|
203
|
+
result is refitted outside the optical envelope before computing normals and
|
|
204
|
+
blink targets. This is geometry repair, not a wrinkle texture filter. It does not
|
|
205
|
+
resolve an incorrect boundary shape or source pigment automatically. Inspect both
|
|
206
|
+
corners, neutral and full closure, obliques and gaze before selecting the asset.
|
|
207
|
+
|
|
208
|
+
A front silhouette alone cannot establish corner depth. `cornerDepths` optionally
|
|
209
|
+
records explicitly reviewed `pixel`, `depthM` (relative to the globe center, positive
|
|
210
|
+
forward), and `radiusM` for a corner. Local source support fades toward that depth;
|
|
211
|
+
the reconstructed lid and lining share a smooth tangent continuation from 85% of
|
|
212
|
+
the globe radius toward the corner. The curve stays outside the globe. Its angular
|
|
213
|
+
influence has a full-strength central half-width and smooth outer falloff. Inspect
|
|
214
|
+
both close lateral views (`SIDE_EYES=1`) and closure. Never assign these corrections
|
|
215
|
+
across characters without independently reviewing their actual depth and silhouette.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Applying reviewed skin maps
|
|
2
|
+
|
|
3
|
+
The projection helper creates evidence and labels. It does not generate a body rig or
|
|
4
|
+
reconstruct missing anatomical detail. Keep source models immutable and store character
|
|
5
|
+
work outside this shipped skill, because GDK upgrades refresh the skill files.
|
|
6
|
+
|
|
7
|
+
## Prepare the material revision
|
|
8
|
+
|
|
9
|
+
Use the project's existing character loader and material pipeline. In the Bitmagic engine,
|
|
10
|
+
read `agent-docs/character-surfaces.md` and use `RealisticCharacter.create(root, options)`
|
|
11
|
+
when that API is available. Do not assume a published engine version already contains it:
|
|
12
|
+
inspect the installed engine declarations first. Preserve working standard glTF materials
|
|
13
|
+
when the specialized adapter is unavailable and report that rendering integration remains.
|
|
14
|
+
Do not silently upgrade the engine or edit unrelated existing character types.
|
|
15
|
+
|
|
16
|
+
Author maps from licensed skin exemplars or the creator's own assets. Register the exemplar
|
|
17
|
+
to this character's reviewed facial landmarks and physical scale; never reuse another
|
|
18
|
+
character's target coordinates. Keep donor identity, tattoos, beard and complexion out of
|
|
19
|
+
relief transfer. Use anatomically appropriate detail for hands, palms, feet and body areas.
|
|
20
|
+
A generic repeated face tile is a preview fallback, not a finished regional detail library.
|
|
21
|
+
Retain attribution, source hashes, transformations and the authored physical amplitude.
|
|
22
|
+
For visible regional creases, the agent may author curves in exact evidence-image
|
|
23
|
+
coordinates and bake physically scaled relief onto independently labelled visible skin.
|
|
24
|
+
Record these as designed enhancements, not captured measurements. Keep glabrous palm
|
|
25
|
+
detail separate from facial follicles, and inspect the result at hand-sized framing.
|
|
26
|
+
The [regional detail helpers](regional-detail.md) evaluate authored crease curves and
|
|
27
|
+
licensed roughness patches without making anatomical decisions.
|
|
28
|
+
|
|
29
|
+
The source UV label map is top-left image data. Convert to the exporter/runtime's UV
|
|
30
|
+
convention exactly once. Bake source albedo as sRGB; roughness, metalness, masks, normals
|
|
31
|
+
and packed detail as linear data. Confirm with a known neutral patch and a source-material
|
|
32
|
+
comparison under identical lighting. A global saturation adjustment cannot diagnose a
|
|
33
|
+
color-space conversion bug.
|
|
34
|
+
|
|
35
|
+
## Specialized engine contract
|
|
36
|
+
|
|
37
|
+
Explicit material extras opt into the character adapter. Untagged materials remain native.
|
|
38
|
+
For mixed skin/clothing primitives, `skinSurfaceBlend: true` uses atlas alpha as per-pixel
|
|
39
|
+
skin coverage. The packed linear RGBA atlas stores signed height around .5, roughness,
|
|
40
|
+
chromatic residual around .5 and coverage. `skinAtlasHeightRangeM` sets physical height.
|
|
41
|
+
`skinAtlasTexture` and optional `skinExpressionTexture` refer to embedded glTF texture
|
|
42
|
+
indices. `_FACE_UV` supplies atlas coordinates; `_FACE_WEIGHT` supplies coverage weighting.
|
|
43
|
+
`_SCATTER` is a fallback transmission attribute. Read the installed engine contract for
|
|
44
|
+
exact current fields rather than guessing their implementation.
|
|
45
|
+
|
|
46
|
+
Check physical texel density before increasing relief strength: a 4K full-body texture
|
|
47
|
+
can still sample the face at roughly half a millimetre per texel. In engines supporting
|
|
48
|
+
`skinFacialAtlasTexture`, retain the registered facial detail separately from body coverage.
|
|
49
|
+
The `skinFacialAtlasLayout: "detail-expression-halves-v1"` contract packs facial detail in
|
|
50
|
+
the left half and facial expression in the right half of one linear texture; its detail
|
|
51
|
+
height uses the same physical range as the body atlas. `_FACIAL_DETAIL` packs independently registered UV in XY and geometry-verified projection
|
|
52
|
+
visibility in Z, retaining the WebGPU vertex-buffer budget on skinned meshes.
|
|
53
|
+
This layer replaces facial detail baked into the body atlas, not skin coverage. Body
|
|
54
|
+
expression must be neutral for this layout. Packing replaces its shader sampler rather
|
|
55
|
+
than adding samplers beyond WebGL's budget. Compare the actual backends, preserve physical
|
|
56
|
+
filter widths when changing resolution, and check that coverage remains byte-identical.
|
|
57
|
+
|
|
58
|
+
The same packed texture can reserve additional rows for independently reviewed body
|
|
59
|
+
patches while keeping the original face texels. `skinFacialAtlasRegion` then records the
|
|
60
|
+
face rectangle within the detail half, and each vertex's `_FACIAL_DETAIL` coordinates
|
|
61
|
+
already address its assigned region. Reconstructed eyelids must use that rectangle too.
|
|
62
|
+
Keep patch alpha as detail blending only: the body atlas still owns skin coverage. This
|
|
63
|
+
retains the sampler and vertex-buffer budget instead of adding one material per patch.
|
|
64
|
+
|
|
65
|
+
Resolve embedded textures through the engine GLTF loader parser. Keep the scene diffusion
|
|
66
|
+
and transmission passes and the body AnimationMixer caller-owned. The adapter exposes
|
|
67
|
+
independent eye controls, preserves source materials on disposal, and does not create a
|
|
68
|
+
missing skeleton. Keep specular reflection outside diffuse scattering. A blurred beauty
|
|
69
|
+
image is not subsurface diffusion. Author channel diffusion ratios in asset metadata;
|
|
70
|
+
never infer skin type from character ID, race, height or RGB thresholds.
|
|
71
|
+
|
|
72
|
+
At a known skin/hair/lip boundary, material weights must sum to one; independent fades
|
|
73
|
+
expose the native response as a glossy line. Fill filtering gutters in UNUSED UV atlas
|
|
74
|
+
space from the nearest occupied texel, but never grow labels into unseen surface regions.
|
|
75
|
+
Check the actual zero-coverage and full-coverage endpoints against the native and skin
|
|
76
|
+
materials. Preserve armor, cloth, hair and optical surfaces during skin changes.
|
|
77
|
+
|
|
78
|
+
## Source defects and acceptance
|
|
79
|
+
|
|
80
|
+
Separate source pigment spill, baked lighting, UV seams, normal errors, geometric creases
|
|
81
|
+
and missing coverage. Inspect unlit source, material labels and shaded results independently.
|
|
82
|
+
Color repair needs a separate authored selection. When a defect crosses UV islands, use
|
|
83
|
+
reviewed clean swatches in surface space; atlas-space harmonic fill may retain contaminated
|
|
84
|
+
island boundaries. A color repair cannot reconstruct missing hand geometry or eyelids.
|
|
85
|
+
|
|
86
|
+
Review all exposed regions and fixed-camera detail on both supported rendering backends.
|
|
87
|
+
Store region verdicts, current output hashes and review images beside the character. A
|
|
88
|
+
successful export or low conflict count is not visual acceptance. Keep incomplete regions
|
|
89
|
+
explicit and continue gathering views or authoring detail rather than calling a face-only
|
|
90
|
+
pass a complete character.
|
|
91
|
+
|
|
92
|
+
When a project uses the `viewerReady` metadata convention, `scripts/select_preview.py`
|
|
93
|
+
can validate the mechanical handoff. Supply `--asset`, `--metadata`, `--render-report`
|
|
94
|
+
and `--visual-verdict`. The render report is an array containing both `webgl` and
|
|
95
|
+
`webgpu` receipts with matching `actual`, empty `errors`, and the current `outputSha256`.
|
|
96
|
+
For combined runtime reports use `--variant eyes` or `--variant surfaces` to read
|
|
97
|
+
`assetHashes` instead. The agent-written verdict must identify the same output hash,
|
|
98
|
+
use `status: "local_preview_with_known_issues"` and `wholeCharacterAccepted: false`,
|
|
99
|
+
and list actually inspected images as `visuallyInspected: [{file, sha256}]`, relative
|
|
100
|
+
to that verdict. The helper checks current image bytes before selecting the preview.
|
|
101
|
+
It does not inspect those images, publish an asset, or declare the character finished.
|
|
102
|
+
|
|
103
|
+
Use the [installed exporters](exporters.md) to build these authored inputs into GLBs.
|
|
104
|
+
[The playground example](playground.md) records the tested asset layout and review harness;
|
|
105
|
+
its browser review commands still require that separate checkout.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
### Regional height composition
|
|
109
|
+
|
|
110
|
+
Independently registered body patches may declare `skinRegionalAtlasHeightMode: "additive-v1"` with `skinFacialAtlasRegion: [0, 0, 1, faceEndV]`, where `0 < faceEndV < 1`. The face occupies the atlas's top rows; body patches occupy rows below it. In those body rows, patch relief adds to the underlying body height rather than replacing authored palm creases or other regional folds. Facial relief retains replacement behavior, and body coverage is unchanged. Roughness still blends to the authored patch value. Assets without this explicit mode retain their previous replacement behavior.
|
|
111
|
+
|
|
112
|
+
This uses the existing packed texture and VEC3 binding on WebGL and WebGPU; it adds no sampler or vertex attribute. Do not compensate for erased crease layers by increasing microdetail strength. Check the composition with the patch enabled and disabled at the same camera, and retain the physical amplitude of each layer.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
Regional bindings need coherent UV coordinates at every corner of a triangle touching the patch, including corners with zero detail weight. A zero-weight corner still participates in UV interpolation. Leaving its old facial coordinates in place can make the triangle sample unrelated atlas texels. Extend coordinate support by adjacent triangles while keeping their detail weight zero and semantic coverage unchanged; reject overlapping active patch bindings or split the geometry explicitly.
|