You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中基于Three.js合并GLTF动画的实现方法

在Three.js中组合同一模型的面部与肢体GLTF动画

核心前提

首先必须确保两组GLTF文件基于完全相同的基础模型与骨骼结构——骨骼的层级、名称、绑定关系必须完全一致,否则动画无法正确映射到模型上。如果导出时没做到这一点,先回到建模软件(比如Blender)调整:导出一个带骨骼的基础模型,再分别导出面部表情、肢体动作的纯动画文件(不带模型网格)。

实现步骤

1. 加载模型与动画资源

在Angular项目中,用GLTFLoader分别加载基础模型、面部动画GLTF、肢体动作GLTF:

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { AnimationMixer, AnimationAction } from 'three';

let mixer: AnimationMixer;
let model: THREE.Group;
// 存储所有动画Action
const animationActions: Record<string, AnimationAction> = {};

// 先加载带骨骼的基础模型
new GLTFLoader().load('path/to/base-model.gltf', (gltf) => {
  model = gltf.scene;
  scene.add(model);
  
  mixer = new AnimationMixer(model);
  
  // 加载面部动画GLTF,提取动画剪辑
  new GLTFLoader().load('path/to/facial-animations.gltf', (facialGltf) => {
    facialGltf.animations.forEach((clip) => {
      const action = mixer.clipAction(clip);
      animationActions[clip.name] = action;
    });
  });
  
  // 加载肢体动作GLTF,提取动画剪辑
  new GLTFLoader().load('path/to/body-animations.gltf', (bodyGltf) => {
    bodyGltf.animations.forEach((clip) => {
      const action = mixer.clipAction(clip);
      animationActions[clip.name] = action;
    });
  });
});

2. 组合播放动画

当需要播放「奔跑+微笑」这类组合时,直接调用对应动画Action的play()方法即可——只要两类动画的骨骼影响范围不重叠(面部动画只动面部骨骼,肢体动画只动躯干四肢),它们会自然叠加:

// 播放奔跑+微笑
animationActions['run'].loop = THREE.LoopRepeat;
animationActions['run'].play();
animationActions['smile'].loop = THREE.LoopRepeat;
animationActions['smile'].play();

如果存在骨骼重叠(比如某段动画同时影响头部),可以通过调整weight属性控制动画混合程度:

// 让面部动画完全覆盖头部的肢体动画影响
animationActions['smile'].weight = 1;
animationActions['smile'].play();

3. 帧更新动画

在Angular的动画循环中(比如用requestAnimationFrame),必须更新AnimationMixer的时间,否则动画不会播放:

let prevTime = performance.now();

function animate() {
  requestAnimationFrame(animate);
  
  const currentTime = performance.now();
  const delta = (currentTime - prevTime) / 1000;
  
  if (mixer) {
    mixer.update(delta);
  }
  
  renderer.render(scene, camera);
  prevTime = currentTime;
}
animate();

关键注意点

  • 不要为同一模型创建多个AnimationMixer,所有动画都要绑定到同一个mixer实例上。
  • 如果加载的GLTF包含重复模型,记得只保留基础模型,只提取另一组的动画剪辑,避免场景中出现重复模型。
  • 建模导出时,确保动画的骨骼名称与基础模型完全匹配,哪怕是大小写差异都会导致动画失效。

内容的提问来源于stack exchange,提问作者james Makinde

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 12:01:02