フリップブックテクスチャ · 完全ガイド

フリップブックテクスチャ:Unity、Godot、VRChatでスプライトをアニメーションさせる方法

自分だけのフリップブックテクスチャを作成

フリップブックテクスチャは、1つのサーフェス上でスプライトシートを1フレームずつ再生するものです。Unity、Godot、VRChatで作成する方法を学び、3D空間で実際のスプライトシートをリアルタイムにめくってみましょう。

✦スプライト
次の素材からフリップブックテクスチャを作成:魔法のポータルのループ

フリップブックテクスチャとは、シェーダーが1つのサーフェス上で1フレームずつ再生するスプライトシートです。リグもタイムラインも不要で、シートはすべてのフレームを固定グリッドに格納し、マテリアルはそのグリッド上を一定速度で小さなウィンドウを移動させます。8 x 8のシートには64フレームが含まれ、毎秒12フレームなら約5.3秒で1ループします。メッシュは一切変化せず、テクスチャの再アップロードも不要で、アニメーション全体のコストはテクスチャ参照1回分です。

このページでは、フリップブックシェーダーが必要とする4つの数値と、フレームインデックスがUV座標にどのようにマッピングされるか、Unityでフリップブックテクスチャを駆動する2つの方法、VRChatアバターでPoiyomiフリップブックを設定する方法、GodotとPhaserにおける同等の方法、そしてGIFまたは記述から独自のシートを構築する方法について説明します。

簡単な回答

フリップブックテクスチャは、シェーダーアニメーションとして使用されるスプライトシートであり、時間の経過とともに行と列でインデックス付けされます。シートは1つのテクスチャスロットに配置されます。各シェーダー評価は、経過時間とフレームレートからフレームインデックスを計算し、そのインデックスを列と行に還元し、サーフェスUVをその単一セルに再マッピングします。Frame = floor(time * fps) mod frameCount、column = frame mod columns、row = floor(frame / columns)。10 FPSの6 x 6シートは、36フレームを3.6秒で循環し、すべてGPU上で行われ、フレームごとのアップロードやドローコールの変更はありません。

フリップブックテクスチャの仕組み

4つの数値がアニメーションを定義します。列と行はシートのレイアウトを記述します。フレームカウントは通常、列×行であり、インデックスがラップする値です。フレームレートはインデックスが進む速度です。その他すべて — フィルタリング、ラップモード、UVインセット — は、サンプラーが現在のセルの外を読み取らないようにするために存在します。

インデックスの計算は短く、書き出す価値があります。経過時間 t が与えられた場合:frame = floor(t * fps) mod frameCount、column = frame mod columns、row = floor(frame / columns)。UVウィンドウは、tiling = (1 / columns, 1 / rows) および offset = (column / columns, row / rows) となります。垂直方向は、人々がつまずく部分です。ほとんどのシート作成ツールは、画像の上部に row 0 を書き込みますが、Unity と Godot の UV 原点は左下にあります。Unity でトップ行ファーストのシートでは、offset.y は 1 - (row + 1) / rows となり、そうでないと行が反転して再生され、アニメーションの最初のフレームがシートの最後の行になります。

フィルタリングは、結果がクリーンであるかどうかを決定します。シートのラップモードを Clamp に設定します。Repeat の場合、テクスチャの右端のサンプルが左端を読み取るため、frame 0 のピクセル列がすべての行の最後のフレーム内に表示されます。ハードエッジのピクセルアートではミップマップをオフにします。ミップチェーンは隣接するセルを平均化し、サーフェスが数メートル離れるとアニメーションがぐちゃぐちゃになるからです。ターゲットエンジンまたはシェーダーがミップマップを強制的にオンにする場合は、各セルの周囲に1〜2ピクセルの透明なガターを残すか、UVウィンドウを4辺すべてで半テクセル内側にオフセットします。

値制御内容
列フレームを横に並べます。1つのセルの水平タイリングを設定します:1 / columns。
行シート内の行。垂直タイリングを設定します:1 / rows。ストリップの場合は1を使用します。
フレームカウントインデックス付けされる合計フレーム数。通常は columns x rows。インデックスはここでラップします。
FPSHow fast the index advances. floor(time * fps) gives the current frame.
Wrap modeClamp. Repeat lets the sampler read across the sheet edge.
Filter modePoint, with mipmaps off, or inset UVs by half a texel per cell.

