こんにちは。情熱開発部プログラム課の安田です。
Youtubeで動画を視聴していると、よく「うまく線を引いて、コップの中に水を入れる」ハイパーカジュアルゲームの宣伝広告を見ます。この広告を見る度、あの手の流体表現は、どうやって実装すればいいのか気になっていました。
というわけで今回は、Unityを使ってハイパーカジュアルゲームでよく見かける流体表現を実現する「流体シミュレーション」を実装します。今回目指すのは、モバイルゲームで使える程度の簡易的な2Dの流体表現の実装であり、リアルな3Dの流体シミュレーションのための理論の理解や実装ではありません。そのため、理論的な話は避けて説明することを、予めご承知おきください。
RigidBody2Dを使って簡単な流体表現
「Happy Glass」というゲームの実況動画をみてみると、このゲームでは水を、沢山の丸い粒子で表現しているようです。丸い粒子の境界をぼかすことで、ただの丸を水のように見せています。
(※画像は【Happy Glass】#1 チャンネル登録の歌、爆誕!?│A.I.Games より)
ということは、水粒子として大量の円形スプライトを用意し、それらの境界をブラーなどでぼかしてやれば、流体を表現できそうです。物理演算はひとまずUnity標準のRigidBody2Dを使えばよいでしょう。
調べてみると、この手法で流体を表現しているチュートリアル動画がみつかりました。今回はその動画の通りに実装してみました。やってることは単純で、下図のとおり水粒子だけ別の縮小バッファに書き込んだあと、それをスクリーンサイズに拡大することで粒子をぼかしています。
実装したものがこちらになります。
これが水に見えるかというと、そんなことはないんですが、実験結果としてはぼちぼちでしょう。
こちらのサイトでは、粒子の境界をぼかすのに、Metaballを利用している事例が紹介されています。この方法だと、先に紹介したゲームとくらべても遜色ない出来の流体表現が実現できるようです。
【Unity】 簡単に水に近い表現を実現したい (Metaball) – KAYAC engineers’ blog]
流体シミュレーションを数値的に解く
先の手法では、水粒子の物理演算をすべてUnity標準のRigidBody2Dに任せていました。これでもハイパーカジュアルゲーム程度であれば、充分使えそうです。しかし、RigidBody2DはあくまでRigidBody = 剛体のための物理演算用コンポーネントです。物理的に正しい流体表現を実現するには、それ専用の物理演算を用意しなければなりません。
ナビエ・ストークス方程式は、流体の運動を記述する方程式です。この方程式を解くことができれば、物理的に正しい流体を描くことができそうです。
以下がそのナビエ・ストークス方程式です。
$$\rho\{\frac{\partial v}{\partial x}+(v\cdot\nabla)v\}=-\nabla P+\mu\nabla^2v+\rho f$$
む、難しい……。私の場合、色々記事を読んで、結果ヨビノリ先生のYoutube動画を見てようやくそういうことか飲み込めました。
ナビエ・ストークス方程式は解析的に解く(手で解けない)ことができません。ですので、流体の動きをシミュレーションしたいときは、この式を離散化して、コンピュータを使い数値的に解くことになります。
流体の振る舞いをシミュレーションする手法には、大別して「格子法」と「粒子法」の2つが知られています。
格子法は、事前に固定の格子点を用意して、その格子点での物理量(密度、速度など)を時間ステップごとに計算する手法です。
粒子法では、粒子の座標は変化します。時間ステップ毎に今注目する粒子の近傍にある粒子を探索して、それらとの関係式から次ステップの物理量を求めます。
今回は、粒子法を用いて2Dの流体をシミュレーションしてみることにしました。といっても、一から実装したわけではなく、「Unity Graphics Programming vol.1」を参考にして実装しています。こちらの本は少し前に完全無料で公開されていますので、興味のある方は是非リンクからダウンロードしてみてください。
実装したものが以下になります。RigidBody2Dを使って実装したものと比べて、流体っぽい振る舞いになっているのではないでしょうか。
まとめ
というわけで、Unityを使って簡単な2Dの流体シミュレーションを実装してみました。製品で使えそうなクオリティにはなりませんでしたが、流体シミュレーションに少しだけ触れて、とても楽しかったです。
将来的には、もっとクオリティの高い2Dの流体シミュレーションを、そして3次元のシミュレーションにも挑戦してみたいです。
参考資料
【Happy Glass】#1 チャンネル登録の歌、爆誕!? – YouTube
【Unity】 簡単に水に近い表現を実現したい (Metaball) – KAYAC engineers’ blog
Simple Liquid Simulation in Unity! – YouTube
[【大学物理】ナビエストークス方程式①(数学的・物理的意味)/全4回【流体力学】 – YouTube
IndieVisualLab/UnityGraphicsProgrammingSeries: 書籍「Unity Graphics Programming」シリーズのPDFコレクション
粒子法入門 – 丸善出版 理工・医学・人文社会科学の専門書出版社
【免責事項】
本サイトでの情報を利用することによる損害等に対し、
株式会社ロジカルビートは一切の責任を負いません。