unirig — automatic 3D rigging (skeleton → skin → merge)
Keyword: unirig · auto-rigging · skeleton prediction · skinning weights
Only rig assets the user is licensed to modify. UniRig is MIT-licensed, but its checkpoints,
the Rig-XL/VRoid/Objaverse data, and the user's own models each carry their own terms.
UniRig is a two-stage autoregressive rigging framework: a GPT-like transformer predicts a
topologically valid skeleton from mesh geometry, then a bone-point cross-attention model
predicts per-vertex skinning weights. A third step merges the predicted rig back onto the
original (full-resolution, textured) asset.
The single most common failure is skipping the merge stage or merging the wrong file — see
Step 5. The second most common failure is an environment that silently lacks CUDA extensions.
When to use this skill
- The user wants a static 3D character/creature/prop turned into a rigged asset
- The user needs a skeleton only, or skin weights for a skeleton they already edited
- The user needs UniRig installed and verified on a CUDA machine, or wants to know up front that
their machine cannot run it
- The user wants to batch-rig a directory of models
- The user is choosing between UniRig, its successor SkinTokens, or classical/hosted riggers
- The user has a rigged output and wants to verify that joints and skin weights actually landed
Instructions
Step 1: Capture the intake packet and pick the stage
Collect four facts before running anything:
- Asset: file format (
.obj, .fbx/.FBX, .dae, .glb, .gltf, .vrm), poly count, single
model or directory, textured or not
- Goal: skeleton only, skin only, or a fully rigged deliverable
- Hardware: NVIDIA GPU + CUDA version, VRAM, OS (no CUDA ⇒ no inference; route out)
- Constraint: install budget (UniRig needs
spconv, flash_attn, torch_scatter,
torch_cluster, bpy), and whether hand-authored control over the skeleton is required
Routing rules:
- Static mesh, no skeleton yet → skeleton stage (
--stage skeleton)
- Skeleton exists (predicted or hand-edited) → skin stage (
--stage skin)
- Deliverable must keep the original geometry/materials → merge stage (
--stage merge)
- All three in one shot →
--stage all (the default of scripts/rig.sh)
- No CUDA GPU, or the user needs artist-controlled naming/IK/constraints → route out
(see references/route-outs-and-troubleshooting.md)
Step 2: Check the environment before installing anything
bash scripts/doctor.sh # human-readable readiness report
bash scripts/doctor.sh --json # machine-readable, for agent branching
doctor.sh reports Python 3.11, torch + CUDA availability, spconv, torch_scatter,
torch_cluster, flash_attn, bpy, trimesh, the UniRig checkout, its launch/inference
scripts, and Hugging Face reachability. It exits 1 when a blocking item is missing, so an
agent can stop before promising a rig that cannot run. Use --unirig-home <path> (or
UNIRIG_HOME) when the checkout is not at ~/.cache/unirig/UniRig.
Step 3: Install the skill and, when the machine qualifies, the upstream repo
npx skills add https://github.com/akillness/jeo-skills --skill unirig
bash scripts/install.sh --repo-only # clone/update UniRig only
bash scripts/install.sh --cuda cu121 # clone + create venv + install deps
bash scripts/install.sh --cuda cu121 --torch 2.4.0 --vrm
The installer is deliberately conservative:
- it never installs CUDA-only wheels on a machine without
nvidia-smi unless --force is passed;
spconv-<cuda> and the PyG wheel index are derived from --cuda/--torch, matching the upstream
README instead of guessing a single pinned wheel;
flash_attn is attempted last and a failure is reported, not swallowed — see the troubleshooting
reference for the source-build path;
--vrm additionally registers the bundled Blender VRM add-on.
Full dependency detail lives in
references/environment-and-install.md.
Step 4: Plan the run with a dry run, then execute
# print the exact upstream commands without executing them
bash scripts/rig.sh --input examples/giraffe.glb --output results/giraffe_rigged.glb --dry-run
# run the whole pipeline (skeleton → skin → merge)
bash scripts/rig.sh --input examples/giraffe.glb --output results/giraffe_rigged.glb
# one stage at a time
bash scripts/rig.sh --stage skeleton --input model.glb --output results/model_skeleton.fbx
bash scripts/rig.sh --stage skin --input results/model_skeleton.fbx --output results/model_skin.fbx
bash scripts/rig.sh --stage merge --source results/model_skin.fbx --target model.glb \
--output results/model_rigged.glb
# whole directory (skeleton and skin stages only — upstream merge takes one file pair)
bash scripts/rig.sh --stage skeleton --input-dir assets/ --output-dir results/skeletons/
rig.sh is a thin, honest wrapper over launch/inference/generate_skeleton.sh,
generate_skin.sh, and merge.sh: it validates the input suffix, derives intermediate
<input>_skeleton.fbx / <input>_skin.fbx paths next to the final output (override with
--skeleton-out / --skin-out), runs the stages in order from UNIRIG_HOME, and fails when an
expected artifact is missing instead of reporting a rig that was never written. --seed,
--faces-target-count, --num-runs, --add-root, --force-override, --skeleton-task, and
--skin-task are passed straight through to upstream with upstream's own defaults.
Step 5: Respect the two merge rules
- Merge the skin file, not the skeleton file.
merge.sh --source <skeleton>.fbx produces an
armature with no skinning weights. Use the *_skin.fbx output for a deliverable rig.
- Fix the skeleton before skinning. Skin quality collapses when bones are missing (tails,
wings, extra limbs). Hand-edit the predicted skeleton in Blender, then re-run
--stage skin
on the edited FBX. Different --seed values produce different skeleton proposals — cheap to
sample a few before committing.
Stage flags, defaults, config files, and the tmp/ npz cache are documented in
references/inference-pipeline.md.
Step 6: Verify the deliverable, do not assume it
python3 scripts/inspect_glb.py results/model_rigged.glb
python3 scripts/inspect_glb.py results/model_rigged.glb --json
inspect_glb.py is stdlib-only (no torch, no Blender): it parses the GLB/glTF JSON chunk and
reports meshes, nodes, skins, joint counts, animations, and whether any mesh primitive carries
JOINTS_0/WEIGHTS_0 attributes. It exits 1 when the file has no skin, which is exactly the
"merged the skeleton file by mistake" case. For FBX outputs, verify in Blender or with bpy
(see the troubleshooting reference) — FBX is binary and not parseable stdlib-only.
Step 7: Training and datasets (only when asked)
Training, Rig-XL/VRoid data layout, the raw_data.npz key schema, and the Rignet validation task
live in references/training-and-datasets.md. Do not start a
training run for a request that only needs inference — the published checkpoint is downloaded
automatically on first inference.
Examples
Example 1: "Rig this GLB character for me"
doctor.sh → rig.sh --dry-run to show the plan → rig.sh → inspect_glb.py to prove the
output has skins and joints.
Example 2: "The tail has no bones"
Do not re-run skinning on the bad skeleton. Re-sample with another --seed, or edit the skeleton
FBX in Blender, then run --stage skin on the edited file and re-merge.
Example 3: "I'm on a MacBook"
doctor.sh exits blocking. Say so plainly and route out to a CUDA machine/cloud GPU, the hosted
Tripo rigging service, or classical Mixamo/AccuRig/Rigify — do not pretend a CPU fallback exists.
Example 4: "Which is better, UniRig or SkinTokens?"
SkinTokens is the same lab's successor (unified autoregressive skin tokens, RL-trained, reported
98–133% skinning and 17–22% bone-prediction gains). Recommend it for new work; keep UniRig when
the user needs its released checkpoint, its Rig-XL tooling, or an already-working environment.
Checklist
- Capture the asset/goal/hardware/constraint packet before touching a shell.
- Run
doctor.sh first; report a blocking environment instead of installing blindly.
- Never install CUDA-only wheels on a machine without an NVIDIA GPU.
- Dry-run the pipeline and show the exact upstream commands before a long GPU run.
- Fix the skeleton before skinning; sample seeds when the topology looks wrong.
- Merge the
*_skin.fbx, never the *_skeleton.fbx, into the original asset.
- Verify the deliverable with
inspect_glb.py (GLB) or Blender (FBX) — never claim success from
a command exit code alone.
- Route out honestly to SkinTokens, hosted services, or classical riggers when UniRig is the
wrong tool.
References
- references/environment-and-install.md — Python 3.11,
torch/CUDA matrix,
spconv/PyG/flash_attn pitfalls, checkpoints, VRM add-on
- references/inference-pipeline.md — every upstream flag and
default for extract/skeleton/skin/merge, configs,
tmp/ npz cache
- references/training-and-datasets.md — Rig-XL/VRoid data,
raw_data.npz schema, config layering, training and Rignet validation tasks
- references/route-outs-and-troubleshooting.md —
when not to use UniRig, and the recurring install/runtime errors
- scripts/doctor.sh — readiness report (
--json, exits 1 when blocked)
- scripts/install.sh — skill plugin + upstream clone/venv/deps
- scripts/rig.sh — stage-aware wrapper with
--dry-run
- scripts/inspect_glb.py — stdlib GLB/glTF rig verifier
- UniRig repository ·
paper ·
checkpoint ·
SkinTokens successor
1---2name: unirig3description: Automatically rig 3D models with UniRig (VAST-AI-Research, SIGGRAPH'25) — predict a skeleton, predict skinning weights, and merge the rig back onto the original mesh. Use when the user wants auto-rigging for .obj/.fbx/.glb/.gltf/.dae/.vrm assets, a skeleton or skin weights for a character or creature, a UniRig environment prepared on a CUDA machine, batch rigging of a model directory, or an honest comparison between UniRig, SkinTokens, Tripo, Mixamo, AccuRig, and Blender Rigify. Triggers on: unirig, auto rig, auto-rigging, 3D rigging, skeleton prediction, skinning weights, rig a character, armature generation, rigged glb, rigged fbx, bone weights.4license: MIT5---67# unirig — automatic 3D rigging (skeleton → skin → merge)89> **Keyword**: `unirig` · `auto-rigging` · `skeleton prediction` · `skinning weights`10>11> Only rig assets the user is licensed to modify. UniRig is MIT-licensed, but its checkpoints,12> the Rig-XL/VRoid/Objaverse data, and the user's own models each carry their own terms.1314UniRig is a two-stage autoregressive rigging framework: a GPT-like transformer predicts a15topologically valid **skeleton** from mesh geometry, then a bone-point cross-attention model16predicts per-vertex **skinning weights**. A third step **merges** the predicted rig back onto the17original (full-resolution, textured) asset.1819The single most common failure is skipping the merge stage or merging the wrong file — see20Step 5. The second most common failure is an environment that silently lacks CUDA extensions.2122## When to use this skill2324- The user wants a static 3D character/creature/prop turned into a rigged asset25- The user needs a skeleton only, or skin weights for a skeleton they already edited26- The user needs UniRig installed and verified on a CUDA machine, or wants to know up front that27 their machine cannot run it28- The user wants to batch-rig a directory of models29- The user is choosing between UniRig, its successor SkinTokens, or classical/hosted riggers30- The user has a rigged output and wants to verify that joints and skin weights actually landed3132## Instructions3334### Step 1: Capture the intake packet and pick the stage3536Collect four facts before running anything:3738- **Asset**: file format (`.obj`, `.fbx`/`.FBX`, `.dae`, `.glb`, `.gltf`, `.vrm`), poly count, single39 model or directory, textured or not40- **Goal**: skeleton only, skin only, or a fully rigged deliverable41- **Hardware**: NVIDIA GPU + CUDA version, VRAM, OS (no CUDA ⇒ no inference; route out)42- **Constraint**: install budget (UniRig needs `spconv`, `flash_attn`, `torch_scatter`,43 `torch_cluster`, `bpy`), and whether hand-authored control over the skeleton is required4445Routing rules:46471. Static mesh, no skeleton yet → **skeleton stage** (`--stage skeleton`)482. Skeleton exists (predicted or hand-edited) → **skin stage** (`--stage skin`)493. Deliverable must keep the original geometry/materials → **merge stage** (`--stage merge`)504. All three in one shot → `--stage all` (the default of `scripts/rig.sh`)515. No CUDA GPU, or the user needs artist-controlled naming/IK/constraints → route out52 (see [references/route-outs-and-troubleshooting.md](references/route-outs-and-troubleshooting.md))5354### Step 2: Check the environment before installing anything5556```bash57bash scripts/doctor.sh # human-readable readiness report58bash scripts/doctor.sh --json # machine-readable, for agent branching59```6061`doctor.sh` reports Python 3.11, torch + CUDA availability, `spconv`, `torch_scatter`,62`torch_cluster`, `flash_attn`, `bpy`, `trimesh`, the UniRig checkout, its `launch/inference`63scripts, and Hugging Face reachability. It exits `1` when a **blocking** item is missing, so an64agent can stop before promising a rig that cannot run. Use `--unirig-home <path>` (or65`UNIRIG_HOME`) when the checkout is not at `~/.cache/unirig/UniRig`.6667### Step 3: Install the skill and, when the machine qualifies, the upstream repo6869```bash70npx skills add https://github.com/akillness/jeo-skills --skill unirig71```7273```bash74bash scripts/install.sh --repo-only # clone/update UniRig only75bash scripts/install.sh --cuda cu121 # clone + create venv + install deps76bash scripts/install.sh --cuda cu121 --torch 2.4.0 --vrm77```7879The installer is deliberately conservative:8081- it never installs CUDA-only wheels on a machine without `nvidia-smi` unless `--force` is passed;82- `spconv-<cuda>` and the PyG wheel index are derived from `--cuda`/`--torch`, matching the upstream83 README instead of guessing a single pinned wheel;84- `flash_attn` is attempted last and a failure is reported, not swallowed — see the troubleshooting85 reference for the source-build path;86- `--vrm` additionally registers the bundled Blender VRM add-on.8788Full dependency detail lives in89[references/environment-and-install.md](references/environment-and-install.md).9091### Step 4: Plan the run with a dry run, then execute9293```bash94# print the exact upstream commands without executing them95bash scripts/rig.sh --input examples/giraffe.glb --output results/giraffe_rigged.glb --dry-run9697# run the whole pipeline (skeleton → skin → merge)98bash scripts/rig.sh --input examples/giraffe.glb --output results/giraffe_rigged.glb99100# one stage at a time101bash scripts/rig.sh --stage skeleton --input model.glb --output results/model_skeleton.fbx102bash scripts/rig.sh --stage skin --input results/model_skeleton.fbx --output results/model_skin.fbx103bash scripts/rig.sh --stage merge --source results/model_skin.fbx --target model.glb \104 --output results/model_rigged.glb105106# whole directory (skeleton and skin stages only — upstream merge takes one file pair)107bash scripts/rig.sh --stage skeleton --input-dir assets/ --output-dir results/skeletons/108```109110`rig.sh` is a thin, honest wrapper over `launch/inference/generate_skeleton.sh`,111`generate_skin.sh`, and `merge.sh`: it validates the input suffix, derives intermediate112`<input>_skeleton.fbx` / `<input>_skin.fbx` paths next to the final output (override with113`--skeleton-out` / `--skin-out`), runs the stages in order from `UNIRIG_HOME`, and fails when an114expected artifact is missing instead of reporting a rig that was never written. `--seed`,115`--faces-target-count`, `--num-runs`, `--add-root`, `--force-override`, `--skeleton-task`, and116`--skin-task` are passed straight through to upstream with upstream's own defaults.117118### Step 5: Respect the two merge rules1191201. **Merge the skin file, not the skeleton file.** `merge.sh --source <skeleton>.fbx` produces an121 armature with **no skinning weights**. Use the `*_skin.fbx` output for a deliverable rig.1222. **Fix the skeleton before skinning.** Skin quality collapses when bones are missing (tails,123 wings, extra limbs). Hand-edit the predicted skeleton in Blender, then re-run `--stage skin`124 on the edited FBX. Different `--seed` values produce different skeleton proposals — cheap to125 sample a few before committing.126127Stage flags, defaults, config files, and the `tmp/` npz cache are documented in128[references/inference-pipeline.md](references/inference-pipeline.md).129130### Step 6: Verify the deliverable, do not assume it131132```bash133python3 scripts/inspect_glb.py results/model_rigged.glb134python3 scripts/inspect_glb.py results/model_rigged.glb --json135```136137`inspect_glb.py` is stdlib-only (no torch, no Blender): it parses the GLB/glTF JSON chunk and138reports meshes, nodes, `skins`, joint counts, animations, and whether any mesh primitive carries139`JOINTS_0`/`WEIGHTS_0` attributes. It exits `1` when the file has no skin, which is exactly the140"merged the skeleton file by mistake" case. For FBX outputs, verify in Blender or with `bpy`141(see the troubleshooting reference) — FBX is binary and not parseable stdlib-only.142143### Step 7: Training and datasets (only when asked)144145Training, Rig-XL/VRoid data layout, the `raw_data.npz` key schema, and the Rignet validation task146live in [references/training-and-datasets.md](references/training-and-datasets.md). Do not start a147training run for a request that only needs inference — the published checkpoint is downloaded148automatically on first inference.149150## Examples151152### Example 1: "Rig this GLB character for me"153`doctor.sh` → `rig.sh --dry-run` to show the plan → `rig.sh` → `inspect_glb.py` to prove the154output has skins and joints.155156### Example 2: "The tail has no bones"157Do not re-run skinning on the bad skeleton. Re-sample with another `--seed`, or edit the skeleton158FBX in Blender, then run `--stage skin` on the edited file and re-merge.159160### Example 3: "I'm on a MacBook"161`doctor.sh` exits blocking. Say so plainly and route out to a CUDA machine/cloud GPU, the hosted162Tripo rigging service, or classical Mixamo/AccuRig/Rigify — do not pretend a CPU fallback exists.163164### Example 4: "Which is better, UniRig or SkinTokens?"165SkinTokens is the same lab's successor (unified autoregressive skin tokens, RL-trained, reported16698–133% skinning and 17–22% bone-prediction gains). Recommend it for new work; keep UniRig when167the user needs its released checkpoint, its Rig-XL tooling, or an already-working environment.168169## Checklist1701711. Capture the asset/goal/hardware/constraint packet before touching a shell.1722. Run `doctor.sh` first; report a blocking environment instead of installing blindly.1733. Never install CUDA-only wheels on a machine without an NVIDIA GPU.1744. Dry-run the pipeline and show the exact upstream commands before a long GPU run.1755. Fix the skeleton before skinning; sample seeds when the topology looks wrong.1766. Merge the `*_skin.fbx`, never the `*_skeleton.fbx`, into the original asset.1777. Verify the deliverable with `inspect_glb.py` (GLB) or Blender (FBX) — never claim success from178 a command exit code alone.1798. Route out honestly to SkinTokens, hosted services, or classical riggers when UniRig is the180 wrong tool.181182## References183184- [references/environment-and-install.md](references/environment-and-install.md) — Python 3.11,185 torch/CUDA matrix, `spconv`/PyG/`flash_attn` pitfalls, checkpoints, VRM add-on186- [references/inference-pipeline.md](references/inference-pipeline.md) — every upstream flag and187 default for extract/skeleton/skin/merge, configs, `tmp/` npz cache188- [references/training-and-datasets.md](references/training-and-datasets.md) — Rig-XL/VRoid data,189 `raw_data.npz` schema, config layering, training and Rignet validation tasks190- [references/route-outs-and-troubleshooting.md](references/route-outs-and-troubleshooting.md) —191 when not to use UniRig, and the recurring install/runtime errors192- [scripts/doctor.sh](scripts/doctor.sh) — readiness report (`--json`, exits 1 when blocked)193- [scripts/install.sh](scripts/install.sh) — skill plugin + upstream clone/venv/deps194- [scripts/rig.sh](scripts/rig.sh) — stage-aware wrapper with `--dry-run`195- [scripts/inspect_glb.py](scripts/inspect_glb.py) — stdlib GLB/glTF rig verifier196- [UniRig repository](https://github.com/VAST-AI-Research/UniRig) ·197 [paper](https://arxiv.org/abs/2504.12451) ·198 [checkpoint](https://huggingface.co/VAST-AI/UniRig) ·199 [SkinTokens successor](https://github.com/VAST-AI-Research/SkinTokens)