Flipbook texture in Unity

There are two routes, and they fail in different ways. Route one is a shader that owns the row and column index and animates itself. Route two is the Animation window keyframing the material's tiling and offset while a plain Lit or Unlit shader does the sampling. Route one is better for effects that must stay in sync with game time; route two is better when you need the animation driven by an Animator state and visible in the timeline alongside everything else in the scene.

Either way, set the sprite sheet import first: Wrap Mode Clamp, Mip Maps off, Filter Mode Point, and no compression on pixel art. Those three settings cause more flipbook bugs than the shader math does.

Route 1: a shader with a row and column index

In Shader Graph, the Flipbook node takes Columns, Rows and a time-driven frame index and outputs the remapped UVs. In a hand-written shader, expose _Columns, _Rows and _Fps as properties and compute the cell in the vertex or fragment stage. If the animation has to be in sync across objects, drive the frame index from a script float rather than sampling _Time.y independently in every material, so two flipbooks on the same object cannot drift apart.

Route 2: the Animation window driving tiling and offset

This route animates the texture's _ST vector. Built-in Standard and Unlit use _MainTex_ST; URP Lit and Unlit use _BaseMap_ST. Tiling stays fixed at (1, 1 / rows) and only offset.y changes. The steps below apply to this route.

1

01

Select the material and open the Animation window. Create a clip, then add the texture's _ST vector property as a track — it appears as a Vector4 on the material.

2

02

Set the clip's sample rate to the same number as your target FPS. If the sample rate is lower than the FPS you want, keyframes collapse onto the same sample and the animation plays slower than intended.

3

03

フレームごとに offset.y をキーします。上段先頭のシートでは value = 1 - (row + 1) / rows、tiling = (1, 1 / rows) です。

4

04

カーブエディターで、すべてのキーフレームの補間を Constant に設定します。Linear では 2 つのセルがブレンドされ、両方のフレームが同時に見えてゴーストのように表示されます。

5

05

最後のキーが最初のフレームの値を繰り返さないようにしてください。そうしないと、ループの継ぎ目でアニメーションが 1 フレーム停止します。

6

06

複数のレンダラーが同じマテリアルを共有している場合は、renderer.material を読み取る代わりに、レンダラーごとに MaterialPropertyBlock をアニメーションさせます。renderer.material は初回アクセス時にマテリアルを複製し、そのクローンはオブジェクトの生存期間中ずっと残ります。

VRChat 向け Poiyomi Flipbook

Poiyomi シェーダーの Flipbook セクションは、マテリアル自体の上で UV ウィンドウをシート上でスクロールさせるため、1 つのマテリアルスロットでアバターのメッシュにアニメーションするスプライトを表示できます。Rows、Columns、フレームレートが公開されており、さらに shader time に任せるのではなく、フレームインデックスを自分で制御するモードもあります。

グリッドではなく、単一行のストリップを使用します。ストリップでは、シェーダーがステップする軸が 1 つになるため、縦方向の継ぎ目が完全に除かれます。グリッドの場合、UV ウィンドウは各行の終わりに次の行へ移動する必要があり、その境界でのフィルタリング、ミップレベル、半テクセルの丸め誤差によって隣接する行がサンプリングされます。これは再生中に別のフレームの細い帯として見えます。ストリップではフレームインデックスも単純な乗算になります。UV でのフレーム幅は 1 / frameCount で、オフセットは frame / frameCount だけです。256 x 256 セルの 8 フレームアニメーションでは、ストリップは 2048 x 256 となり、2 の累乗のままです。

