Akatsuki Hackers Lab | 株式会社アカツキ(Akatsuki Inc.)

Akatsuki Hackers Labは株式会社アカツキが運営しています。

モバイルで動くShaderでの流体表現


この記事は Akatsuki Advent Calendar 2020の25日目の記事です.
前回の記事は脆弱性診断時のAndroidのプロキシ設定を行うコマンドラインツールを作った話+その他内製ツールの紹介でした。

 

 

はじめに


新卒研修で流体を用いたスマホゲームをリリースする機会がありましたので,実装を紹介します.

具体的には,ミラーケーキ(ケーキの一種)を作成するゲーム内で,
ケーキに溶けたチョコをかけてコーティングする作業(グラサージュ)の実装です.

(実際のアプリ: iOS, Android

実際の動画


実際のゲームプレイ動画がこちらになります.この部分の実装方法を以下で説明していきます.

f:id:AxI:20201223125005g:plain
ちなみに実際のミラーケーキはこんな感じです.

実装

概要:ケーキの柄が変わってるだけ

モバイルで三次元流体表現を行うことはスペック上難しいので,二次元で液体挙動の近似計算を行い,影で立体感をつけることで上記の挙動を実現しています.
具体的には,ケーキオブジェクトのテクスチャをリアルタイムで変化させることで,ケーキの表面に液体が流れているかのように見せています.

f:id:AxI:20201224123839p:plain
ぱっと見,ケーキになにか物体が覆いかぶさっていくように見えますが,実はケーキの柄が変わっているだけです.

実装は主に3つのパートに分かれています.以下の処理はUnity×Shaderで実装されています.
1.液体の広がりを表現
2.液体の流れを表現
3.液体の立体感を表現

液体の広がり


液体の広がりでは,ミラーケーキでのグラサージュの特徴である,注いだ点からじわーっと広がる挙動を表現しています.

具体的には二次元上で液量を定義し,”ぼかし”(平滑化)を行うことで液体が多いところから少ないところへ広がる動きを計算しています.毎フレームShader上で周囲のピクセルの液量の平均をそのピクセルの次の値とすることで,下図のように注いだ点から周囲に広がり,付近の液量と影響しあう挙動となります.

f:id:AxI:20201223133432p:plain

上図において,液量2以上など,閾値以上の部分のみ液体が存在すると定義し,液体が存在するところは別のテクスチャを参照するとすることで下図のようになります.

f:id:AxI:20201223133450p:plain

液体の流れ


液体の流れでは,液体が流れていく方向へ色も移動する処理を行います.

先ほどの液体の広がりで用いた図を見ると,液体範囲の縁は閾値に近くなることがわかります.よって,閾値に近い部分に黄色をつけるとするならば,黄色は常に外側,つまり液体が流れていく方向へ移動することになります.
このように液量が似ているピクセルは似た色を参照するという仕組みにすることで,流れていく方向に色が移動しているような挙動になります.

f:id:AxI:20201223133505p:plain
具体的には,液体範囲が液体テクスチャを参照する際,テクスチャの参照座標を液量分ずらすことで,任意のテクスチャにおいて液量に伴い変動するマーブル模様が生成され.流体っぽい挙動を実現しています.(時間が経つと戻っていく など,実際の流体挙動とは大きく異なる部分があります)

f:id:AxI:20201223133516p:plain

液体の立体感


液体の立体感は,液体の広がりで計算された,液体が存在する範囲の周囲に影をつけることで表現されています.
具体的には,テクスチャ上で光の方向を定義し,液体が存在しない かつ 光の逆向きに隣接するピクセルに液体が存在するピクセルを黒くします.

f:id:AxI:20201223133532p:plain

f:id:AxI:20201223133542p:plain

影をつけることで一気に立体感が出たと思います.影と反対側にハイライトをつけることでより立体感,艶感がでます.
上記の三つの要素を合体させることでモバイルで動く流体表現を実装しました.

おわりに


実際のアプリリンクです.楽しんでいただけたら幸いです.

Mirror cakes - Apps on Google Play

Mirror cakes on the App Store

 

限定的な状況下の実装ですがみなさまの発想の助けになれば幸いです.
来年も,おもしろいがたくさん生まれますように,メリークリスマス.