本文へ移動
記事一覧

スプライトシートとPNG連番

スプライトシートとPNG連番、2Dゲームの書き出しにはどちらを選ぶ?

同じ96フレームの透過アニメーションをスプライトシート+JSONとPNG連番にし、容量、デコード後のメモリの基準、テクスチャ上限、適した用途を比較します。

AnimGen更新日 12 分で読める
同じ96フレームの透過動画をスプライトシート+JSONとPNG連番ZIPとして比較
目次

両方とも同じ透過アニメーションを保存できますが、使う工程が違います。2Dゲームの実行時には、アトラスが対象ハードウェアのサイズ制限内で、インポーターがフレーム領域を読めるなら、メタデータ付きスプライトシートを検討します。1枚ずつの検査、修正、差し替え、保管、再加工には PNG連番を残します。

シートが必ず省メモリで速いわけではなく、PNG連番も必ず96枚の別テクスチャを同時に読み込むわけではありません。違いを見るため、公開されている同じAnimGenアニメーションを実測しました。512 × 512のRGBAが96フレーム、24 FPS、4秒の戦士の斬撃です。

工程ごとに適した形式を考える

使用場面 最初に検討 理由 公開前の確認
2Dゲーム実行時 シート+JSON、またはエンジン用パッケージ 共通テクスチャと明示的な領域 最大テクスチャ、フィルタ、原点、時間、余白
フレームの修正・清掃 PNG連番 個々の画像を開いて交換できる 名前順、位置合わせ、Alpha、FPS
高解像度・長い動作 PNG連番または複数の小さなアトラス 巨大な1枚への詰め込みを避ける 読み込み方式、管理、時間情報
WebGLや多くの端末 実測上限以内のアトラス サイズを制御したテクスチャにできる 実際のGPU上限を問い合わせる
再加工できる制作元 PNG連番 可逆の独立フレームから派生可能 READMEやmanifestも一緒に保管

実務では二者択一にせず、独立フレームを検査可能な制作元として残し、ランタイム向けに1枚または複数のシートを作ることが多いでしょう。

同じ動画から作った2つの実ファイルパッケージ

等角投影の戦士の斬撃は、以前の透過形式比較にも使った素材です。両パッケージで96枚の順序は同じです。シートは固定の10 × 10グリッドで、96マスにフレームを置き、最後の4マスは透明です。JSONには96個の512 × 512領域を記録し、回転もトリミングも行っていないことを明示しています。

同じ96枚をスプライトシートとJSON、独立PNG入りZIPに梱包した比較

両方の表現をデコードしてフレームごとに比較しました。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

ZIPには96枚とREADMEが入り、展開後の全エントリーは14,550,491バイトです。PNG自体が圧縮済みなので、ZIPによる追加削減は約0.9%でした。この例ではシートのパッケージがZIPより 54.44%小さい 結果です。

両パッケージのダウンロードサイズとRGBAの未圧縮メモリ基準

54.44%は普遍的な圧縮率ではありません。透明領域、重複画素、細部、フレーム寸法、グリッド、PNGエンコーダー、ZIP設定で変わります。今回のシートは透明・類似領域をまとめて圧縮できましたが、別の動作では別の結果になります。

なお、PNG連番をZIPで配布するときのネットワークリクエストは1つであり、97回ではありません。「ファイルが多い」問題は主に展開、バージョン管理、編集、ランタイム処理に関わります。

ダウンロードが小さくても、メモリが少ないとは限らない

PNGの容量は圧縮された保存・転送サイズです。レンダラーは画素をデコードし、エンジンはプラットフォーム向け圧縮、mipmap、余白などを適用することもあります。

単純なRGBA8の基準なら次の通りです。

  • 5120 × 5120のシートは26,214,400画素 × 4バイトで、ちょうど 100 MiB。
  • 512 × 512の96枚は25,165,824画素で、全枚を同時にデコード・常駐させれば 96 MiB。
  • シートの未使用4マスが4 MiBで、差を説明できます。

これはPNG連番がランタイムで必ず96 MiB使うという意味ではありません。1枚ずつ、一部だけ、必要時だけ読み込んだり、デコード後に解放したり、ビルド時に再パックしたりできます。逆にエンジンが全フレームをメモリに置く場合もあります。ダウンロード容量からVRAMを推測せず、対象ビルドを測定してください。

複数のスプライトが1つのアトラスを共有するとバッチ処理しやすくなりますが、「1枚のアトラス=1回のDraw Call」ではありません。マテリアル、ブレンド、描画順、Shader、レンダラーの規則なども影響します。

最大テクスチャサイズを無視しない

今回のシートは5120 × 5120です。PNGとしてはダウンロードして閲覧できますが、モバイルやWebGL向けの保守的な4096 × 4096の基準を超えます。