アルファは、フラットなシーンよりもアバター上でより重要になります。スプライトにハードエッジがある場合は、Cutout または Opaque を使用します。Transparent キューの Flipbook は深度を書き込まず、アバター上では身体や互いに対してソートされ、その結果はカメラアングルによって変わります。可能な限り、アニメーションする表面はすでにアバターにあるマテリアル上に保ってください。余分なマテリアルスロットは 1 つごとにアバターのパフォーマンスランクに影響します。フレームインデックスを同期パラメーターを持つ Animator state から駆動する場合、すべてのクライアントが同じフレームを見ます。shader time から計算されるフレームインデックスはローカルで評価されるため、視聴者ごとにループ内の異なる位置になることがあります。

1

01

フレームを 1 本の横方向ストリップとして書き出します。ストリップの高さはセルの高さと同じで、ストリップの幅はフレーム数 × セル幅です。末尾に余分なセルを残さないでください。

2

02

テクスチャを Wrap Mode Clamp、Mip Maps オフ、sRGB オンでインポートします。Alpha Is Transparency は、ストリップが実際にアルファを持つ場合にのみ有効にします。

3

03

Poiyomi マテリアルを作成し、アニメーションするメッシュに割り当てて、Flipbook セクションを開きます。

4

04

Rows を 1 に、Columns をフレーム数に設定します。フレームレートを目的の再生時間に合わせて設定します。8 FPS で 8 フレームなら 1 秒のループです。

5

05

フレームソースを選択します。Manual モードでは、Animator state から駆動するフレームインデックスが公開されます。time-driven モードは自動でループします。

6

06

Rendering で、ハードエッジのスプライトには Cutout または Opaque を設定します。Transparent はソフトエッジのエフェクト専用に残し、深度ソートの癖があることを想定してください。

7

07

ループを確認します。最後のフレームが最初のフレームの複製であってはいけません。複製だと、スプライトが毎サイクル 1 フレーム停止します。

8

08

アップロードしたアバターで、ミラーを使い、近距離からインスタンス全体の距離までテストします。ミップマップとフィルタリングの問題は距離によって現れます。

Godot & Phaser でのフリップブック

Godot 4 の 2D では、AnimatedSprite2D と SpriteFrames リソースを使用するのが正攻法です。シートをインポートし、SpriteFrames を開き、Hframes と Vframes を列数と行数に設定し、アニメーションのフレームを追加した後、アニメーションの速度をフレーム毎秒で設定し、Loop を有効にします。SpriteFrames はアニメーションをフレームインデックスのリストとして保存するため、グリッドシートでも単一のストリップでも、UV 計算を自分で行うことなく動作します。

アニメーションが 1 つだけ必要な場合は、通常の Sprite2D の方が軽量です。Hframes と Vframes を一度設定し、整数の frame プロパティを AnimationPlayer からステップ補間で進めます。デフォルトのイージングカーブで frame をトゥイーンしないでください。値は整数インデックスであるため、補間すると単一の値に丸められるか、2 つのセル間でちらつきます。

Godot で 3D サーフェス上のフリップブックを実現するには、Unity 版と同じ行・列の計算を行う ShaderMaterial が最短経路です。uv = UV * vec2(1.0 / cols, 1.0 / rows) + vec2(col / cols, row / rows) とし、行はフレームインデックスから計算します。Godot の UV 原点は Unity と同じ左下であるため、最上行から始まるシートには同じ垂直反転が必要です。

Phaser 3 では、シートは一度読み込まれ、読み込み時に分割されます。frameWidth と frameHeight がセルを定義し、frames は左から右、上から下へ番号が振られ、アニメーションは座標ではなくフレーム番号で識別されます。シェーダーを書く必要も、間違えようのない行・列の計算もありません。

エンジン対象設定内容
Godot 4AnimatedSprite2D + SpriteFramesHframes と Vframes をシートのレイアウトに合わせて設定し、アニメーション速度を FPS で指定して Loop を有効にします。
Godot 4Sprite2DHframes と Vframes を一度設定し、整数の frame プロパティを AnimationPlayer でステップ補間しながら進めます。
Godot 43D メッシュ上の ShaderMaterialシェーダー内の列、行、フレームインデックス。Unity と同じ UV リマップと垂直反転を使用します。
Phaser 3this.load.spritesheetframeWidth と frameHeight。Phaser はシートを左から右へ、上から下へと分割します。
Phaser 3this.anims.createフレームは anims.generateFrameNumbers から取得し、frameRate と repeat: -1 でループします。

