regenerate-3d Skill
Runtime: Asset generation steps use the vg generate CLI (FLUX.2 / GPT-Image-2 / Meshy v6 / Seedance / etc.); the final deliverable is a static HTML page with Three.js and the generated assets bundled in. Install with npm install -g vibedgames (or pnpm dogfood in this repo). The generation credentials live on the vibedgames server, so there is no per-machine setup. See the generate skill for the command reference — including its async-job recovery rule (keep the request_id, resume with status, never re-run after an ambiguous failure).
End-to-end recipe to ship a polished, multi-character 3D web experience using generative models.
This is the recipe that powers a cyberpunk character selector with 10 unique operatives, each with a matching companion creature, environment-themed floor texture, animated background and color palette.
What it builds
For each character you get:
- A stylized 3D character GLB (rigged + animated, baked into the file)
- A companion creature GLB (small static, themed to match the character)
- A per-character PBR floor (basecolor / normal / roughness / metalness, all generated)
- A looped video background keyed to the biome
- A 3-color palette that drives the whole UI (CSS custom properties)
- A portrait crop for the roster card
All packaged into a single static HTML page with a Three.js scene. ~25–35 MB of GLBs total after compression.
Pipeline
1. GPT-Image-2 → 1024x1536 character full-body T-pose (per character)
2. Meshy v6 → image-to-3d, enable_rigging=true, animation_action_id={chosen}
→ animated GLB (idle, dance, alert, etc.)
3. GPT-Image-2/edit → companion creature image, color-locked to character palette
4. Meshy v6 → image-to-3d, enable_rigging=false → static creature GLB
5. PATINA → fal-ai/patina/material/extract on the character image,
returns basecolor + normal + roughness + metalness for the floor
6. Seedance 2.0 → fal-ai/bytedance/seedance-2.0/fast/image-to-video, 8s loop
7. gltf-transform CLI → resize 1024 → webp q80 → draco
(typically 95–96% size reduction, ~400–800 KB final)
8. Three.js scene → MeshStandardMaterial floor with alphaMap circular cutout,
mirrored reflection (refl.y = root.y, scale.y = -1),
breathing animation on companions,
per-character palette via CSS custom properties (--c1/--c2/--c3),
per-character floor texture swap on character click,
transition lines + radial flash on swap
Riggable-character rules
Auto-rigging quality is decided at image-generation time. For any character
image headed into enable_rigging=true:
- Full-body T- or A-pose, front-facing, arms clearly away from the body,
legs separated, symmetric. Whole body in frame — head to feet, no cropped
limbs.
- No props, capes, tabards, or long skirts fused into the silhouette —
anything that merges limbs into the body confuses the auto-rigger. Give
weapons/props to the character afterward as separate meshes if needed.
- Verify the generated image actually shows the pose before spending on
the 3D step. Models drift toward action poses; a cool contrapposto shot
rigs badly. Regenerate with a stronger pose instruction rather than
rigging a bad pose.
- Body plan drives animation choice: the mesh's stance decides how
animation presets read. A quadruped walk on an upright dragon looks like a
human in a costume; an upright biped clip on a hunched creature warps.
Match the animation library entry to the stance you generated.
- Hard-surface armored designs (plate knights, mechs) auto-rig worse than
organic silhouettes — budget a retry or prefer visible-anatomy designs.
CREATE-YOUR-OWN flow
Visitors with generation credentials can generate their own character + companion live, in-browser:
flux-2 klein 9b (text-to-image)
└─ character full-body image
├─ Meshy v6 (rigged + animated) → character GLB
└─ flux-2 klein 9b/edit → companion image
└─ Meshy v6 (no rig) → companion GLB
Cost: ~$2–3 per generation (4 generation calls). Runs in background, modal closes on Generate so the user can keep using the experience while the gen runs. The CREATE YOUR OWN tile transforms into a loading state, then becomes the new character card with a ↻ re-create button.
Key endpoints used
| Step |
Endpoint |
| Character image (curated) |
openai/gpt-image-2 |
| Character image (live) |
fal-ai/flux-2/klein/9b |
| Companion image |
fal-ai/gpt-image-2/edit or fal-ai/flux-2/klein/9b/edit |
| 3D character/companion |
fal-ai/meshy/v6/image-to-3d |
| Per-character floor PBR |
fal-ai/patina/material/extract |
| Background video |
fal-ai/bytedance/seedance-2.0/fast/image-to-video |
| Logo / icon cleanup |
fal-ai/bria/background/remove |
Meshy animation IDs
Curated dance / idle action IDs (full list at https://docs.meshy.ai/en/api/animation-library):
| ID |
Animation |
| 0 |
Idle (default) |
| 2 |
Alert |
| 36 |
Confused (scratch) |
| 48 |
Mirror viewing |
| 64 |
All_Night_Dance |
| 405 |
Joyful_Dance_with_Hand_Sway |
| 591 |
Hip_Hop_Dance |
| 64–83 |
Various Pop_Dance variants |
Three.js scene notes
- Floor:
PlaneGeometry(7, 7, 220, 220) cut into a disc via radial-gradient alphaMap. High tessellation enables real displacementMap (uses basecolor as height).
- Reflection: clone of the root with
scale.y = -1, BackSide, depthWrite = false, renderOrder = -1. For characters whose origin is at the feet, refl.position.y = root.position.y produces a visible mirror; the floor's transparent = true; opacity ≈ 0.5 lets it bleed through.
- Breathing: per-frame
scale.setScalar(base * (1 + sin(t*1.3)*0.025)) + a small Y bob on companions. The reflection mirrors the bob so the mirror stays consistent.
- Palette swap:
:root.style.setProperty('--c1', hex) etc. Every UI element (sparklines, pulses, bars, model pills, edge map dots) derives its color from var(--c1) / var(--c2).
- Normalisation: Meshy vehicles/props come back facing ±X — yaw −π/2, scale by the length axis (not height), ground at y=0. Do it as a runtime
fit per skin, not a bake, so a regenerated model drops in unchanged. Compress with gltf-transform optimize in.glb out.glb --texture-compress webp --texture-size 1024. Budget ~$1/model.
- Floor swap:
texLoader.load() 4 PBR maps from assets/floor/{charId}/, dispose old textures, set floorMat.color back to white (since the basecolor is already char-themed).
- Transition: 9 diagonal lines sweep across the viewport (
@keyframes tfx-sweep) on character click + a radial flash; bg video crossfades between two <video> elements; character GLB slides out and the new one slides in.
Cost reference (curated build)
For one full character:
| Step |
Approx. cost |
| 1 GPT-Image-2 (character) |
$0.04 |
| 1 Meshy v6 rigged + animated |
$0.80 |
| 1 GPT-Image-2/edit (companion) |
$0.04 |
| 1 Meshy v6 static (companion) |
$0.20 |
| 1 PATINA floor (4 maps) |
$0.04 |
| 1 Seedance fast (bg video) |
$0.08 |
| Total per character |
~$1.20 |
| 10 characters |
~$12 |
Runtime parallelizes well, the original 10-character set was generated in ~10 minutes wall-clock with 9 concurrent jobs per stage.
1---2name: regenerate-3d3description: Build a 3D character-selector scene entirely from `vg generate` output: stylised characters, rigged GLBs, companions, floor textures, looped video backgrounds, palette swaps.4---56# regenerate-3d Skill78> **Runtime:** Asset generation steps use the `vg generate` CLI (FLUX.2 / GPT-Image-2 / Meshy v6 / Seedance / etc.); the final deliverable is a static HTML page with Three.js and the generated assets bundled in. Install with `npm install -g vibedgames` (or `pnpm dogfood` in this repo). The generation credentials live on the vibedgames server, so there is no per-machine setup. See the `generate` skill for the command reference — including its async-job recovery rule (keep the `request_id`, resume with `status`, never re-`run` after an ambiguous failure).910End-to-end recipe to ship a polished, multi-character 3D web experience using generative models.11This is the recipe that powers a cyberpunk character selector with 10 unique operatives, each with a matching companion creature, environment-themed floor texture, animated background and color palette.1213## What it builds1415For each character you get:1617- A **stylized 3D character GLB** (rigged + animated, baked into the file)18- A **companion creature GLB** (small static, themed to match the character)19- A **per-character PBR floor** (basecolor / normal / roughness / metalness, all generated)20- A **looped video background** keyed to the biome21- A **3-color palette** that drives the whole UI (CSS custom properties)22- A **portrait crop** for the roster card2324All packaged into a single static HTML page with a Three.js scene. ~25–35 MB of GLBs total after compression.2526## Pipeline2728```291. GPT-Image-2 → 1024x1536 character full-body T-pose (per character)302. Meshy v6 → image-to-3d, enable_rigging=true, animation_action_id={chosen}31 → animated GLB (idle, dance, alert, etc.)323. GPT-Image-2/edit → companion creature image, color-locked to character palette334. Meshy v6 → image-to-3d, enable_rigging=false → static creature GLB345. PATINA → fal-ai/patina/material/extract on the character image,35 returns basecolor + normal + roughness + metalness for the floor366. Seedance 2.0 → fal-ai/bytedance/seedance-2.0/fast/image-to-video, 8s loop377. gltf-transform CLI → resize 1024 → webp q80 → draco38 (typically 95–96% size reduction, ~400–800 KB final)398. Three.js scene → MeshStandardMaterial floor with alphaMap circular cutout,40 mirrored reflection (refl.y = root.y, scale.y = -1),41 breathing animation on companions,42 per-character palette via CSS custom properties (--c1/--c2/--c3),43 per-character floor texture swap on character click,44 transition lines + radial flash on swap45```4647## Riggable-character rules4849Auto-rigging quality is decided at image-generation time. For any character50image headed into `enable_rigging=true`:5152- **Full-body T- or A-pose**, front-facing, arms clearly away from the body,53 legs separated, symmetric. Whole body in frame — head to feet, no cropped54 limbs.55- **No props, capes, tabards, or long skirts fused into the silhouette** —56 anything that merges limbs into the body confuses the auto-rigger. Give57 weapons/props to the character afterward as separate meshes if needed.58- **Verify the generated image actually shows the pose** before spending on59 the 3D step. Models drift toward action poses; a cool contrapposto shot60 rigs badly. Regenerate with a stronger pose instruction rather than61 rigging a bad pose.62- **Body plan drives animation choice**: the mesh's stance decides how63 animation presets read. A quadruped walk on an upright dragon looks like a64 human in a costume; an upright biped clip on a hunched creature warps.65 Match the animation library entry to the stance you generated.66- Hard-surface armored designs (plate knights, mechs) auto-rig worse than67 organic silhouettes — budget a retry or prefer visible-anatomy designs.6869## CREATE-YOUR-OWN flow7071Visitors with generation credentials can generate their own character + companion live, in-browser:7273```74flux-2 klein 9b (text-to-image)75 └─ character full-body image76 ├─ Meshy v6 (rigged + animated) → character GLB77 └─ flux-2 klein 9b/edit → companion image78 └─ Meshy v6 (no rig) → companion GLB79```8081Cost: ~$2–3 per generation (4 generation calls). Runs in background, modal closes on Generate so the user can keep using the experience while the gen runs. The `CREATE YOUR OWN` tile transforms into a loading state, then becomes the new character card with a `↻ re-create` button.8283## Key endpoints used8485| Step | Endpoint |86| ------------------------- | ---------------------------------------------------------- |87| Character image (curated) | `openai/gpt-image-2` |88| Character image (live) | `fal-ai/flux-2/klein/9b` |89| Companion image | `fal-ai/gpt-image-2/edit` or `fal-ai/flux-2/klein/9b/edit` |90| 3D character/companion | `fal-ai/meshy/v6/image-to-3d` |91| Per-character floor PBR | `fal-ai/patina/material/extract` |92| Background video | `fal-ai/bytedance/seedance-2.0/fast/image-to-video` |93| Logo / icon cleanup | `fal-ai/bria/background/remove` |9495## Meshy animation IDs9697Curated dance / idle action IDs (full list at https://docs.meshy.ai/en/api/animation-library):9899| ID | Animation |100| ----- | --------------------------- |101| 0 | Idle (default) |102| 2 | Alert |103| 36 | Confused (scratch) |104| 48 | Mirror viewing |105| 64 | All_Night_Dance |106| 405 | Joyful_Dance_with_Hand_Sway |107| 591 | Hip_Hop_Dance |108| 64–83 | Various Pop_Dance variants |109110## Three.js scene notes111112- **Floor**: `PlaneGeometry(7, 7, 220, 220)` cut into a disc via radial-gradient `alphaMap`. High tessellation enables real `displacementMap` (uses basecolor as height).113- **Reflection**: clone of the root with `scale.y = -1`, `BackSide`, `depthWrite = false`, `renderOrder = -1`. For characters whose origin is at the feet, `refl.position.y = root.position.y` produces a visible mirror; the floor's `transparent = true; opacity ≈ 0.5` lets it bleed through.114- **Breathing**: per-frame `scale.setScalar(base * (1 + sin(t*1.3)*0.025))` + a small Y bob on companions. The reflection mirrors the bob so the mirror stays consistent.115- **Palette swap**: `:root.style.setProperty('--c1', hex)` etc. Every UI element (sparklines, pulses, bars, model pills, edge map dots) derives its color from `var(--c1)` / `var(--c2)`.116- **Normalisation**: Meshy vehicles/props come back facing ±X — yaw −π/2, scale by the length axis (not height), ground at y=0. Do it as a runtime `fit` per skin, not a bake, so a regenerated model drops in unchanged. Compress with `gltf-transform optimize in.glb out.glb --texture-compress webp --texture-size 1024`. Budget ~$1/model.117- **Floor swap**: `texLoader.load()` 4 PBR maps from `assets/floor/{charId}/`, dispose old textures, set `floorMat.color` back to white (since the basecolor is already char-themed).118- **Transition**: 9 diagonal lines sweep across the viewport (`@keyframes tfx-sweep`) on character click + a radial flash; bg video crossfades between two `<video>` elements; character GLB slides out and the new one slides in.119120## Cost reference (curated build)121122For one full character:123124| Step | Approx. cost |125| ------------------------------ | -----------: |126| 1 GPT-Image-2 (character) | $0.04 |127| 1 Meshy v6 rigged + animated | $0.80 |128| 1 GPT-Image-2/edit (companion) | $0.04 |129| 1 Meshy v6 static (companion) | $0.20 |130| 1 PATINA floor (4 maps) | $0.04 |131| 1 Seedance fast (bg video) | $0.08 |132| **Total per character** | **~$1.20** |133| **10 characters** | **~$12** |134135Runtime parallelizes well, the original 10-character set was generated in ~10 minutes wall-clock with 9 concurrent jobs per stage.