最近把自己用的骨骼动画烘焙与 GPU 播放方案整理成了 coo-skel-baker 插件。这里分享一下实现思路、测试结果。
先看效果
完整演示包含 Playback、Events、Sockets、Features,以及 2D / 3D 各 10000 个动画单位实测
https://www.bilibili.com/video/BV1Bzsd6nEBD/
| 播放路径 | 测试角色 | 单位数 | 视频中 Stats FPS | Draw Calls |
|---|---|---|---|---|
| 2D UI 合批 | Spineboy | 10000 | 60 | 4 |
| 3D GPU Instancing | Hero | 10000 | 60 | 14 |
1. 把实时解算换成离线采样
核心不是把整套 Spine Runtime 搬到 GPU,而是提前计算运行时不再需要改变的部分:
Spine JSON / SKEL + Atlas
→ 编辑器使用匹配版本的官方运行时采样
→ 烘焙数据:骨骼矩阵、绘制数据、事件、挂点等
→ CPU 更新时间、队列和实例参数
→ GPU 读取数据纹理,恢复顶点并插值
基础蒙皮数据保存采样后的骨骼矩阵,Shader 根据播放时间读取相邻采样帧,并对恢复的结果做插值。
所以它省掉的主要是每个角色每帧的实时 Spine 解算和 CPU 蒙皮,不是让 CPU 完全不工作。事件分发、挂点更新、组件管理、渲染提交仍然有少量成本。
烘焙采样率不等于运行帧率:30 FPS 采样可以在更高运行帧率下插值播放,但插值不等价于重新求解原始曲线和约束,快速动作与循环接缝仍要对照检查。
2. 2D 合批与 3D 实例化是两套问题
2D 路径使用 SkbAnimation组件,接入 UIRenderer。烘焙动画与 Sprite、Label 交错时,仍要遵守 UI 顺序;材质、贴图、混合状态、遮罩或缓冲条件不一致,都可能拆批。多页图集和不同混合模式也会增加批次。
3D 路径使用 SkbAnimation3D组件,在资源、材质和绘制范围匹配时,通过 GPU Instancing 提交各实例的变换与动画参数。适合把平面骨骼角色放进 3D 场景,也提供 Billboard;它不会把 Spine 角色变成立体模型,透明排序和填充依然需要注意。
两条路径都不意味着“所有素材固定一个 Draw Call”。我更关心的是:在保持正确画面和顺序的前提下,能共享多少资源、减少多少 CPU 工作。
3. 事件与挂点
动画时间轴事件随数据一起烘焙,播放端按经过的时间区间触发回调;挂点则保存指定骨骼的采样变换,运行时读取并驱动目标节点,适合枪口、武器和特效节点跟随。
这和重新执行完整骨骼解算不同。挂点越多、每帧更新的目标节点越多,CPU 成本也会增加。
4. 如何接入使用
插件负责源文件烘焙和运行时模块安装。
作者建议
适合割草、群体单位、大量实例展示等场景;也适合多版本 Spine 资源统一烘焙后的播放(就是多版本spine混用)。
如果项目依赖运行时 IK、复杂多轨混合、动态新增附件或实时物理驱动动画,不建议直接替代官方 Runtime。



