Convert Figma logo to code with AI

VAST-AI-Research logoUniRig

[SIGGRAPH 2025] One Model to Rig Them All: Diverse Skeleton Rigging with UniRig

1,105
92
1,105
23

Top Related Projects

Code to accompany "A Method for Animating Children's Drawings of the Human Figure"

33,406

OpenPose: Real-time multi-person keypoint detection library for body, face, hands, and foot estimation

A real-time approach for mapping all human pixels of 2D RGB images to a 3D surface-based model of the body

1,194

[CVPR'23, Highlight] ECON: Explicit Clothed humans Optimized via Normal integration

2,441

SMPL-X

Quick Overview

UniRig is an open-source project by VAST AI Research that aims to provide a universal rigging system for 3D character animation. It offers a standardized approach to character rigging, making it easier for animators and developers to create and manipulate 3D characters across different platforms and software.

Pros

  • Standardized rigging system that can be used across multiple 3D software and game engines
  • Potentially reduces development time and improves workflow efficiency for 3D character animation
  • Open-source nature allows for community contributions and improvements
  • May simplify the process of character rigging for beginners and non-technical artists

Cons

  • May require adaptation of existing workflows and pipelines to fully utilize the system
  • Possible limitations in customization compared to traditional character-specific rigging
  • Could face compatibility issues with some specialized animation software or techniques
  • Adoption rate in the industry might be slow, potentially limiting its widespread use

Code Examples

As UniRig is primarily a 3D rigging system and not a traditional code library, there are no specific code examples to provide. The project likely involves 3D modeling files, rig setups, and possibly some scripting for various 3D software, but these are not typically represented in code blocks.

Getting Started

Since UniRig is a 3D rigging system rather than a code library, traditional getting started instructions with code snippets are not applicable. Users would likely need to:

  1. Download the UniRig files from the GitHub repository
  2. Import the rig into their preferred 3D software
  3. Apply the rig to their 3D character models
  4. Learn how to use the standardized controls for animation

For specific instructions, users should refer to the documentation provided in the GitHub repository, as the exact process may vary depending on the 3D software being used and the specific implementation of UniRig.

Competitor Comparisons

Code to accompany "A Method for Animating Children's Drawings of the Human Figure"

Pros of AnimatedDrawings

  • More established project with a larger community and more extensive documentation
  • Focuses specifically on animating 2D drawings, which may be more suitable for certain use cases
  • Includes a web-based interface for easier user interaction

Cons of AnimatedDrawings

  • Limited to 2D drawings, while UniRig supports both 2D and 3D character rigging
  • Less flexibility in terms of customization and integration with other workflows
  • May require more computational resources for complex animations

Code Comparison

AnimatedDrawings:

from animated_drawings import render
character = render.Character(char_cfg)
animation = render.Animation(motion_cfg)
render.render_animation(character, animation, output_path)

UniRig:

from unirig import Rig, Animator
rig = Rig.from_image("character.png")
animator = Animator(rig)
animator.animate("dance.bvh")
animator.export("output.mp4")

Both projects aim to simplify character animation, but UniRig offers a more versatile approach by supporting both 2D and 3D rigging. AnimatedDrawings provides a more user-friendly interface and extensive documentation, making it potentially easier for beginners to get started. However, UniRig's flexibility may be more appealing to advanced users or those working with diverse character types.

Pros of Monster-Mash

  • More mature project with a longer development history
  • Focuses on 3D character creation from 2D drawings
  • Provides a user-friendly interface for non-technical users

Cons of Monster-Mash

  • Limited to character creation and animation
  • Less flexible for general-purpose 3D rigging tasks
  • Requires more manual input for character design

Code Comparison

Monster-Mash (JavaScript):

function createMesh(vertices, faces) {
  const geometry = new THREE.Geometry();
  geometry.vertices = vertices.map(v => new THREE.Vector3(v[0], v[1], v[2]));
  geometry.faces = faces.map(f => new THREE.Face3(f[0], f[1], f[2]));
  return new THREE.Mesh(geometry, material);
}

UniRig (Python):

def create_rig(skeleton, mesh):
    rig = bpy.data.objects.new("Rig", bpy.data.armatures.new("Armature"))
    bpy.context.scene.collection.objects.link(rig)
    bpy.context.view_layer.objects.active = rig
    bpy.ops.object.mode_set(mode='EDIT')
    for bone in skeleton:
        edit_bone = rig.data.edit_bones.new(bone.name)
        edit_bone.head = bone.head
        edit_bone.tail = bone.tail

This comparison highlights the different approaches and focus areas of Monster-Mash and UniRig. Monster-Mash is more specialized for character creation from 2D drawings, while UniRig appears to be a more general-purpose 3D rigging tool with greater flexibility.

33,406

OpenPose: Real-time multi-person keypoint detection library for body, face, hands, and foot estimation

Pros of OpenPose

  • More established and widely used in academia and industry
  • Supports multi-person pose estimation
  • Offers real-time performance on GPU

Cons of OpenPose

  • Limited to 2D pose estimation
  • Requires more computational resources
  • Less flexibility in terms of customization and integration

Code Comparison

OpenPose:

auto datum = opWrapper.emplaceAndPop(imageToProcess);
if (datum != nullptr)
{
    auto poseKeypoints = datum->poseKeypoints;
    // Process keypoints
}

UniRig:

model = UniRig.from_pretrained("unirig-base")
outputs = model(image)
keypoints = outputs.keypoints
# Process keypoints

UniRig offers a more straightforward API and is designed for easier integration with other AI models. OpenPose, while powerful, requires more setup and configuration.

A real-time approach for mapping all human pixels of 2D RGB images to a 3D surface-based model of the body

Pros of DensePose

  • More established project with extensive documentation and research backing
  • Broader community support and integration with other Facebook AI tools
  • Focuses on dense human pose estimation, offering detailed surface-to-surface correspondences

Cons of DensePose

  • Primarily designed for human pose estimation, limiting its versatility for other subjects
  • Requires more computational resources due to its dense estimation approach
  • Less flexible for customization compared to UniRig's modular design

Code Comparison

DensePose:

from detectron2.config import get_cfg
from detectron2.engine import DefaultPredictor
cfg = get_cfg()
cfg.merge_from_file("path/to/densepose_rcnn_R_50_FPN_s1x.yaml")
predictor = DefaultPredictor(cfg)

UniRig:

from unirig import UniRig
model = UniRig(backbone="resnet50", num_joints=17)
model.load_weights("path/to/weights.pth")
predictions = model(image)

Both repositories offer powerful tools for pose estimation, but they cater to different use cases. DensePose excels in detailed human pose analysis, while UniRig provides a more flexible framework for various subjects and customization options. The code snippets demonstrate the initialization process for each project, highlighting DensePose's integration with Detectron2 and UniRig's more straightforward API.

1,194

[CVPR'23, Highlight] ECON: Explicit Clothed humans Optimized via Normal integration

Pros of ECON

  • More focused on human body reconstruction and pose estimation
  • Provides detailed documentation and examples for usage
  • Actively maintained with recent updates and contributions

Cons of ECON

  • Limited to human body modeling, less versatile for other applications
  • Requires specific datasets and preprocessing steps
  • May have higher computational requirements for real-time applications

Code Comparison

ECON:

import econ
model = econ.load_model('path/to/model')
result = model.reconstruct(image)

UniRig:

from unirig import UniRig
model = UniRig()
result = model.process(image)

Both repositories provide high-level APIs for their respective tasks, but ECON focuses on human body reconstruction, while UniRig offers a more general-purpose approach to rigging and animation. ECON's code is more specialized for body modeling, whereas UniRig's interface is designed for broader applications in character rigging and animation.

2,441

SMPL-X

Pros of SMPLX

  • More established and widely used in the research community
  • Offers multiple body models (SMPL, SMPL+H, SMPL-X) with varying levels of detail
  • Provides pre-trained models and extensive documentation

Cons of SMPLX

  • Focused primarily on human body modeling, less versatile for other rigging tasks
  • May require more computational resources due to its comprehensive nature
  • Steeper learning curve for beginners due to its complexity

Code Comparison

SMPLX:

import smplx
model = smplx.create(model_path, model_type='smplx')
output = model(betas=betas, expression=expression, return_verts=True)
vertices = output.vertices

UniRig:

from unirig import UniRig
model = UniRig(config_path)
output = model.forward(input_data)
rigged_mesh = output['rigged_mesh']

Summary

While SMPLX excels in human body modeling with multiple detailed options, UniRig aims for a more versatile approach to rigging various 3D objects. SMPLX offers pre-trained models and extensive documentation, making it a go-to choice for human-centric research. However, UniRig's flexibility may be advantageous for broader applications beyond human modeling. The code comparison shows that SMPLX is more specialized for human body parameters, while UniRig appears to have a more general-purpose interface for rigging tasks.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

UniRig: One Model to Rig Them All

Project Page Paper Model

teaser

This repository contains the official implementation for the SIGGRAPH'25 (TOG) UniRig framework, a unified solution for automatic 3D model rigging, developed by Tsinghua University and Tripo.

Paper: One Model to Rig Them All: Diverse Skeleton Rigging with UniRig

Overview

Rigging 3D models – creating a skeleton and assigning skinning weights – is a crucial but often complex and time-consuming step in 3D animation. UniRig tackles this challenge by introducing a novel, unified framework leveraging large autoregressive models to automate the process for a diverse range of 3D assets.

Combining UniRig with keyframe animation produces these following results:

devildragonrabbit

The full UniRig system consists of two main stages:

  1. Skeleton Prediction: An GPT-like transformer autoregressively predicts a topologically valid skeleton hierarchy using a novel Skeleton Tree Tokenization scheme.
  2. Skinning Weight & Attribute Prediction: A Bone-Point Cross Attention mechanism predicts per-vertex skinning weights and relevant bone attributes (e.g., for physics simulation) based on the predicted skeleton and input mesh geometry.

This repository provides the code implementation for the entire framework vision, with components being released progressively.

Key Features (Full UniRig Framework)

  • Unified Model: Aims to handle diverse model categories (humans, animals, objects) with a single framework.
  • Automated Skeleton Generation: Predicts topologically valid skeleton structures. (✅ Available in current release)
  • Automated Skinning Prediction: Predicts per-vertex skinning weights. (✅ Available in current release)
  • Bone Attribute Prediction: Predicts attributes like stiffness for physics-based secondary motion. (⏳ Coming Soon)
  • High Accuracy & Robustness: Achieves state-of-the-art results on challenging datasets (as shown in the paper with Rig-XL/VRoid training).
  • Efficient Tokenization: Uses Skeleton Tree Tokenization for compact representation and efficient processing.
  • Human-in-the-Loop Ready: Designed to potentially support iterative refinement workflows.

🚨 Current Release Status & Roadmap 🚨

We are open-sourcing UniRig progressively. Please note the current status:

Available Now (Initial Release):

  • ✅ Code: Implementation for skeleton and skinning prediction.
  • ✅ Model: Skeleton & Skinning Prediction checkpoint trained on Articulation-XL2.0. Available on Hugging Face.
  • ✅ Dataset: Release of the Rig-XL and VRoid datasets used in the paper. We also filtered out 31 broken models in the training dataset which do not affect the performance of the final model.
  • ✅ Training code.

Planned Future Releases:

  • ⏳ Full UniRig model checkpoints (Skeleton + Skinning) trained on Rig-XL/VRoid, replicating the paper's main results.

We appreciate your patience as we prepare these components for release. Follow VAST-AI-Research announcements for updates!

Installation

  1. Prerequisites:

    • Python 3.11
    • PyTorch (tested with version >=2.3.1)
  2. Clone the repository:

    git clone https://github.com/VAST-AI-Research/UniRig
    cd UniRig
    
  3. Set up a virtual environment (recommended):

    conda create -n UniRig python=3.11
    conda activate UniRig
    
  4. Install dependencies:

    python -m pip install torch torchvision
    python -m pip install -r requirements.txt
    python -m pip install spconv-{you-cuda-version}
    python -m pip install torch_scatter torch_cluster -f https://data.pyg.org/whl/torch-{your-torch-version}+{your-cuda-version}.html --no-cache-dir
    python -m pip install numpy==1.26.4
    

spconv is installed from this repo, torch_scatter and torch_cluster are installed from this site. Also, there is a high chance that you will encounter flash_attn installation error, go to its original repo and follow its installation guide.

  1. Download Model Checkpoint: The currently available skeleton prediction model checkpoint is hosted on Hugging Face and will typically be downloaded automatically by the provided scripts/functions.

  2. (Optional, for importing/exporting .vrm) Install the blender addon: The blender addon is modifed from VRM-Addon-for-Blender.

    Make sure you are in the root directory of the project, then:

    python -c "import bpy, os; bpy.ops.preferences.addon_install(filepath=os.path.abspath('blender/add-on-vrm-v2.20.77_modified.zip'))"
    

RigXL Dataset

processed data link

Notice that aside from vroid, all models are selected from Objaverse. Just download mapping.json if you already have Objaverse dataset (or need to download from web).

The json contains all ids of the models with type indicating their category and url specifying where to download. url is the same with fileIdentifier in Objaverse.

Training/validation split is put in datalist folder.

📝 Note:
All floating-point values are stored in float16 format for compression.

Visualize Data

Put the dataset in dataset_clean, go back to root, and run the command to export FBX model:

from src.data.raw_data import RawData
raw_data = RawData.load("dataset_clean/rigxl/12345/raw_data.npz")
raw_data.export_fbx("res.fbx")
📁 Dataset Format (click to expand)

🔑 Keys of Data

All models are converted into world space.

  • vertices:
    Position of the vertices of the mesh, shape (N, 3).

  • vertex_normals:
    Normals of the vertices, processed by Trimesh, shape (N, 3).

  • faces:
    Indices of mesh faces (triangles), starting from 0, shape (F, 3).

  • face_normals:
    Normals of the faces, shape (F, 3).

  • joints:
    Positions of the armature joints, shape (J, 3).

  • skin:
    Skinning weights for each vertex, shape (N, J).

  • parents:
    Parent index of each joint, where parents[0] is always None (root), shape (J).

  • names:
    Name of each joint.

  • matrix_local:
    The local axis of each bone; aligned to Y-up axis, consistent with Blender.

Usage

Skeleton Prediction

Generate a skeleton for your 3D model using our pre-trained model. The process automatically analyzes the geometry and predicts an appropriate skeletal structure.

# Process a single file
bash launch/inference/generate_skeleton.sh --input examples/giraffe.glb --output results/giraffe_skeleton.fbx

# Process multiple files in a directory
bash launch/inference/generate_skeleton.sh --input_dir <your_input_directory> --output_dir <your_output_directory>

# Try different skeleton variations by changing the random seed
bash launch/inference/generate_skeleton.sh --input examples/giraffe.glb --output results/giraffe_skeleton.fbx --seed 42

Supported input formats: .obj, .fbx, .glb, and .vrm

Skinning Weight Prediction

# Skin a single file
bash launch/inference/generate_skin.sh --input examples/skeleton/giraffe.fbx --output results/giraffe_skin.fbx

# Process multiple files in a directory
bash launch/inference/generate_skin.sh --input_dir <your_input_directory> --output_dir <your_output_directory>

Note that the command above uses an edited-version from skeleton phase. The results may degrade significantly if the skeleton is inaccurate — for example, if tail bones or wing bones are missing. Therefore, it is recommended to refine the skeleton before performing skinning in order to achieve better results.

Merge the Predicted Results

Combine the predicted skeleton with your original 3D model to create a fully rigged asset:

# Merge skeleton from skeleton prediction
bash launch/inference/merge.sh --source results/giraffe_skeleton.fbx --target examples/giraffe.glb --output results/giraffe_rigged.glb

# Or merge skin from skin prediction
bash launch/inference/merge.sh --source results/giraffe_skin.fbx --target examples/giraffe.glb --output results/giraffe_rigged.glb

Note that there will be no skinning if you try to merge a skeleton file(giraffe_skeleton.fbx). Use the predicted skinning result(giraffe_skin.fbx) instead!

Rignet Dataset Validation

Validate the metrics mentioned in the paper. This is for academic usage.

First, Download the processed dataset from Hugging Face and extract it to the dataset_clean.

Then run the following command:

python run.py --task=configs/task/validate_rignet.yaml

To export skeleton & mesh, set record_res to True in the config file configs/system/ar_validate_rignet.yaml.

Train from Scratch

The code may be a bit messed up — hopefully this will be addressed in a future update from the VAST team.

📝 Custom Data Preparation (click to expand) In `configs/data/rignet.yaml`, `input_dataset_dir` specifies the original model folder and `output_dataset_dir` specifies the output folder to store npz files. After changing them, run the following command to process the data:
bash launch/inference/preprocess.sh --config configs/data/<yourdata> --num_runs <number of threads to run>
🚅 Train Skeleton Model (click to expand)

This section provides the configuration files needed to reproduce the results trained on the Rignet dataset, as described in the paper. Several configuration components are required:

  1. data:

    To tell dataloader where and how to load. Defined in configs/data/rignet.yaml. The program will try to find data in <output_dataset_dir>/<relative path in datalist>/raw_data.npz, so you need to put processed dataset under dataset_clean.

  2. transform:

    Data augmentations. Defined in configs/transform/train_rignet_ar_transform.yaml.

    For details on the augmentation operations, refer to src/data/augment.py.

  3. tokenizer:

    To tell model how to encode skeletons. Defined in configs/tokenizer/tokenizer_rignet.yaml

  4. system:

    Control on training process. Defined in configs/system/ar_train_rignet.yaml. In this config, the training process will export generation results after 70 epochs every 4 epochs. You can also change sampling methods in it.

  5. model:

    Defined in configs/model/unirig_rignet.yaml, and you can change base transformer model here.

    Note: n_positions must > sum of the conditional embedding length and the maximum number of skeleton tokens.

  6. task:

    The final training config. Defined in configs/task/train_rignet_ar.yaml. This integrates all components above, and also configures loss, optimizer, and scheduler. You can find optimizers and schedulers initialization in src/system/optimizer.py and src/system/scheduler.py.

    The trainer section controls GPU/node usage (multi-node training is not tested).

    The wandb section enables logging with Weights & Biases, and the checkpoint section configures the checkpoint saving strategy.

    You can comment out wandb and checkpoint if you don’t need logging or final model checkpoints.

During training, the checkpoints will be saved to experiments/<experimentname>.

To run the training, use the following command:

python run.py --task=configs/task/train_rignet_ar.yaml

The best results typically appear around epoch 120, after approximately 18 hours of training on 4× RTX 4090 GPUs.

It is also noted that in ar training, lower validation CE loss does NOT necessarily imply better skeleton generation results. This can be verified in the following picture:

alt text

After training, change resume_from_checkpoint to path of the final model to see the results in the inference task. Create a new inference task named rignet_ar_inference_scratch.yaml in configs/task:

mode: predict # change it to predict
debug: False
experiment_name: test
resume_from_checkpoint: experiments/train_rignet_ar/last.ckpt # final ckpt path

components:
  data: quick_inference # inference data
  system: ar_inference_articulationxl # any system without `val_interval` or `val_start_from` should be ok
  tokenizer: tokenizer_rignet # must be the same in training
  transform: train_rignet_ar_transform # only need to keep the normalization method
  model: unirig_rignet # must be the same in training
  data_name: raw_data.npz

writer:
  __target__: ar
  output_dir: ~
  add_num: False
  repeat: 1
  export_npz: predict_skeleton
  export_obj: skeleton
  export_fbx: skeleton

trainer:
  max_epochs: 1
  num_nodes: 1
  devices: 1
  precision: bf16-mixed
  accelerator: gpu
  strategy: auto

and run:

bash launch/inference/generate_skeleton.sh --input examples/giraffe.glb --output examples/giraffe_skeleton.fbx --skeleton_task configs/task/rignet_ar_inference_scratch.yaml 
🚅 Train Skin Model (click to expand) The process of skinning training is very similar to skeleton training. You can modify `configs/task/train_rignet_skin.yaml`, and run:
python run.py --task=configs/task/train_rignet_skin.yaml

If you run into pyrender related issues, change vertex_group_confis/kwargs/voxel_skin/backend to open3d in configs/transform/train_rignet_skin_transform. This also means you need to change it in prediction mode.

Note that this task takes up at least 60GB memory on a single gpu, even with batch_size=2 in data config. You can change batch_size to 1, increase accumulate_grad_batches in the task, and decrease num_train_vertex in configs/model/unirig_skin.yaml for less memory requirement.

After training, change resume_from_checkpoint to path of the final model to see the results in the inference task. Create a new inference task named rignet_skin_inference_scratch.yaml in configs/task:

mode: predict # change it to predict
debug: False
experiment_name: test
resume_from_checkpoint: experiments/train_rignet_skin/last.ckpt # final ckpt path

components:
  data: quick_inference # inference data
  system: skin
  transform: inference_skin_transform # do not need skin vertex_group
  model: unirig_skin # must be the same in training
  data_name: raw_data.npz

writer:
  __target__: skin
  output_dir: ~
  add_num: False
  repeat: 1
  save_name: predict
  export_npz: predict_skin
  export_fbx: result_fbx

trainer:
  max_epochs: 1
  num_nodes: 1
  devices: 1
  precision: bf16-mixed
  accelerator: gpu
  strategy: auto
  inference_mode: True

and run:

bash launch/inference/generate_skin.sh --input examples/skeleton/giraffe.fbx --output results/giraffe_skin.fbx --skin_task configs/task/rignet_skin_inference_scratch.yaml 

Models

Available models are hosted on the: https://huggingface.co/VAST-AI/UniRig

System Requirements

  • For generation: CUDA-enabled GPU with at least 8GB VRAM

Citation

@article{zhang2025unirig,
  title={One Model to Rig Them All: Diverse Skeleton Rigging with UniRig},
  author={Zhang, Jia-Peng and Pu, Cheng-Feng and Guo, Meng-Hao and Cao, Yan-Pei and Hu, Shi-Min},
  journal={arXiv preprint arXiv:2504.12451},
  year={2025}
}

Acknowledgements

We would like to thank the following open-source projects and research works:

We are grateful to the broader research community for their open exploration and contributions to the field of 3D generation.