如何使用 Three.js 实现复杂的 3D 动画效果

本技能提供一套完整的 Three.js 动画解决方案,涵盖从简单的程序化运动到复杂的 GLTF 骨骼动画加载、动画权重混合及形态目标控制。

为什么需要这个技能

在 3D 场景中,静态模型无法提供沉浸感。无论是简单的物体旋转、复杂的角色走跑跳动作,还是面部表情的细微变化,都需要一套系统化的动画方案。

Three.js 提供了强大的 AnimationMixerAnimationClip 体系,但其 API 较为复杂且分散。掌握该技能可以让你快速实现从简单的正弦波运动到专业级角色动画平滑过渡(Crossfade)的各种效果,而无需从零开始研究底层数学。

适用场景

  • 角色控制:加载 GLTF 模型并播放走、跑、跳等预设动画。
  • 环境动态化:创建程序化的物体漂浮、旋转或循环往复的机械运动。
  • 面部表情:利用 Morph Targets 实现角色说话、眨眼或微笑。
  • 状态切换:在不同动画片段之间实现平滑的权重过渡(Blending)。

核心工作流

1. 程序化动画 (Procedural Animation)

对于简单的循环运动,推荐使用 THREE.Timer(r183+ 版本)在渲染循环中直接更新属性。

const timer = new THREE.Timer();

renderer.setAnimationLoop(() => {
  timer.update();
  const delta = timer.getDelta();
  const elapsed = timer.getElapsed();

  mesh.rotation.y += delta;
  mesh.position.y = Math.sin(elapsed) * 0.5;

  renderer.render(scene, camera);
});

2. 基于关键帧的系统 (Keyframe System)

Three.js 动画系统由三个核心组件构成:

  • AnimationClip:存储关键帧数据(时间轴和数值)。
  • AnimationMixer:将动画应用于目标对象并驱动播放。
  • AnimationAction:控制单个片段的播放状态(速度、权重、循环模式)。

3. GLTF 骨骼动画加载

这是最常见的角色动画实现方式,通过 GLTFLoader 获取预设的 animations 数组。

const loader = new GLTFLoader();
loader.load("model.glb", (gltf) => {
  const model = gltf.scene;
  const mixer = new THREE.AnimationMixer(model);
  
  // 寻找名为 "Walk" 的动画片段并播放
  const walkClip = THREE.AnimationClip.findByName(gltf.animations, "Walk");
  if (walkClip) {
    mixer.clipAction(walkClip).play();
  }
  window.mixer = mixer;
});

// 在循环中必须调用 mixer.update(delta)
function animate() {
  const delta = clock.getDelta();
  if (window.mixer) window.mixer.update(delta);
  requestAnimationFrame(animate);
}

4. 动画混合与过渡 (Blending)

通过调整 AnimationAction.weight,可以在两个动画之间实现平滑切换(如从“走”切换到“跑”)。

const action1 = mixer.clipAction(clip1);
const action2 = mixer.clipAction(clip2);

action1.play();
// 0.5秒内将 action1 平滑过渡到 action2
action1.crossFadeTo(action2, 0.5, true);
action2.play();

下载和安装

下载 threejs-animation 中文版 Skill ZIP

解压后将目录放入你的 AI 工具 skills 文件夹,重启工具后即可使用。具体路径参考内附的 USAGE.zh.md

你可能还需要

暂无推荐