はじめに:スマホで映画みたいなモクモクを出したい!🌟
こんにちは!✨
株式会社スパーククリエイティブ CTO 広本です。
普段はUnityとかUnrealEngineとかでグラフィックスとか最適化とかをやっています。
皆さんはゲームを作っていて、「リアルな炎🔥や、ふわふわの煙☁️を出したいな〜」と思ったことはありませんか?
でも、映画みたいな本格的な流体シミュレーション(ボリュメトリックレンダリング)って、PC向けでとっても重たいイメージがありますよね💦
「スマホで出したら端末がホッカイロになってFPSが一桁になっちゃう……」
そこで今回は!スマホでも余裕で 60FPS で動いちゃう、
超軽量で綺麗な流体エフェクトの作り方をご紹介します!
工夫を凝らしてデータサイズも極限まで圧縮しているので、スマホゲームやモバイルVRにもそのまま入れられちゃうかもしれません📱✨
初心者の方でも大丈夫!
順番に解説していくので、一緒に素敵なVFXを作ってみましょう💪

実際にモバイル上で動いている流体
AIで作ったふざけた導入でしたが、ここからは真面目に進めましょう。
本稿では、数百MBに及ぶ流体のキャッシュデータを、モバイルGPUの限られたVRAMやメモリ帯域に収めるために開発した「リアルタイムレンダリング特化型の非可逆圧縮パイプライン」について解説していきます。
1. 序章:愚直にリアルタイムシミュレーションを回してみる
「最近のスマホは性能が良いから、Compute Shaderでゴリゴリ書けばそのままリアルタイムで動くのでは?」
まずは物理ベースのアプローチです。
MacCormack法による移流や、Multigrid法とRed-Black SOR法を組み合わせた圧力ソルバーなど、本格的な「3Dナビエ・ストークス方程式ソルバー」をUnity上に構築し、Pixel 9aの実機で8個同時に回してみました。

