Animating 3D Models in Three.js with Mixamo and GLTF

Introduction

Animating 3D models in Three.js is a powerful way to bring interactive experiences to life. Mixamo, an online animation library by Adobe, provides high-quality character animations, while the GLTF format allows efficient model storage and rendering in Three.js. This article covers how to import, animate, and control Mixamo animations in Three.js using GLTF models.

1. Exporting an Animated Model from Mixamo

Step 1: Choose a Character in Mixamo

  1. Go to Mixamo
  2. Select a character from Mixamo’s library or upload a custom model.

Step 2: Apply an Animation

  1. Browse the animation library and choose an animation.
  2. Adjust settings like arm spacing, speed, and in-place movement.
  3. Click Download and choose:
  • Format: GLTF (Binary, .glb)
  • Frames per second: 30 or 60
  • Skin: With Skin
  • Keyframe Reduction: Optional (recommended for smoother playback)

2. Loading the GLTF Model in Three.js

Installing Three.js and GLTFLoader

Ensure you have Three.js set up. If using a module-based environment:

npm install three

Import the necessary components:

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

Loading the GLTF Model

const loader = new GLTFLoader();
loader.load('path/to/your/animated_model.glb', (gltf) => {
    const model = gltf.scene;
    scene.add(model);
});

3. Playing Mixamo Animations

Setting Up the Animation Mixer

let mixer;
loader.load('path/to/your/animated_model.glb', (gltf) => {
    const model = gltf.scene;
    scene.add(model);

    mixer = new THREE.AnimationMixer(model);
    const action = mixer.clipAction(gltf.animations[0]);
    action.play();
});

Here:

  • THREE.AnimationMixer handles animations.
  • clipAction() selects an animation from the loaded GLTF.
  • .play() starts the animation.

Updating the Animation in the Render Loop

function animate() {
    requestAnimationFrame(animate);
    const delta = clock.getDelta();
    if (mixer) mixer.update(delta);
    renderer.render(scene, camera);
}

This ensures animations run smoothly each frame.

4. Switching Between Animations

For models with multiple animations (e.g., walking, jumping, idle), use:

const actions = {};
gltf.animations.forEach((clip) => {
    actions[clip.name] = mixer.clipAction(clip);
});

function playAnimation(name) {
    Object.values(actions).forEach(action => action.stop());
    actions[name].play();
}

Call playAnimation('Walk') or another animation name to switch dynamically.

5. Blending and Transitioning Animations

To smoothly blend between animations:

function transitionToAnimation(name, duration = 0.5) {
    Object.values(actions).forEach((action) => {
        action.fadeOut(duration);
    });
    actions[name].reset().fadeIn(duration).play();
}

This ensures smooth transitions when switching animations.

6. Controlling Animations with User Input

To trigger animations based on user input:

document.addEventListener('keydown', (event) => {
    if (event.code === 'KeyW') playAnimation('Walk');
    if (event.code === 'Space') playAnimation('Jump');
});

This allows real-time interaction based on keyboard events.

Conclusion

By combining Mixamo’s high-quality animations with Three.js’s robust rendering engine, you can create dynamic, interactive 3D experiences. The GLTF format ensures efficient file handling, and AnimationMixer enables smooth playback and transitions. With these techniques, you can animate characters for games, simulations, or VR experiences.

Leave a comment

Your email address will not be published. Required fields are marked *