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

使用3D关节坐标在three.js中驱动VRM人形模型动画的技术问题咨询

Three.js VRM动捕常见问题解答

1. 3D关节坐标转骨骼旋转值的方法

1.1 单个关节坐标对应的欧拉角计算逻辑

首先需要先对齐坐标系:你的输入坐标系是y轴向下,three.js默认y轴向上,需要先将输入坐标的y值乘-1完成坐标系转换。
单个关节的坐标无法直接计算旋转,你需要同时获取该关节所属骨骼的根点和末点坐标(比如计算左肩关联的左上臂骨骼旋转,需要同时拿到左肩、左肘两个关节的坐标),计算步骤如下:

  1. 拿到父骨骼(左上臂的父骨骼为胸腔)的世界坐标,将两个关节坐标转换到父骨骼的局部坐标系下
  2. 计算骨骼的目标朝向向量:末点局部坐标减去根点局部坐标,做归一化处理
  3. 调用THREE.Quaternion的setFromUnitVectors方法,将骨骼初始朝向向量(可以在模型绑定姿势下提前获取存储)转换到目标朝向向量,得到四元数
  4. 调用四元数的toEuler方法,传入和模型一致的欧拉角顺序(一般为XYZ)即可得到需要的rotation值

1.2 需要计算旋转的骨骼范围

仅需要对具备可动父子层级、关联肢体运动的骨骼计算旋转,包括脊柱、颈部、头部、肩、上臂、下臂、手腕、髋部、大腿、小腿、脚踝等部位。
左肩的旋转具备实际意义,直接控制整个手臂的抬起、转向角度;鼻子这类属于头部骨骼的子节点,不需要单独计算旋转,头部骨骼旋转后鼻子会自动跟随运动,单独调整其旋转没有常规应用价值。

1.3 不能直接修改骨骼position的原因

核心原因是人形骨骼动画遵循刚体层级绑定规则:

  1. 正常人体的骨骼长度是固定的,关节仅能做旋转运动,不能随意改变相对父骨骼的位置,直接修改position相当于将骨骼从父级上扯离,完全不符合人体运动逻辑
  2. 你给出的代码写法本身也存在语法错误:Object3D的position是Vector3类型,不能直接赋值元组,需要调用set(10, -2.5, 1)方法赋值,即使语法正确,最终效果也会和预期动作完全不符
  3. 只有根骨骼(通常是髋部)的position可以调整,用来实现整个人物的位移,其余骨骼的position在绑定姿势下就已经固定,不需要修改

2. VRM人形骨骼节点的结构与旋转计算逻辑

VRM返回的骨骼节点就是标准的three.js Object3D实例,不是单纯的向量,它包含完整的三维变换属性:局部位置position、局部欧拉角rotation、局部四元数quaternion、缩放scale、局部变换矩阵matrix、世界变换矩阵matrixWorld,以及父节点、子节点的引用关系,完全支持三维空间的旋转、位移、缩放操作。
你拿到左肩的单个三维坐标,不能直接计算三个轴的角度赋值给rotation:

  1. 单个点的坐标没有方向参考,你必须拿到该骨骼关联的两个端点坐标,才能计算出骨骼的朝向
  2. 所有旋转计算需要在父骨骼的局部坐标系下完成,不能直接用世界坐标计算角度
  3. 更推荐直接给quaternion属性赋值四元数,不需要转欧拉角,可以避免万向锁问题,旋转精度更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:45:04