# Visual Asset Generator

> Executes AI visual asset generation using prompts from visual-asset-prompt-generator. Calls fal.ai (Nano Banana/Flux 1.1 Pro) for images and Hunyuan3D (via Blender MCP or HuggingFace) for 3D models. Handles async polling and asset post-processing. Use when this capability is needed.

- Skill: `tomevault-io/visual-asset-generator` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/visual-asset-generator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/visual-asset-generator/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/visual-asset-generator

---


# Visual Asset Generator

Takes structured prompts from visual-asset-prompt-generator and generates actual visual assets via AI APIs. Manages async 3D generation, image downloads, and asset organization.

## When to Use

- After visual-asset-prompt-generator has produced prompts JSON
- User says "generate the images", "create the 3D models", "run the asset pipeline"
- As Step 2 of the brand-visual-pipeline

## Input Variables

- `[BRAND_NAME]` — Brand name (for directory paths)
- `[PROMPTS_FILE]` — Path to prompts JSON from Skill 1 (default: `brands/{BRAND_NAME}/visual-prompts.json`)
- `[OUTPUT_DIR]` — Asset output directory (default: `assets/{BRAND_NAME}/`)

## Required Environment

```bash
FAL_KEY=xxx          # fal.ai API key (for Nano Banana / Flux)
HF_TOKEN=hf_xxx     # HuggingFace Pro token (for Hunyuan3D fallback)
```

## The Protocol

### Phase 1: Load Prompts

Read the prompts JSON generated by visual-asset-prompt-generator. Group by service:
- `fal-flux` prompts → fal.ai pipeline
- `hunyuan3d` prompts → Blender MCP or HuggingFace pipeline
- `polyhaven` prompts → Blender MCP PolyHaven search

### Phase 2: Image Generation via fal.ai

Use `scripts/fal_client.py` for each image prompt:

```bash
python scripts/fal_client.py \
  --prompt "the generation prompt" \
  --negative-prompt "things to avoid" \
  --width 1920 --height 1080 \
  --guidance-scale 7.5 \
  --steps 50 \
  --output "assets/{brand}/images/hero-shots/{asset_id}.png"
```

**fal.ai API Pattern:**
```python
import fal_client

# For Flux 1.1 Pro (high quality)
result = fal_client.subscribe(
    "fal-ai/flux-pro/v1.1",
    arguments={
        "prompt": prompt_text,
        "image_size": {"width": width, "height": height},
        "num_inference_steps": steps,
        "guidance_scale": guidance_scale,
        "safety_tolerance": "2"
    }
)
image_url = result["images"][0]["url"]

# For Nano Banana (image cleanup/enhancement)
result = fal_client.subscribe(
    "fal-ai/nano-banana",
    arguments={
        "prompt": prompt_text,
        "image_url": input_image_url,  # if enhancing existing image
        "image_size": {"width": width, "height": height}
    }
)
```

**Post-processing for each generated image:**
1. Download from result URL
2. Save as PNG to `assets/{brand}/images/{type}/{asset_id}.png`
3. Convert to WebP for web use
4. Generate 800px and 400px thumbnails

### Phase 3: 3D Model Generation via Hunyuan3D

**Option A: fal.ai (preferred — no Blender required)**

Use `scripts/fal_3d_client.py` for each 3D prompt:

```bash
# Text-to-3D
python scripts/fal_3d_client.py \
  --mode text-to-3d \
  --prompt "the 3D generation prompt" \
  --enable-pbr \
  --face-count 100000 \
  --output "assets/{brand}/3d-models/{asset_id}/"

# Image-to-3D (from generated product image)
python scripts/fal_3d_client.py \
  --mode image-to-3d \
  --image-url "https://fal.media/files/..." \
  --output "assets/{brand}/3d-models/{asset_id}/"
```

Output: GLB + OBJ + preview.png in the output directory.

**Option B: Blender MCP (when Blender is running)**

