
本文目录
精灵图和 PNG 序列可以保留完全相同的透明动画,但它们服务于不同阶段。面向 2D 游戏运行时,如果图集尺寸符合目标硬件限制,而且导入器能够读取帧区域,优先考虑精灵图加元数据。需要逐帧检查、修改、替换、归档或继续加工时,则应保留或导出PNG 序列。
精灵图并不会天然占用更少内存,也不会在所有引擎里都更快;PNG 序列也不等于运行时一定要加载 96 张独立纹理。为了把区别说清楚,我们使用同一段公开 AnimGen 动画进行实测:96 张 512 × 512 RGBA 帧,以 24 FPS 表现一段四秒的战士挥砍动作。
不同环节需要的格式不同
| 使用场景 | 更适合先选 | 原因 | 上线前检查 |
|---|---|---|---|
| 2D 游戏运行时 | 精灵图 + JSON 或引擎包 | 单张纹理和明确帧区域更方便导入与批处理 | 最大纹理尺寸、过滤、轴点、时间和图集留边 |
| 逐帧修改或清理 | PNG 序列 | 每一帧都能单独打开和替换 | 文件名顺序、画布对齐、Alpha 和 FPS |
| 高分辨率或长动画 | PNG 序列或多张小图集 | 避免把所有帧塞进一张超大纹理 | 加载策略、文件管理和时间信息 |
| WebGL 或覆盖更多设备 | 不超过实测限制的图集 | 目标渲染器更容易处理尺寸可控的纹理 | 查询真实 GPU 限制,不套用桌面端结果 |
| 可重复加工的生产源 | PNG 序列 | 无损独立帧可以继续派生其他格式 | 把 README 或 manifest 与图片一起保存 |
实际项目里最稳妥的方式往往不是二选一:用独立帧作为可检查的生产源,再为具体运行环境生成一张或多张精灵图。
同一段动画,两种真实文件包
本次使用的等轴视角战士挥砍动作,也用于此前的透明格式对比。两个文件包中的 96 张画布顺序一致。精灵图采用固定的 10 × 10 网格,其中 96 个格子存放帧,最后 4 个格子保持透明。配套 JSON 记录 96 个 512 × 512 帧区域,并明确所有帧都没有旋转或裁边。
可以直接检查本文使用的全部文件:
我们先解码了两种表示,再进行逐帧比较。96 帧的 Alpha 数值全部完全一致;在源图 Alpha 大于 8 的可见像素中,RGB 也全部一致。完全透明像素中的 RGB 字节不会影响合成结果,打包时还可能被归一化,因此没有把它们计入可见 RGB 对比。
这一步很重要:“同一段动画”不应该只表示缩略图看起来相似。上述检查确认,本次比较的变量是打包方式,而不是两套视觉结果。
下载体积与文件数量实测
这组样例得到的数据如下:
| 文件包 | 打开后的文件数 | 精确字节数 | 约合大小 |
|---|---|---|---|
| 精灵图 PNG + JSON | 2 | 6,573,057 | 6.27 MiB |
| PNG 序列 ZIP | 97 | 14,427,494 | 13.76 MiB |
PNG 序列 ZIP 包含 96 张帧图和一个 README。全部条目解压后共 14,550,491 字节;由于 PNG 本身已经压缩,ZIP 对条目数据只额外减少约 0.9%。在这一个样例里,精灵图文件包的下载体积比 ZIP 小 54.44%。
54.44% 不是通用的精灵图压缩比例。透明区域、重复像素、画面细节、单帧尺寸、网格布局、PNG 编码器和 ZIP 设置都会改变结果。一张排列紧凑的精灵图可能更好地压缩重复的透明或相似区域,换一段动画则可能得到不同结果。
还要注意:PNG 序列通过 ZIP 交付时,网络上下载的是一个文件,而不是发起 97 次 HTTP 请求。“文件很多”主要影响解压、版本控制、编辑流程和运行时处理方式,不能直接等同于 97 个网络请求。
下载更小,不代表内存一定更少
PNG 文件大小描述的是压缩存储或传输体积。渲染器通常需要先解码像素,引擎还可能应用平台纹理压缩、mipmap、留边或其他内部格式。
只按 RGBA8 做一个易于核对的基线:
- 5120 × 5120 精灵图包含 26,214,400 个像素,每像素 4 字节,正好是 100 MiB;
- 96 张 512 × 512 独立帧共有 25,165,824 个像素,如果全部同时解码并驻留内存,正好是 96 MiB;
- 精灵图多出的 4 个未使用格占 4 MiB,正好解释两者差值。
这不表示 PNG 序列运行时一定占 96 MiB。工具可以每次只加载一帧、按需加载一部分、解码后释放,或者在构建阶段重新打包;相反,引擎也可能把导入的全部帧同时保留在内存。应该测量目标构建,而不是用下载体积推算显存。
多个精灵引用同一张图集时,确实更容易参与批处理,但“一张图集”也不保证“一次 Draw Call”。材质、混合状态、排序、Shader、渲染器规则和其他状态切换仍会影响批次。
别忽略最大纹理尺寸
本文测量的精灵图尺寸是 5120 × 5120。它当然可以作为 PNG 下载和查看,但已经超过面向移动端与 WebGL 时常用的保守 4096 × 4096 基线。
Godot 当前的纹理尺寸说明建议,为了覆盖更多平台,应避免使用超过 4096 × 4096 的纹理,并指出移动 GPU 通常受这一尺寸限制。MDN 的 WebGL 最佳实践也把 4096 视为广泛可用的基线,同时提醒桌面设备可能支持更大的纹理。
4096 是兼容性基线,不是所有设备的统一上限。Unity 可以通过 SystemInfo.maxTextureSize读取目标硬件限制,WebGL 也可以查询当前上下文:
const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
对本文这组 96 帧素材,如果保持每格 512 × 512,同时要求图集不超过 4096,可以拆成:
- 一张 8 × 8、包含 64 帧的 4096 × 4096 图集;
- 一张 8 × 4、包含 32 帧的 4096 × 2048 图集。
拆分后,元数据必须说明每一帧属于哪张纹理。不要直接把 5120 像素的图集缩小,却继续使用旧的 512 像素帧区域;那会改变单格尺寸并让坐标失效。其他可行方式还包括减小输出帧尺寸、减少采样帧数,或使用会针对目标环境布局的引擎包。
元数据到底解决了什么
一张孤立的精灵图并不知道应该如何播放。使用方至少需要帧区域和顺序;具体项目还可能需要单帧时长、动作名、循环设置、源画布、轴点、偏移和纹理文件名。
本文使用的公开 JSON 包含:
- 从
frame_0000.png到frame_0095.png的键名; - 每一帧的
x、y、w、h区域; - 源尺寸与 Sprite Source Size;
- 每帧 42 毫秒的整数时长;
- 覆盖第 0–95 帧的
tactician_slash标签; - 精灵图尺寸与 RGBA8888 格式。
42 毫秒是 24 FPS 单帧时长的整数近似。如果项目需要严格的时间线同步,应读取导出 manifest 中的权威 FPS 或总时长,而不要假设经过取整的单帧整数在长动画中仍然数学精确。
PNG 序列 ZIP 具有明确的文件名,README 记录了 24 FPS、固定画布对齐和建议的底部居中轴点;但 PNG 文件本身不会保存动画顺序、FPS、循环行为或游戏状态。序列帧必须和这些旁路信息一起保存。
所以,“精灵图还是 PNG 序列”不仅是图片格式选择,也是元数据选择。
精灵图和纹理图集有关,但不完全相同
两种说法经常混用,不过可以这样理解:
- **精灵图(Sprite Sheet)**通常按照规则横条或网格摆放一段动画的帧;
- **纹理图集(Texture Atlas)**还可能混合不同素材、裁掉透明边缘、旋转区域,并用不规则矩形压缩空间。
本次测试使用规则精灵图。各帧既没有裁边,也没有旋转,因此始终保留同一个 512 × 512 画布。它会浪费一部分透明像素,但帧间对齐和底部居中轴点也更直接。
更紧凑的图集可以减少空白,不过导入器必须正确处理源尺寸偏移、裁边、旋转、留边和边缘扩展。忽略这些字段后,角色可能出现跳动、采到相邻格或产生可见接缝。应当选择目标导入器能够稳定还原的最紧凑结构;截图里的排列更紧凑,并不代表运行时也更可靠。
哪些情况更适合精灵图
以下情况优先使用精灵图加 JSON 或引擎包:
- 帧图将进入实时 2D 运行环境;
- 图集没有超过目标平台的实测纹理上限;
- 导入器能够读取帧区域和时间信息;
- 这段动作的帧通常会一起加载和使用;
- 共用纹理符合当前引擎的批处理与资产管理策略;
- 希望文件包不容易被误拆、漏帧或打乱顺序。
如果目标是 Godot,可以继续查看单独的 Godot 4 导入实测。那篇文章验证了针对运行时制作的小尺寸精灵图、SpriteFrames、时间、轴点和实际播放。它使用每帧 96 × 96 的引擎包,因此没有被混入本文 512 × 512 样例的体积表。
哪些情况更适合 PNG 序列
以下情况优先使用 PNG 序列:
- 美术需要修改或替换个别帧;
- 合成、编码或自研工具需要按编号读取图片;
- 希望保留一份无损生产源,继续派生 WebM、ProRes、精灵图或引擎包;
- 整段动画会超过安全纹理尺寸;
- 运行时可以只加载当前场景需要的帧或动作;
- 正在排查问题到底来自原始像素、打包、导入、过滤还是播放。
当只有一帧变化时,独立文件也更容易在版本控制中比较。代价是文件名、时间、画布和轴点必须始终与图片保持同步,而且部分引擎导入后仍会重新打包。
视频剪辑和网页交付需要另一套选择标准,可以查看同一素材的 WebM Alpha、ProRes 4444 与 PNG 序列实测。
一套更稳妥的导出流程
对游戏项目来说,可以按下面的顺序处理:
- 打包之前先选择并检查真正可用的动画区间。
- 导出独立 PNG 帧,作为检查或生产源。
- 确认 Alpha、固定画布对齐、帧顺序、FPS 和轴点。
- 根据目标平台的最大纹理尺寸选择输出分辨率。
- 为目标环境打包一张精灵图、多张精灵图或专用引擎包。
- 在小型测试场景中检查时间、过滤、边缘、轴点和循环端点。
- 分开保存帧序列、JSON、manifest 和已经验证的运行时文件包。
AnimGen 的精灵图制作工具可以从生成动作或受支持的视频开始,选择有效区间与帧数,再导出 PNG 帧、带 JSON 的精灵图或引擎包。输出格式说明列出了具体交付物;免费和付费格式权益则以当前定价与导出权限为准。
人和工具需要独立帧时,使用 PNG 序列。经过验证的运行时能够从共享纹理和可靠元数据中获益时,使用精灵图。两种格式分别服务于同一生产流程的不同阶段时,就把两种都保留下来。