しゅみぷろ

プログラミングとか

Splatoonの塗りみたいのを再現したい その6

はじめに

めっちゃまったりと進行してるインク処理についてめちゃくちゃ少しだけ進捗あったのでご報告。

f:id:es_program:20161006235916p:plain:w400

といってもTexturePaintに何かあったとかではなく、インクを実際に描画する側のシェーダーでインクに関していい感じに反射するようにしましたよということについてと、今後の展望についてメモがてら書いておきます。

今までの塗り処理まとめはイカに。

esprog.hatenablog.com

TexturePaintはイカに。

esprog.hatenablog.com

PBR(Physically-Based Rendering)

PBR(Physically-Based Rendering)は、 Lambert/Phongの反射モデルを用いるような従来のシェーディングとは異なり、物理現象として起こっている光学現象(光の反射・散乱・屈折・吸収など)を計測してより厳密に数式でモデル化したレンダリング手法です。

今回、インクの反射計算はPBRで行っています。

従来のモデルでは「ベースカラー」「スペキュラーマップ」「スペキュラーパワー」をパラメータとして計算を行っていましたが、PBRでは「アルベド」「メタリック」「ラフネス」をパラメータとして計算を行っていきます。

従来のモデルについて知識があれば、PBRについても容易に理解が得られるかと思います。 以下はシェーディングについて簡単にまとめた過去記事です。

esprog.hatenablog.com

また、PBRの概要を知るには以下の記事が役に立つと思います。

物理ベースレンダリング -基礎編- | Cygames Engineers' Blog

あと、PBR勉強のためのリンク集的なの見つけました。ありがたや。 まだ見てないけど、今度いっぱい読みたいです。

物理ベースレンダリング (PBR; Physically-Based Rendering) 理論に入門するためのリンク集 - graphics.hatenablog.com

今後

今後どんなのすれば、それっぽくなるかなーと。 考えてることをちょっと書き出してみたいと思います。

ハイトマップ実装

はやくしろよって感じですが・・・。やる気が起きればすぐにでも実装できます(。 どのくらい変わるのかはちょっとまだ未知ですが、きっともうちょっときれいになると思います。

アンチエイリアス

テクスチャペイントした際に、テクスチャサイズとスケール、キャンバスサイズに依存して、ギザギザしちゃったりします。 何個か方針はあるけどどうしようか迷い中です。

インクのスロープ移動

Splatoonでは壁についたインクが垂れるような処理が存在します。外力(重力など)をパラメータに、インクがマッピングされたテクスチャのハイトを参照し、外力の方向に垂れていくような処理を試作中です。ただ、TexturePaintの構造上、シェーダーでこの処理を行うことがかなり困難です。UVなんてどことどこ繋がってるかとか自由だし。シェーダーで行いたい場合、アーティストとの連携が必須になります(ちゃんとUV設定すること)。簡単な壁などのモデルなら、結構簡単にこの処理は実現できそうだと思ってます。

複雑なモデルの場合、もうゲームロジックで無理矢理Paint呼び出して垂れ下がらせればいいと思います(ぇ。 パフォーマンスがネックになりそうな予感がしそうですが、これが案外問題なかったりします(根拠もなにもないけど、でも、きっと、たぶん、おそらく、めいびー)。 というのも、CPU側で負担になるであろう処理がUV算出(とその他のゲームロジック)なので、UV算出については

esprog.hatenablog.com

こちらで紹介しているとおり、そこまでスペックが良くない環境でも、27k頂点で30fps以上は普通に出ます。 (ちなみに、本家がどう実装してるのかしりませんが、垂れ下がる処理は30fpsで動作してるとかなんとかどこかで見ました。)

これに加え、一度オブジェクト表面を取得してしまえば垂れ下がる場所はサーフェスがインクの垂れる方向に連続している場合、接空間から算出できます。

よって、UV算出ステップの「平面上に存在するかの調査」と「メッシュトライアングル内に存在するかの調査」が不要になり、既に求まっているトライアングルの頂点UVから指定座標のUVを補完して求めるだけでよくなります。メッシュの集合から該当するメッシュトライアングルを探す手間が省けるのでほぼノーコストになるも同然です(言い過ぎですが...)。

というわけで、CPUでスロープ移動計算やる場合も最適化を行えば結構速度出ると思います。

ちなみにサーフェスがインクの垂れる方向に連続していない場合の調査は既に求まっているメッシュトライアングルについてだけ「平面上に存在するかの調査」と「メッシュトライアングル内に存在するかの調査」を行えばいいので、こちらもメッシュの集合から該当するメッシュトライアングルを探す手間は掛かりません。

問題は、インクがスロープを移動する際にハイトを移動させるなど、凝ったことをしたい場合です。GPU(アーティストとの連携必須ver)であれば割りといい感じに解決できますが、CPUでどうするか。。。

ここらへんは実際やってみてどうなのかを見てみることも必要なので、一応どっちも実装できればしてみようと思っています。