From c27ff44d96945d61d873435bfcd253015a703fb2 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Wed, 18 Mar 2026 01:21:30 +0100 Subject: [PATCH] docs(skills): document Trellis API params and Godot import settings Full parameter reference for image_to_3d (9 params) and extract_glb (3 params) with failure mode table. Added Godot embedded_image_handling guidance and input requirements for concept images. Fix Blender export_image_format from 'PNG' to 'AUTO' (Blender 5.0 removed PNG as a valid option). Co-Authored-By: Claude Opus 4.6 --- .claude/skills/glb-gen/SKILL.md | 94 ++++++++++++++++--- .../skills/glb-gen/scripts/postprocess_glb.py | 2 +- 2 files changed, 82 insertions(+), 14 deletions(-) diff --git a/.claude/skills/glb-gen/SKILL.md b/.claude/skills/glb-gen/SKILL.md index 0f9f08071..d971c6a45 100644 --- a/.claude/skills/glb-gen/SKILL.md +++ b/.claude/skills/glb-gen/SKILL.md @@ -39,6 +39,57 @@ python3 tooling/db/trellis_connector.py generate input.png \ | `--seed` | 0 | Random seed for reproducibility | | `--timeout` | 600 | Max wait seconds | +## Batch Usage + +For multiple models, use the batch script: + +```bash +bash tooling/trellis-batch.sh +``` + +The batch script runs one model at a time with 15s cooldown between jobs, +retries up to 3 times on failure, and skips already-generated GLBs. + +**Never run Trellis jobs in parallel** — it uses the full GPU and concurrent +jobs will OOM and corrupt the CUDA state. + +## Trellis API Reference + +The connector talks to a Gradio API. The parameter layout is fragile — document +changes here when the container is updated. + +### /image_to_3d — 9 inputs + +| Pos | Name | Type | Value | +|-----|------|------|-------| +| 0 | image | Image | preprocessed image from /preprocess_image_1 | +| 1 | multiimages | Gallery | `[]` for single-image mode | +| 2 | is_multiimage | State | `False` for single-image (**not a session — it's a boolean flag**) | +| 3 | seed | Slider | int, 0-2147483647 | +| 4 | ss_guidance | Slider | float, default 7.5 | +| 5 | ss_steps | Slider | int, default 12 | +| 6 | slat_guidance | Slider | float, default 3.0 | +| 7 | slat_steps | Slider | int, default 12 | +| 8 | multiimage_algo | Radio | `"stochastic"` or `"multidiffusion"` | + +### /extract_glb — 3 inputs + +| Pos | Name | Type | Value | +|-----|------|------|-------| +| 0 | output_buf | State | `None` — server uses internal state from image_to_3d | +| 1 | simplify | Slider | float, mesh simplification ratio (default 0.95) | +| 2 | texture_size | Slider | int, texture resolution (default 1024) | + +### Common Failure Modes + +| Error | Cause | Fix | +|-------|-------|-----| +| "needed 9, got 8" on image_to_3d | Missing `is_multiimage` at position 2 | Pass `False` | +| "needed 3, got 2" on extract_glb | Missing `output_buf` at position 0 | Pass `None` | +| `'float' cannot be interpreted as int` | numpy rejects float for linspace steps | Patch `flow_euler.py` on server: `int(steps)` | +| CUDA device mismatch / invalid argument | GPU state corrupted after crash | Restart the Trellis container | +| Repeated 500 after restart | Previous crash left tensors on wrong device | Full container restart (not just API restart) | + ## Intermediate and Output Directories All intermediates go to `.tmp/` in the project root (gitignored, findable). @@ -48,29 +99,35 @@ Use deep nesting by pipeline stage, asset category, and subcategory: .tmp/ image-gen/ ← concept images (from /image-gen) furniture/tables/baroque_table_concept.png - characters/body/slim_body_concept.png + characters/bodies/slim_m.png glb-gen/ ← raw Trellis output furniture/tables/baroque_table.glb - characters/body/slim_body.glb + characters/bodies/slim_m.glb glb-gen/postproc/ ← Blender post-processed furniture/tables/baroque_table.glb - characters/body/slim_body.glb + characters/bodies/slim_m.glb ``` Always mirror the category/subcategory path across stages so you can trace `image-gen/furniture/tables/foo_concept.png` → `glb-gen/furniture/tables/foo.glb`. -Final game-ready assets are copied to `client-tmp/models/[category]/` for -spike testing, or to `client/assets/models/` when ready for production. +Final game-ready assets are copied to `spikes/3dpipeline/models/` for spike +testing, or to `client/assets/models/` when ready for production. -## Post-process in Blender (optional) +## Post-process in Blender -Reassign materials to game standard names, adjust scale: +Normalize scale, center, generate recolor mask, adjust materials: + +```bash +.claude/skills/glb-gen/scripts/postprocess input.glb [output.glb] [--target-width 1.0] [--color-threshold 0.25] +``` + +Or directly: ```bash flatpak run org.blender.Blender --background \ --python .claude/skills/glb-gen/scripts/postprocess_glb.py \ - -- input.glb output.glb [--scale FACTOR] + -- input.glb output.glb [--target-width N] [--color-threshold N] ``` ## Input Requirements @@ -78,16 +135,27 @@ flatpak run org.blender.Blender --background \ For best Trellis results: - Square image (1:1), PNG format - Plain dark background, single object centered -- Near-white/light base color +- Near-white/light base colors (engine applies final color via recolor shader) - No text, labels, or watermarks +- 3/4 front view at eye level gives Trellis the most information +- **Do NOT force isometric angle** — Trellis reconstructs full 3D, the game camera handles the view +- Use a style anchor image (`--input`) to maintain consistency across batches These match `/image-gen` output with the Settled Reach style guide. -## Batch Usage +## Godot Import Settings -Each `trellis_connector.py generate` call is independent. Run sequentially -(Trellis uses GPU — one job at a time) or queue them. Each call is non-blocking -relative to other skills. +**Critical:** Godot must use `gltf/embedded_image_handling=3` (embed uncompressed) +for Trellis GLBs. Other values cause texture loss: + +| Value | Mode | Result | +|-------|------|--------| +| 0 | Discard | No textures at all | +| 1 | Extract | **Silently fails** — null texture references | +| 2 | Embed Basis Universal | Compressed, may lose quality | +| 3 | Embed uncompressed | **Correct** — textures preserved | + +Set in `project.godot` under `[gltf]` so new imports pick it up automatically. ## Material Convention diff --git a/.claude/skills/glb-gen/scripts/postprocess_glb.py b/.claude/skills/glb-gen/scripts/postprocess_glb.py index d21f8f16f..a238e930d 100644 --- a/.claude/skills/glb-gen/scripts/postprocess_glb.py +++ b/.claude/skills/glb-gen/scripts/postprocess_glb.py @@ -332,7 +332,7 @@ def export_glb(filepath): use_selection=False, export_apply=True, export_materials='EXPORT', - export_image_format='PNG', + export_image_format='AUTO', ) size = os.path.getsize(filepath)