3D でスプライトシートをリアルタイムに反転する

このセクションのプレイアブルシーンは The Cyclops' Island で、Neta Studio の 3D ゲームビルダー上で動作します。画面のフリップブックは上記と同じインデックスから UV への変換を GPU 上の Three.js シェーダーで評価したもので、違いは実際のメッシュが実際のシーン上で動作し、操作可能なカメラと動くライトが存在する点です。

これは言葉の印象以上に重要です。フラットな Unity シーン内のフリップブックは通常正面から見られるため、シームの滲みやミップの混色は確認しにくくなります。アニメーションするサーフェスに対して斜めの角度からカメラを動かすと、問題はすぐに現れます。フレーム端に隣接セルの帯が見える、最後のミップレベルが 2 つのフレームを平均してぼやける、あるいはアルファのエッジが正面からは正しく見えて側面からは消える、といった具合です。ブラウザビルドでは、シートを制作してからサーフェス上で確認するまでのループが、ビルドステップなしで反復できるほど短くなります。

Mini World は単一のシートをテストするためのより小さなシーンで、メッシュ数が少なく読み込みも短時間です。Agent Sprite Forge はシートがまだない場合にフレームを生成します。どちらのシーンも同じフリップブックの経路で動作するため、Mini World で正しく見えるシートは The Cyclops' Island でも同じように動作します。

Mage cast — 4 フレームのストリップ。まさにフリップブックシェーダーが求める入力です。

自分のシートを作成する

使用可能なシートにたどり着く経路は 3 つあります。既存の GIF を変換する、グリッドを切り出して 1 本のストリップにする、記述からフレームを生成する、のいずれかです。3 つとも同じファイルに収束します。すべてのセルが同じサイズで、左から右、上から下へと配置され、シートの幅がセル幅の整数倍である 1 枚の PNG です。

GIF の変換は最も手間の見えにくい経路です。GIF は完全なフレームの連続ではないためです。フレームは前のフレームに対する部分的な差分であることが多く、遅延はフレームごとに 100 分の 1 秒単位で保存されます。フリップブックシェーダーは 1 つのフレームレートしか受け付けないため、可変のタイミングは書き出し前に重複フレームへと平坦化する必要があります。

グリッドからストリップへの切り出しは機械的な作業です。必要な行を残し、高さを 1 セルに切り詰め、幅はフレーム数 × セル幅のままにします。グリッドシートを単一のアニメーションとして使う場合に適した方法で、垂直方向の軸とそれに伴うシームを排除できます。記述からの生成は 3 つ目の経路です。Agent Sprite Forge はアクションとフレーム数を受け取り、固定のセルサイズでシートを返すため、1 フレームずつ書き出したものを手作業で位置合わせする必要がなくなります。

1

01

エクスポートする前に、すべての GIF フレームを平坦化してください。各フレームを、前のフレームを引き継ぐキャンバス上にデコードします。そうしないと、画像ではなく差分矩形をエクスポートすることになります。

2

02

タイミングを正規化してください。GIF の遅延から最短値または中央値を選び、元のフレームがより長く保持されていた箇所にはフレームを複製して、シートが一定の FPS で再生されるようにします。

3

03

フレームは左から右、上から下へ配置し、すべてのセルを同じサイズにしてください。シートの寸法はセルサイズの正確な倍数にします。幅が 9.5 セル分になるシートは、常に誤ったテクセルをサンプリングし続けます。

4

04

ストリップに切り出すには、高さを 1 セルにクロップし、幅はフレーム数 × セル幅に保ってください。元のグリッドに空の末尾セルがある場合は削除します。

5

05

ターゲットのエンジンでミップマップを無効にできない場合は、各セルの周囲に 1~2 ピクセルの透明なガターを追加してください。そうでない場合は、UV ウィンドウを四辺すべてで半分のテクセル分内側に縮めます。

6

06

変換ではなく生成するには、アクション、フレーム数、向きを記述し、1 フレームずつエクスポートして手作業で位置合わせするのではなく、Agent Sprite Forge から固定セルのシートを返させます。

7

