从动作捕捉到 BVH Motion Retargeter
2025年,我为了自己做 Blender 动画,买了一套商用 AGI 动作捕捉系统。
最开始其实完全是兴趣消费。
以前自己做人物动画,如果动作稍微复杂一点,大量手工 K 帧还是挺麻烦的。动作捕捉最吸引我的地方也很直接:真人先把动作做出来,再把动作转换成骨骼动画,至少基础运动不用全部从零手调。
所以买它的时候,我想的基本就是:
自己想做动画
↓
买动作捕捉系统
↓
少手搓一点关键帧
没想太多别的。
设备真正买回来以后,我又发现一个很现实的问题:我并不会每天都做动画。
大部分时候,这套东西其实是闲着的。
硬件、软件和学习成本都已经发生了,真正自己使用的时间却只占一部分。既然这样,我就顺手开始在网上提供视频动作捕捉服务:客户把人物动作视频给我,我负责做动作捕捉、整理数据,再根据需求交付 BVH,或者继续处理成可以直接给角色使用的动画。
于是原本很简单的一笔兴趣消费,慢慢变成了:
自己的动画需求
│
▼
购买 AGI 动作捕捉系统
│
├── 自己制作动画
│
└── 在线提供动作捕捉服务
│
▼
产生收益

这时候我原本以为,最麻烦的部分已经被动作捕捉系统解决了。
后来发现并没有。
动作捕捉完了,事情才刚开始
真正开始处理订单以后,我很快发现,动作捕捉本身反而不是最折腾人的地方。
设备把动作算出来,输出 BVH,这一步其实已经相对标准化了。真正开始麻烦的是:
客户拿什么骨架来接这段动作?
客户的角色来源可能完全不一样。
有的是 Mixamo。
有的是 Unreal Engine 5。
有的是 VRM 人形角色。
还有一些是自己处理过的 FBX。
看起来都是“人形骨架”,真正放到 Blender 里面却很容易出现各种问题:
骨骼名称不同
骨骼层级不同
人体比例不同
局部坐标轴不同
Root 结构不同
Root Motion 处理方式不同
所以:
有一份 BVH。
和:
这份动作已经可以直接塞进客户角色。
中间其实还隔着很长一段。
如果完全手工做,大概就是先检查源 BVH,再对应目标骨骼,建立 Constraint,处理位置和旋转,调整 Root Motion,然后 Bake 动画,最后再检查动作有没有明显问题,根据目标平台重新配置导出。
一单当然能做。
问题是下一单还要再来一次。
再下一单,继续来一次。
动作捕捉把采集阶段自动化以后,后处理重新变成了整条流程里面最明显的人工瓶颈。
我不想每一单都重新做一遍
这种重复劳动对我来说特别难受。
第一次碰到一个骨架问题,需要自己查资料、试参数、搞明白为什么动作歪了,这个过程我反而觉得挺有意思。
真正无聊的是:
这个问题我明明已经解决过了,为什么下一次还要手工重新解决?
例如某种 BVH 的骨骼命名已经搞清楚了。
下一次再来同类文件,还得重新对应一遍。
某一种目标骨架的约束关系已经验证过了。
下一次还是重新加 Constraint。
某个导出目标需要怎样的设置也知道了。
结果每次最后还是重新点一遍。
所以我后来干脆开始把这些重复使用的流程写进 Blender。
最后慢慢变成了一个插件:
BVH Motion Retargeter
项目最初的目的其实非常朴素:
把我自己每一单都在重复做的事情,尽量让程序做掉。
先解决骨骼 Mapping
第一件事情就是骨骼映射。
不同动作捕捉系统输出的 BVH,不一定使用同一套骨骼命名。
目标角色也一样。
例如 Mixamo 常见的是一套命名,UE5 又是另一套,VRM 还会出现自己的 Humanoid Bone 结构。
如果把每一种 BVH 的兼容逻辑直接硬写死在程序里面,以后增加一种源格式就要改一次代码,我觉得不太舒服。
所以后来用了 JSON 来保存 Mapping。
思路大概就是:
源 BVH 骨骼
↓
JSON Mapping
↓
内部能够识别的对应关系
↓
目标骨架 Profile
这样如果以后碰到另一种 BVH,只需要增加或者修改 Mapping,不必为了几个骨骼名字重新改整个 Retarget 逻辑。
Mapping 建好以后,插件会先检查源骨架,确认需要使用的骨骼能不能找到,再进入真正的动作传递。
这一步看起来很基础,但实际上已经解决了我前面大量:
“这个骨骼在这个文件里面到底叫什么?”
的重复工作。
Constraint Retarget
动作真正从 BVH 转到目标骨架上,我主要还是利用 Blender 本身已经存在的 Constraint 系统。
核心就是:
Copy Rotation
Copy Location
先让目标 Armature 对应的骨骼,根据 Mapping 去跟随源 BVH Armature。
也就是说,这个阶段并不是直接把 BVH 的关键帧复制过去,而是先建立一种关系:
源骨骼动
↓
Constraint
↓
目标骨骼跟着动
这样做的好处是,动作传递过程里面仍然有一层可以调整的空间。
例如:
某些骨骼只需要旋转
Root 需要位置变化
部分骨骼需要特殊处理
人体比例需要重新缩放
都可以在这一层处理。
整个流程现在大概可以写成:
视频
↓
AGI 动作捕捉
↓
BVH
↓
Source Mapping
↓
骨架兼容性检查
↓
Constraint Retarget
↓
Motion Scale / Root Motion
↓
NLA Bake
↓
动画检查与清理
↓
FBX / Blender Animation
为什么最后还要 Bake
Constraint 跑起来以后,目标角色虽然已经会跟着 BVH 动,但这时候动画本质上仍然依赖那套 Constraint。
这并不是我最后想交付的状态。
我更希望最终得到的是:
真正写在目标骨架上的动画关键帧。
所以 Retarget 完成以后,还要经过 NLA Bake。
Bake 以后,前面通过 Constraint 得到的运动会被烘焙到目标 Armature 的 Animation Action 里面。
这时候就可以把临时 Constraint 删除掉。
目标角色不再需要一直挂着源 BVH 骨架才能播放动作。
最后留下的是正常的 Blender 动画数据,可以继续:
手工修动作
编辑关键帧
清理曲线
进一步做动画
或者直接导出 FBX
对我来说,这一点很重要。
因为插件最终不是想制造一个只能在自己内部运行的奇怪中间状态,而是把结果重新交回 Blender 正常的动画工作流。
人体比例和 Root Motion
真正做 Retarget 的时候还有一个问题:
两套骨架长得并不一样。
源 BVH 对应的真人比例,和目标角色可能差很多。
如果直接把某些位移原样塞过去,很容易出现移动距离、Root 高度或者整体运动不自然的问题。
所以中间还需要考虑 Motion Scale。
Root Motion 也一样。
有些动画希望角色真正向前移动,有些流程更希望角色基本留在原点,把移动交给游戏引擎或者后面的系统处理。
这不能永远用一个固定答案。
所以在我自己的流程里,它本来就应该成为一个可以控制的步骤,而不是每一单重新手工处理。
后来越来越觉得,所谓“自动化 Retarget”也不是:
点一个按钮,然后不管什么骨架都100%完美。
这不现实。
真正值得自动化的是:
那些我已经明确知道处理规则的部分。
剩下异常的、特殊的,再由人处理。
Mixamo、UE5 和 VRM
最开始我主要遇到的目标骨架,大致就是几类:
Mixamo
Unreal Engine 5
VRM
所以插件也逐渐围绕这些骨架做 Profile。
它们都属于人形动画,但实际工作流并不完全一样。
Mixamo 比较常见,很多角色本身就已经使用 mixamorig: 这一套骨骼命名。
UE5 常见的则是 root、pelvis、spine_01 这些结构,后面还可能继续进入 Unreal 自己的动画和 Retarget 流程。
VRM 又有自己的 Humanoid 结构,而且角色里面经常还会带头发、衣服、装饰等次级骨骼。
但动作捕捉真正需要解决的,主要还是人体主体。
所以我的思路不是:
把一个角色身上的所有骨骼全部纳入动作捕捉。
而是先抓住:
Hips
Spine
Chest
Neck
Head
Arms
Hands
Legs
Feet
这些真正负责人体运动的骨骼。
次级物理骨骼以后仍然可以留给原本的物理系统。
插件真正省掉的是什么
BVH Motion Retargeter 对我最直接的意义,并不是:
我写了一个 Blender 插件。
这件事本身其实没那么重要。
真正重要的是,它开始把原来订单里面不断重复出现的劳动固化下来。
以前的流程是:
来一单
↓
手工处理
下一单
↓
再手工处理
碰到同类问题
↓
重新操作一次
后来逐渐变成:
第一次碰到问题
↓
自己解决
↓
确认规则
↓
把规则写进插件
↓
以后同类数据
让程序处理
这样以后,我真正需要花时间处理的东西会慢慢向两端移动。
一端是:
客户到底要什么。
另一端是:
这一次有没有以前没有遇到过的特殊情况。
至于中间那些已经解决过很多遍的步骤,应该尽量交给程序。
自动化以后,我的工作反而更明确了
最后整套流程慢慢形成了一个比较清楚的分工。
AGI 动作捕捉系统负责:
视频
↓
人体动作
↓
BVH
BVH Motion Retargeter 负责:
BVH
↓
Mapping
↓
目标骨架
↓
Bake
↓
可继续使用的动画
而我自己主要处理:
客户需求
源数据异常
特殊骨架
动作质量检查
自动流程处理不了的边缘情况
最终交付
这反而比一开始什么都自己手工点舒服很多。
因为人的时间开始集中在真正需要判断的地方。
一套兴趣设备慢慢变成了生产工具
回头看,这件事情的发展其实挺有意思。
最开始只是:
我想自己做 Blender 动画,所以买了一个动作捕捉系统。
然后觉得:
大部分时间闲着也是闲着,不如拿去接一点单。
接单以后又发现:
动作捕捉快了,但是后处理太慢。
于是继续想:
那就把后处理也自动化一点。
最后就形成:
兴趣需求
↓
购买动作捕捉设备
↓
出现闲置能力
↓
提供动作捕捉服务
↓
真实订单暴露重复劳动
↓
编写 Blender 插件
↓
降低后处理成本
↓
反过来提升整个服务效率
一套最开始为了兴趣购买的设备,也慢慢从单纯的消费品,变成了可以同时服务:
个人创作
+
对外业务
的生产工具。
我还挺喜欢这种变化。
因为它不是我一开始先设计好了一套:
“商业模式。”
然后按计划实施。
反而就是一路做下去,哪里开始重复、哪里开始烦,就写点东西解决。
最后回头一看,才发现原本几个分散的东西已经被串成了一套流程。
开源
既然这个插件本身已经能脱离我的动作捕捉设备单独使用,我后来也把项目放到了 GitHub。
BacteriaJun / BVH-Motion-Retargeter
现在它对我来说仍然首先是一个自己会实际使用的工具。
以后再碰到新的 BVH、新的骨架或者新的兼容性问题,如果最后能够找到比较稳定的处理规则,我也可以继续把它塞回这套流程里面。
我一直很喜欢这种程序。
不是为了想一个项目,然后强行找需求。
而是:
我自己真的遇到了一个麻烦。
第一次我手工把它解决。
第二次再出现的时候,我开始觉得不对。
第三次以前,最好让程序接手。
BVH Motion Retargeter 大概就是这么来的。

















这一切,似未曾拥有