画面を覆う8個の爆発。流体コストは1個あたり 5.43ms。FPSは26。
最適化の余地があるとはいえ、60FPS(16.6ms)が絶対条件のゲームにおいて、1個の処理に5.4msも消費するのは現実的ではありません。
そこで今回は、「PCのハイエンド環境でシミュレーションを行って高品質なデータを生成し、モバイル側は極限まで圧縮したデータの再生に特化させる」という、演算と描画のアーキテクチャを分離するアプローチを採用しました。
2. 生データ88MBを3.5MBに。驚異の「95.99%」圧縮ベイク
PCからボクセルデータを持ち込む際、一番の課題となるのがVRAMの容量です。
今回のパイプラインを適用した結果、以下のような圧倒的なデータ削減を実現できました。
📊 ボリューム情報
- 解像度: 64x64x64
- フレーム数: 22 frames (秒間 15fps)
- 再生時間: 1.5 秒💾 圧縮レポート
- 生データ換算: 88.00 MB
- 最終ファイル: 3.53 MB
- 圧縮率: 95.99% カット達成!
この圧倒的な削減率は、単なる力技ではなく、以下の最適化アルゴリズムの結晶です。
コア技術1:動的AABBとSparse Packing(空間の最適化)
解像度 64x64x64 のボクセル空間(約26万ボクセル)において、実は爆発や煙が初期段階で占める割合はごくわずかです。
フレームの8割以上は「完全な無(密度ゼロ)」であり、この余白を保存するのはVRAMの致命的な無駄遣いになってしまいます。
そこで、シミュレーション実行時に「流体が存在する最小のバウンディングボックス(動的AABB)」を毎フレーム算出するようにしました。
有効なブロックのみを抽出し、メモリ空間上に隙間なくパッキング(Sparse Packing)して出力しています。
これにより、煙が小さい序盤フレームのデータサイズを数KB単位まで劇的に削ぎ落としています。
コア技術2:視覚特性に基づく非線形カーブとベクトル量子化
PC環境の高精度なシミュレーションデータ(FP16)をモバイル向けに切り詰める際、単純な線形量子化を行うと、煙が消えゆくエッジ部分や炎のグラデーションに致命的な「バンディング(階調割れ)」が生じてしまいます。
流体のリアリティは、この微細なディテールにこそ宿るため、ここは妥協できません。
そこで、「人間の目は暗い(薄い)部分の階調変化に敏感である」という視覚特性を応用しました。
非線形マッピングを適用し、薄い密度帯域に高いビット解像度を割り当て、高密度なコア部分は粗く圧縮しています。
さらにベクトル量子化を組み合わせることで、4x4x4のボクセルブロック(密度、温度、速度ベクトル、AO)をわずか 108バイト の固定長データへと高密度に圧縮することに成功しました。
3. モバイルアーキテクチャ(TBDR)の限界を突破する
データ容量を極小化した後は、モバイルGPU(TBDRアーキテクチャ)における最大のボトルネック、「メモリ帯域幅(テクスチャの読み書き)」と「ALU(演算器)サイクル」の削減に挑みます。
GPU-Driven Tight Boundsによる「空振り」防止
空間全体を愚直にレイマーチングするのではなく、圧縮時に算出したAABB情報をコンピュートシェーダーへ転送しています。
「煙の境界外を飛ぶレイは、一切のテクスチャフェッチを行わず即座に破棄(Discard)する」という設計にすることで、描画負荷を画面解像度ではなく「流体の実際の体積」に完全に比例させることに成功しました。
FP16(half)精度の徹底
フラグメントシェーダー内の変数を極限まで half (min16float) に切り詰め、レジスタの圧迫を回避しています。
これによりALUスループットを最大化し、重い演算を物理的なリソース制限内に収めています。
4. 時間軸のハックで15FPSを60FPSへと昇華させる
データサイズを最小化するため、流体データのベースフレームレートは「15FPS」に設定しています。
しかし、これをそのまま再生してはユーザー体験を損なってしまいます。
そこで、流体データに内包された「速度ベクトル」を活用したオプティカルフローをGPU上で展開します。
隣接する過去と未来のフレーム間でピクセルを速度場に沿って歪ませることで、物理的に妥当な中間フレームを動的に生成(錬成)しています。
さらに、この速度場をスクリーン空間(UV)の移動量ベクトルへと変換し、URP標準のTAA(Temporal Anti-Aliasing)に入力します。
量子化やステップ間引きによって生じた微細なノイズは、TAAによる時間軸のディザリング効果によって視覚的に補完され、結果として15FPSの軽量データが「60FPSの極めて高品質な流体VFX」として画面に描き出されます。
5. 結論:モバイルでも流体シミュレーションは現実的な時代へ
ここまでの最適化手法をすべて統合したパイプラインを用い、Pixel 9aの実機で再度8個の爆発を発生させた結果がこちらです。


画面を覆う8個の爆発。流体コストは1個あたり 0.47ms。
初期のリアルタイムシミュレーション時(5.43ms)と比較し、1個あたりの描画コストを 0.47ms(約11分の1) へと劇的に削減することに成功しました。
これは、計算コストの事前オフロードと、ハードウェア特性に最適化された圧縮アルゴリズムの極めて有効な組み合わせを示しています。
適切なアーキテクチャ設計と最適化手法を講じることで、現在のモバイル環境においても、AAAタイトルに匹敵する流体表現が実用段階に到達したと言えます。
この記事が、制約の厳しい環境下で限界に挑むエンジニアやクリエイターの皆様のインスピレーションとなれば幸いです!🔥
おまけ:竜巻エフェクトにおけるシームレスループの裏側
冒頭でお見せした竜巻エフェクトのボリュームキャッシュの情報も載せておきます。

📊 ボリューム情報
• 解像度: 96x96x96
• フレーム数: 90 frames (秒間 60fps)
• 再生時間: 1.5 秒💾 レポート
• 生データ換算: 1215.00 MB
• 最終ファイル: 81.70 MB
• 圧縮率: 93.28% カット
このエフェクトはシームレスなループ再生を前提としています。技術的な留意点として、スカラー値(密度・温度)の単純なクロスフェードは可能ですが、オプティカルフローを駆動する「速度ベクトル」をベイク時に合成してしまうと、ベクトル空間が破綻し、ランタイムでの補間時に強烈なアーティファクトを引き起こしてしまいます。
そのため、本システムにおける完全なループの実現には、事前ベイクデータの合成ではなく、「再生時に2つのデータを同時に展開し、それぞれ独立してベクトル評価を行った上で最終合成する(デュアルプレイヘッド方式)」というアーキテクチャを採用しています。