07

エンジンでフレームインデックスを 1 つずつ進めて確認してください。いずれかのセルの端に隣接セルの欠片が見える場合、間違っているのはシートのレイアウトまたは UV インセットであり、シェーダーではありません。

The Cyclops' Island — ライブ 3D シーン内のサーフェス上で再生されるフリップブック アニメーション。

それが属する世界に足を踏み入れてください

スプライトとは、立つ場所を持たないキャラクターです。最後のステップは、他では提供されていないものです。作成したばかりのシートを、誰かが歩き回れる世界に配置します。小さな島、惑星、雨の降る街角などです。このサイトのすべての世界は、1 つの記述文から作られ、プレイできるページとして公開されています。

FAQ

Poiyomi フリップブックとは何ですか? +

これは Poiyomi シェーダーの Flipbook セクションです。マテリアル上で UV ウィンドウをスプライトシートに沿ってスクロールさせ、1 つのマテリアルスロットでアバターメッシュにアニメーション スプライトを表示できるようにします。Rows、Columns、フレームレートを設定し、フレームインデックスをシェーダー時間で進めるか、Animator ステートから駆動します。行間の縦方向の継ぎ目がなくなるため、単一行のストリップが推奨されます。

GIF を直接フリップブックすることはできますか? +

いいえ。GIF はフレームごとの遅延を保存し、多くの場合、変更されたピクセルだけを保存します。一方、フリップブック シェーダーは 1 つのテクスチャと一定のフレームレートを前提とします。まず変換してください。すべてのフレームを前のフレームに重ねて平坦化し、タイミングを正規化し、結果を固定セルグリッドに書き込みます。シェーダーが GIF を参照することはありません。

フリップブックのテクスチャがフレーム間でにじむのはなぜですか? +

サンプラーが現在のセルウィンドウの外側を読み取っています。テクスチャのラップモードをClampに設定し、ハードエッジのアートではミップマップをオフにし、UVウィンドウを各辺で半テクセル内側に寄せてください。にじみは距離が離れるほど悪化します。その距離では、ミップチェーンが隣接するセルをまとめて平均化し始めるためです。

フリップブックではどのフレームレートを使用すべきですか? +

8~12 FPSは手描きアニメーションのように見え、キャラクタースプライトに適しています。24~30 FPSは、炎、水、その他の連続エフェクトに適しています。シェーダーにはレートが1つしかないため、元のソースが可変タイミングだった場合は、ループ途中で速度を変えようとするのではなく、一致するようにフレームを複製してください。

グリッドは必要ですか、それとも1行で十分ですか? +

シーケンスとして再生されるものには1行で十分であり、シームエラーの軸を1つ取り除けます。グリッドは、複数のアニメーションを1つのテクスチャに詰め込むシート向けで、シェーダーまたはエンジンが idle、run、attack の行を選択します。グリッドシートからアニメーションが1つしか得られない場合は、ストリップに切り詰めてください。

フリップブックはUnity URPのLitシェーダーで動作しますか? +

そのままでは動作しません — URP Litにはフレームインデックスがありません。Columns、Rows、時間駆動のインデックスを受け取るFlipbookノードを備えたShader Graphを使用するか、マテリアルの_BaseMap_STのタイリングとオフセットをConstantのキーフレーム補間でアニメーション化してください。Built-inのStandardとUnlitは、同じ規則で_MainTex_STを使用します。

3D Game Builderに戻る

完成した31点の3Dワールド、ゲーム、シーンはすべて1ページにまとまっており、そのすべてがプレイ可能です。

プラットフォーム: Neta Studioページ: フリップブックテクスチャ:Unity、Godot、VRChatでスプライトをアニメーションさせる方法次に読む: /explore/tool/gif-to-flipbook · /explore/tool/gif-to-sprite-sheet · /explore/guide/sprite-sheet

スプライトアセットライブラリを開く

このライブラリのすべてのアセットは、プロンプトが記録された透過 PNG で、ゲームですぐに使える形式です — スプライトシートリソースと無料スプライトシートは、アクション、スタイル、主題でタグ付けされています。閲覧とダウンロードは無料です。

×