5120角のシートと、4096以内の2枚に分けたアトラスの比較

Godotのテクスチャサイズの説明は広いプラットフォーム対応のため4096 × 4096超を避けるよう勧め、モバイルGPUにはこのサイズの制限が多いと述べています。MDNのWebGLのベストプラクティスも4096を広く利用可能な基準とし、デスクトップなら大きなものが使える場合があると説明しています。

4096は互換性の基準であり、全端末共通の絶対上限ではありません。UnityならSystemInfo.maxTextureSizeでハードウェア上限を読み、WebGLなら現在のコンテキストに問い合わせます。

js
const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);

512 × 512の96枚を保ち、アトラスを4096以内にするには、例えば以下の2枚に分けられます。

  • 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における1フレーム時間の整数近似です。長いアニメーションで厳密な同期が必要なら、丸めた整数を数学的に正確とせず、書き出しmanifestの正式なFPSまたは総時間を参照してください。

PNG連番ZIPのファイル名は順序を示し、READMEに24 FPS、固定キャンバス、推奨される下中央原点があります。しかしPNGファイル自身は順序、FPS、ループ、ゲームの状態を保存しません。この付随情報も一緒に保管します。つまりこれは画像形式だけでなく、メタデータの選択でもあります。

スプライトシートとテクスチャアトラスは近いが同一ではない

  • スプライトシートは通常、1つの動作のフレームを規則的な横列やグリッドに並べます。
  • テクスチャアトラスは異なる素材を混ぜ、透明な余白を切り、領域を回転させ、不規則な矩形で詰めることもあります。

今回の規則的なシートではトリミングも回転もなく、全フレームが512 × 512のキャンバスを保ちます。透明画素の一部は無駄になりますが、フレーム間の位置合わせと下中央原点は単純です。

密なアトラスは空白を減らせますが、インポーターは元サイズからのオフセット、トリミング、回転、パディング、縁の拡張を正しく扱う必要があります。無視するとキャラクターが跳ねたり、隣のセルをサンプリングしたり、継ぎ目が見えたりします。見た目だけ最も密な配置より、対象インポーターが安定して再現できる構造を選びます。

スプライトシートが向く条件

リアルタイム2D環境に入れる、実測したテクスチャ上限内、インポーターが領域と時間を読める、動作のフレームをまとめて使う、共有テクスチャがエンジンのバッチング・管理に合う、ファイルを誤って分割・欠落・並べ替えしたくない場合です。

Godotなら別のGodot 4導入実測をご覧ください。ランタイム向けの小さなシート、SpriteFrames、時間、原点、実際の再生を検証しました。1フレーム96 × 96の別パッケージなので、この記事の512 × 512サンプルの容量表には混ぜていません。

PNG連番が向く条件

個別フレームを直す、合成・エンコード・独自ツールが番号順に画像を読む、WebM・ProRes・シート・エンジン用パッケージを派生できる可逆の元ファイルを残す、1本が安全なテクスチャサイズを超える、ランタイムで必要な一部だけ読み込める、不具合が元画素・パッキング・取り込み・フィルタ・再生のどこにあるか調べる場合です。

1フレームだけ変わったときも独立ファイルならバージョン管理で比較しやすくなります。一方、名前、時間、キャンバス、原点を常に画像と同期させる必要があります。エンジンによっては取り込み後に再パックもします。

動画編集やWeb配信は別の基準で考えます。同じ素材を使うWebM Alpha、ProRes 4444、PNG連番の比較を参照してください。

堅実な書き出し手順

  1. パッキング前に使える動作範囲を選び、検査します。
  2. 独立したPNGフレームを確認・制作元として書き出します。
  3. Alpha、固定キャンバスの位置合わせ、順序、FPS、原点を照合します。
  4. 対象プラットフォームの最大テクスチャに合わせて出力解像度を決めます。
  5. 1枚または複数のシート、もしくはエンジン用パッケージにします。
  6. 小さなテストシーンで時間、フィルタ、縁、原点、ループ境界を確認します。
  7. 連番、JSON、manifest、検証済みの実行時パッケージを分けて保存します。

AnimGenのスプライトシート作成ツールでは、生成した動作または対応動画から有効範囲と枚数を選び、PNGフレーム、JSON付きシート、エンジン用パッケージを書き出せます。出力形式の説明には具体的な納品物があります。無料・有料の権限は現在の料金と書き出し条件に従ってください。

人やツールが独立フレームを必要とするならPNG連番を、検証済みランタイムが共有テクスチャと確かなメタデータを生かせるならシートを使います。両方が同じ制作フローの異なる段階で役立つなら、両方残しましょう。

画像の詳細