```python
# Step 1: Check availability
status = mcp__blender__get_hunyuan3d_status(user_prompt="Generate 3D for {brand}")

# Step 2: Generate model
result = mcp__blender__generate_hunyuan3d_model(
    text_prompt=prompt_data["prompt"],
    user_prompt="Generate 3D model for {brand}"
)
# Returns: {"job_id": "job_xxx"}

# Step 3: Poll for completion (30-second intervals)
while True:
    status = mcp__blender__poll_hunyuan_job_status(job_id=job_id)
    if status["status"] == "DONE":
        zip_url = status["ResultFile3Ds"]
        break
    elif status["status"] in ["FAILED", "CANCELED"]:
        # Fall back to Option B
        break
    # Wait 30 seconds between polls

# Step 4: Import into Blender
mcp__blender__import_generated_asset_hunyuan(
    name=f"{brand}_{asset_id}",
    zip_file_url=zip_url
)

# Step 5: Capture viewport render
mcp__blender__get_viewport_screenshot(max_size=1920, user_prompt="Render {brand} model")

# Step 6: Export GLB
mcp__blender__execute_blender_code(
    code=f"""
import bpy
bpy.ops.export_scene.gltf(
    filepath='{output_dir}/3d-models/{asset_id}/model.glb',
    export_format='GLB'
)
""",
    user_prompt="Export model"
)
```

**Option C: HuggingFace API (fallback when fal.ai and Blender are unavailable)**

Use `scripts/hunyuan_generate.py`:

```bash
python scripts/hunyuan_generate.py \
  --prompt "the 3D generation prompt" \
  --output "assets/{brand}/3d-models/{asset_id}/"
```

### Phase 4: Texture Search via PolyHaven

For texture prompts:
```python
results = mcp__blender__search_polyhaven_assets(
    asset_type="textures",
    categories=prompt_data["categories"],
    user_prompt="Find textures for {brand}"
)

mcp__blender__download_polyhaven_asset(
    asset_id=chosen_id,
    asset_type="textures",
    resolution="4k",
    user_prompt="Download texture"
)
```

### Phase 5: Generate Asset Manifest

Create `assets/{BRAND_NAME}/manifest.json`:

```json
{
  "brand": "[BRAND_NAME]",
  "generated_at": "ISO_DATE",
  "assets": [
    {
      "asset_id": "hero-001",
      "type": "hero-image",
      "service": "fal-flux",
      "status": "completed",
      "files": {
        "primary": "images/hero-shots/hero-001.png",
        "webp": "images/hero-shots/hero-001.webp",
        "thumb_800": "images/hero-shots/hero-001-800.png",
        "thumb_400": "images/hero-shots/hero-001-400.png"
      },
      "dimensions": { "width": 1920, "height": 1080 },
      "prompt_used": "the prompt that was used",
      "generation_params": { ... }
    },
    {
      "asset_id": "model-001",
      "type": "3d-model",
      "service": "hunyuan3d",
      "status": "completed",
      "files": {
        "glb": "3d-models/model-001/model.glb",
        "render": "3d-models/model-001/render.png"
      },
      "job_id": "job_xxx"
    }
  ]
}
```

## Error Handling

| Error | Action |
|-------|--------|
| fal.ai 401 | Check FAL_KEY env var, report to user |
| fal.ai 429 | Retry with exponential backoff (max 3 retries) |
| Hunyuan3D timeout (>10 min) | Fall back to HF API or report |
| Blender not connected | Use HF API fallback |
| Image download fails | Retry once, then skip with warning |

## Scripts

### `scripts/fal_client.py`
fal.ai API client for Flux 1.1 Pro and Nano Banana image generation.

### `scripts/fal_3d_client.py`
fal.ai 3D model generation client. Supports four modes:

```bash
# Text to 3D (Hunyuan3D V3) — $0.375/gen, ~2 min, PBR materials
python scripts/fal_3d_client.py --mode text-to-3d --prompt "a leather journal" --output ./output/

# Image to 3D (Hunyuan3D V3) — $0.375/gen, ~2 min
python scripts/fal_3d_client.py --mode image-to-3d --image-url "https://..." --output ./output/

# Image to 3D (TripoSR) — $0.07/gen, <1s, lower quality
python scripts/fal_3d_client.py --mode triposr --image-url "https://..." --output ./output/

# Image to 3D (Hunyuan3D V2) — $0.16/gen
python scripts/fal_3d_client.py --mode hunyuan-v2 --image-url "https://..." --output ./output/
```

**Hunyuan3D V3 extra options:**
- `--enable-pbr` — PBR materials (default: true)
- `--face-count 100000` — Target polygon count
- `--generate-type Normal|LowPoly|Geometry`

**Output:** GLB, OBJ, and preview PNG files in the specified output directory.

### `scripts/hunyuan_generate.py`
HuggingFace API client for Hunyuan3D when Blender MCP and fal.ai are unavailable.

## Integration

- **Upstream**: visual-asset-prompt-generator (consumes prompts JSON)
- **Downstream**: visual-asset-integrator (consumes asset manifest)
- **External APIs**: fal.ai, HuggingFace, Blender MCP
- **Part of**: brand-visual-pipeline orchestrator

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/sheshiyer) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-16 -->

