blender

Drive Blender headlessly (no GUI) to process 3D game assets from Node/TS or the shell: convert FBX/OBJ/GLB/.blend to web-ready GLB, reduce polygon counts, best-effort auto-rig humanoid meshes with Rig

SKILL.md

GitHub

Blender headless asset pipeline

This skill turns the locally installed Blender 4.5 LTS into a programmable, GUI-free asset processor. Every operation is a single blender --background call running a Python (bpy) script. Nothing here opens a window, so it works over SSH / in WSL / from a Node.js child_process.

Install location (already set up)

  • Binary: ~/.local/bin/blender → ~/.local/opt/blender-4.5.10/blender
  • Bundled Python: 3.11, with the glTF importer/exporter and Rigify available.
  • Override the binary by exporting BLENDER_BIN before calling the wrapper.

If blender --version ever fails, re-run the install steps at the bottom of this file. Check the command's stderr first — Blender prints the real error there even when the Python layer looks fine.

The runner

All scripts go through scripts/blender_run.sh, which adds the right headless flags and forwards everything after -- to the Python script:

SKILL=~/.claude/skills/blender
$SKILL/scripts/blender_run.sh <script.py> -- --in INPUT --out OUTPUT [opts]

<script.py> may be a bare name (resolved against scripts/) or a path.

Operations

Convert anything to web-ready GLB (the default format — this game targets the browser, so Y-up binary glTF loads straight into three.js/babylon.js):

$SKILL/scripts/blender_run.sh convert.py -- --in meshy_export.fbx --out assets/unit.glb
# drop stray cameras/lights/empties, keep only meshes:
$SKILL/scripts/blender_run.sh convert.py -- --in raw.glb --out clean.glb --selected-meshes

Reduce polygons (generated meshes are usually far too dense for a game):

$SKILL/scripts/blender_run.sh decimate.py -- --in dense.glb --out lod.glb --ratio 0.25

Best-effort humanoid auto-rig with Rigify (see the honest limits in scripts/auto_rig.py — it gets you a riggable GLB fast but expects weight-paint touch-up, and only makes sense for upright humanoid meshes):

$SKILL/scripts/blender_run.sh auto_rig.py -- --in character.glb --out character_rigged.glb

Render a preview thumbnail so an agent can visually inspect an asset (Cycles on CPU; no GPU needed):

$SKILL/scripts/blender_run.sh render_preview.py -- --in unit.glb --out unit.png --size 512

Where Meshy AI fits

If you generate with Meshy AI, prefer Meshy's own rigging/animation and its GLB export — it is usually better than auto_rig.py. Use this skill for the steps Meshy does not do well: format normalization, decimation/LOD, merging, applying transforms, batch processing, retargeting, and producing previews. Typical flow:

Meshy API (Node/TS) → downloads model.glb
  → convert.py        (normalize, strip junk)   [if not already clean GLB]
  → decimate.py       (LOD for the web target)
  → render_preview.py (agent inspects result)
  → game/public/assets/

For pure JS post-processing that does not need Blender (Draco/meshopt compression, texture resize), @gltf-transform is lighter weight; reach for Blender when you need geometry edits, rigging, or animation.

Writing new operations

Add a script to scripts/ and import lib. lib.py provides get_args() (parses args after --), reset_scene(), import_model() (glb/gltf/fbx/obj/ stl/blend), export_glb(), select_meshes(), and ensure_addon(). See references/bpy-cookbook.md for common recipes (joining meshes, baking, applying transforms, batch loops, retargeting animation).

Reinstall (if the binary is missing)

curl -fSL -o /tmp/blender.tar.xz \
  https://download.blender.org/release/Blender4.5/blender-4.5.10-linux-x64.tar.xz
mkdir -p ~/.local/opt ~/.local/bin
tar -xJf /tmp/blender.tar.xz -C ~/.local/opt/
mv ~/.local/opt/blender-4.5.10-linux-x64 ~/.local/opt/blender-4.5.10
ln -sf ~/.local/opt/blender-4.5.10/blender ~/.local/bin/blender