从一张图到 SpriteSheet:AI 自动生成 2D 精灵动画实操
文章目录
在 2D 游戏研发的过程中,序列帧动画(精灵动画)是常见的一种动画形式。精灵动画的承载模式,也常常被叫做 SpriteSheet。
本文介绍如何使用生图大模型,从单张参考图生成 SpriteSheet 动画素材的过程。
善用这个流程,可以大幅降低 2D 游戏开发过程中美术和动画的工作量。如果审美到位,也可以不用美术帮忙,就实现基础的逐帧动画。
SpriteSheet 考古
曾老师 15 年前写过一个 SpriteSheet 编辑器并开源,啊!这该死的回忆……
涉及的大模型和技术栈
曾老师已经将整个功能封装成了 Skill 并开源。不想看技术栈的同学可以跳转到文章末尾。
- 必须:Seedance 2.0/Gemini Omni 或其他视频生成模型。
- 必须:gpt-image-2/Nano Banana Pro 或其他生图模型。
- 必须:OpenCV 库。
- 必须:Agent 工具,Claude Code、Codex、OpenCode、Hermes Agent、OpenClaw 等均可。
- 可选:doubao-seed-2.0-pro 或其他支持视频理解的模型。
两种主流方案
生图大模型直接生成序列帧
社区一直在探索使用大模型直接生成序列帧的模式,这种方式有一个较大的弊端,就是动作的连贯性和一致性。
拿来做表情包是可以的,但如果放入游戏中,就会显得动画之间不连贯。
视频抽帧生成序列帧
另一种主流的序列帧生成方式,是使用视频生成模型生成视频,然后用抽帧的方式生成序列帧。
这个流程稍微复杂一点点:
- 使用生图模型或者手绘参考图。
- 使用视频生成大模型,基于参考图生成视频。
- 基于生成的视频,进行抽帧,考虑循环动画的闭合性,以及一次性动画的连贯性。
- 批量抠图,让背景透明,使其可放入游戏中。
视频生成的核心难点
图像生成关键点
- 闭合边缘,避免参考图中出现镂空的部分。
- 避免出现过细的边缘(例如天线、头发之类)。
- 优先提供背景透明的参考图(主体之外 Alpha = 0)。
如下图所示,很小的镂空图像,容易出现抠不干净的像素:
这种情况下,可以通过 gpt-image-2 的编辑功能,对图像进行修改:
上面的提示词是我口喷的,千万不要学习!
但口喷真的很快啊!
视频生成关键点
- 使用绿幕关键色作为视频背景。
- 提供视频循环的关键细节。
- 要求视频模型不要生成阴影(影响抠图)。
- 不要生成烟气、云朵这种边缘模糊的物体(影响抠图)。
影视行业绿幕关键色
视频生成的时候,必须指定一个背景色。影视行业的传统抠像标准使用的是绿色。
在实拍摄影棚中,一般使用 #00B140 这个色值,因为纯绿 #00FF00 在强光下容易过曝。但对 AI 生成视频来说不存在灯光问题,所以使用 #00FF00 即可。
| 类型 | 标准色值 | 说明 |
|---|---|---|
| 绿幕(推荐) | #00FF00 或 chroma green background | 影视行业标准,布景中极少纯绿 |
| 蓝幕 | #0000FF 或 chroma blue background | 传统影视,绿色冲突可用蓝色 |
不建议使用白幕布(白色背景)或黑幕布。前者容易混淆高光区,后者容易混淆物体的暗部。
对应的视频提示词可以这样写:
1从第一帧开始就保持绿色关键色,色值:#00FF00,没有渐变色,没有阴影。
或者:
1Pure chroma green background (#00FF00), solid color with no gradients or shadows
不要让视频大模型生成绿幕
在提供的图像素材透明的前提下,上面的提示词可以让视频大模型生成绿幕视频。
但曾老师实际操作的过程中,这个效果并不好。
大模型经常会忽略关于颜色的提示词,给我生成一个白色幕布;或者自作主张把 绿色改为草绿,或者主动在车辆下方增加一个 阴影(当然会影响抠图)。这种主动让人吐血(如下图),但我并不需要啊!
更好的方案,是直接提供一个带有绿幕的参考图像,如下图所示:
循环动画细节
以上面提到的车辆开动的动画为例,如果最终需要生成一个 12 帧的 SpriteSheet 序列帧动画,那么要考虑在所有 12 帧中:
- 车轮的转动,需要在循环中闭环。
- 车辆的震动,需要在循环中闭环。
可以在生成视频的时候,针对性使用提示词限定。例如可以使用这样的提示词限定车轮的滚动:
1车轮细节:在 12 个关键帧中,车轮匀速旋转。
在我的测试过程中,车轮旋转 3 周 这样的提示词,可能会让 Seedance 2.0 理解为车辆自转。但 Gemini 能正确理解。
针对上面的车辆动画,我的提示词为:
1基于 @图像1,创建包含 12 个关键帧的视频。确保所有画面中的一切细节完全保持一致:车辆细节、摄像机角度、焦距、光影、背景以及色调。唯一发生变化的是微动作的递进。
2
3严格遵守:
4
5**不要** 改变车辆的方向。
6车辆底部 **没有** 任何阴影。
7
8风格:干净的摄影棚动画摄影,高细节,清晰对焦,与参考图完全一致的风格。
9画面大小:按照图像比例处理车辆大小,保证最终视频中完整展现车辆。
10视频背景色:从第一帧开始就保持绿色关键色,色值:#00FF00,没有渐变色,没有阴影。
11动画:车辆在原地开动,保证视频中有一个完整的开动循环,车轮转动,车身小幅颠簸,悬挂拉伸小幅变形。
12车轮细节:在 12 个关键帧中,车轮匀速旋转。
抠图难点
视频生成之后,需要将视频抽帧,再转成逐帧 SpriteSheet。
以一个 5 秒 / 30 FPS 的视频为例,共包含 150 帧。
在本例中,需要从 150 帧中抽出 12 帧,组成一个完整的车辆开动循环逐帧动画。
OpenCV MSE 抽帧
抽帧的重点,是识别 一个完整的循环动画。这里需要对画面的理解能力。
OpenCV 使用 MSE 算法,通过分析每一帧像素之间的差异,来判断动画的关键帧,再执行抽帧。
MSE = Mean Squared Error(均方误差)
这是一个通用的统计度量方法,中文叫「均方误差」。它常用于需要量化两组数据差异的场景,例如图像处理、信号处理、机器学习损失函数等。
$$ \mathrm{MSE} = \frac{1}{N}\sum_{p=1}^{N}\left(\mathrm{pixel}_{A,p} - \mathrm{pixel}_{B,p}\right)^2 $$在代码中归一化到 0-1 范围:
$$ \mathrm{MSE} = \frac{\operatorname{mean}\left((\mathrm{gray}_0 - \mathrm{gray}_i)^2\right)}{255^2} $$| MSE 值 | 含义 |
|---|---|
| 0.00000 | 两帧完全相同 |
| 0.00003 | 几乎没变(帧 0 vs 帧 2) |
| 0.00500 | 有可感知的变化 |
| 0.01000 | 明显不同 |
| 1.00000 | 完全不同(理论上限) |
在本例中,MSE 用于两处:
- 循环检测:逐帧与第 0 帧计算 MSE,找到 MSE 曲线的「回归点」(值重新变小的位置),也就是循环终点。
- 车轮分析:裁剪车轮区域单独算 MSE,判断车轮是否在转动。
严格来说,这不算 理解画面,因此可能存在抽帧不准确的情况。
视觉识别大模型抽帧
视觉识别大模型则是通过准确分析画面的内容,在本例中使用的是 doubao-seed-2.0-pro。
下面是大模型思考的部分过程:
1不过等下,首先要确认帧的效果,比如 8 帧的变化:
2帧 1:初始位置,车轮 0 度,车身 y=0
3帧 2:车轮转 22.5 度,车身 y=+1px
4帧 3:车轮转 45 度,车身 y=+2px
5帧 4:车轮转 67.5 度,车身 y=+1px
6帧 5:车轮转 90 度,车身 y=0
7帧 6:车轮转 112.5 度,车身 y=-1px
8帧 7:车轮转 135 度,车身 y=-2px
9帧 8:车轮转 157.5 度,车身 y=-1px
10然后帧 8 接帧 1,车轮转 180 度?不对,哦,刚才说的是双循环转一圈,所以帧 1 的下一个是帧 2,到帧 8 之后接帧 1,车轮继续转 180 度,然后到帧 16 的时候转完 360 度,这样转速很慢,符合平稳行驶的感觉。
11对,这样的话,循环两次车轮转一圈,速度合适,不会太快。
12还有,车身的纹理变化,原视频里的车身是慢慢变脏,所以 8 帧的纹理是从稍干净到稍脏,然后第 8 帧的纹理和第 1 帧的纹理过渡自然,不会有突然变干净的情况,对吧?对,调整第 8 帧的纹理和第 1 帧的纹理接近,这样循环的时候不会跳变。
使用 OpenCV 抠图
视频生成的背景关键色(绿幕),不一定会非常准确(可能需要抽卡)。但在抠图的过程中,也需要调整参数。
以上面的车辆行驶动画为例。车身本身是军绿色,如果抠图的 HSV 色差阈值过宽,就会将动画做成酱紫……把我的发动机盖也抠没了。
| 背景绿幕 | 车身军绿 | 当前范围 S ≥ 40 | |
|---|---|---|---|
| H (色相) | 63 (很窄) | 56 (很宽) | 35-85 ❌ 重叠 |
| S (饱和度) | 198 | 46 | ≥ 40 ❌ 车身被错误抠掉 |
| V (亮度) | 145 | 102 | ≥ 40 ❌ 车身被错误抠掉 |
S 阈值从 40 开始,车身的 S=46 落入范围。调整方案也很简单:提高 S 和 V 的下限到 >= 80,只匹配高饱和度、高亮度的绿幕。
开源 Skill 下载
曾老师将基于视频抽帧的能力,封装成一个 Skill。
从下面的参数表可以看出,上面提到的幕布颜色功能,以及使用 --smart 参数控制是否使用大模型,还有基础的指定帧数和画布尺寸的功能都已经提供。
| 参数 | 默认值 | 说明 |
|---|---|---|
--video |
(必填) | 视频文件路径 |
--frames |
8 |
提取帧数 |
--cols |
4 |
spritesheet 列数 |
--canvas-size |
512 |
输出帧画布尺寸(正方形) |
--bg-color |
auto |
背景色: auto/green/blue/white/black |
--smart |
关闭 | 启用视频模型分析最佳循环区间 |
--output-dir |
./output |
输出目录 |
如果只使用 OpenCV 抽帧,优点是免费,缺点是可能不准确。
如果需要使用大模型辅助抽帧,配置 API Key 即可使用,优点是可能更准确,缺点就是贵。
需要了解更多用法,查看 SKILL.md 即可。
安装 Skill 之后,只需要和 Agent 说一声:
1使用 spritesheet 技能,处理 [视频文件路径],视频背景为绿色,生成 12 帧循环动画,分别使用 smart 和非 smart 模式处理。
| CV 模式 | Smart 模式 | |
|---|---|---|
| 循环区间 | 0 → 229(9.6 秒) | 0 → 119(5.0 秒) |
| 帧间距 | 19 帧(0.79s) | 10 帧(0.42s) |
| 丰富度 | 0.237 | — |
| 模型理由 | — | 完成一次完整上下起伏周期,首尾帧姿态完全一致 |
这个 Skill 会生成分割好的帧文件,同时也会生成一个 spritesheet.png 文件,并创建一个 player.html 播放器,双击调用浏览器自动播放这个序列帧动画。
最终生成的 SpriteSheet 逐帧动画播放效果:
Skill 开源下载地址:
1https://github.com/zrong/skills/tree/main/spritesheet
- 文章ID:2878
- 原文作者:zrong(Jacky)
- 原文链接:https://blog.zengrong.net/post/ai-2d-sprite-animation/
- 版权声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,非商业转载请注明出处(原文作者,原文链接),商业转载请联系作者获得授权。