Uber Shader第1回「エフェクト用Shaderの統一化」
こんにちは、クライアントエンジニアの中田、エフェクトデザイナーの野本です。
今回は「Uber Shader」についてコロプラ独自のカスタマイズ、実際使ってみた時の使用感やメリットなどをご紹介します。
▼Uber Shaderを使用した炎エフェクト
Uber Shaderとは?
様々な機能をひとつのShaderにまとめたものです。
エフェクトのUber Shaderでは、エフェクトで使用する全ての機能が網羅されていますが、各エフェクトが使用する機能のみ処理を行い、使用しない機能は処理を行わないようにすることによって、多機能なShaderを必要最低限の負荷で使うことができます。
Shaderの種類は無限に増える
Shaderの種類が増えることで表現の幅が広がる一方、管理しきれないマテリアルが増えていったりしないでしょうか? 社内のとある運用タイトルではエフェクトのShaderだけで61個あります。
プロジェクトを運用していくと似たようなShaderが増え続けてしまいます。
例えば同じエフェクトのShaderでも、UVScrollがあるかないか、Cutoutがあるかないかで以下のShaderが必要になります。
・EffectUV
・EffectUVScroll
・EffectUVScrollCutout
・EffectUVCutout
このようにプロジェクトごとに必要な組み合わせが増えるたびに、エンジニアがShaderを追加していく必要があります。
また、各プロジェクトで量産していたShaderの中には人知れず高負荷なShaderも紛れ込んでしまい、ゲーム全体の負荷にも影響していました。
Shaderを統一化
Shaderが量産されてしまう問題を解決するために、エフェクトで使用する機能を一つのShaderにまとめました。
Shaderの機能一覧
各機能でON・OFFやModeの切り替えを行うために、shader_featureやmulti_compileという機能で、定義したキーワードごとに処理を分岐させます。
この時、分岐ごとに内部で別のシェーダーとして生成され、選択された分岐のみ処理を行うので、必要最低限の処理負荷で済みます。
shader_featureは使用されている分岐だけ、シェーダーを生成するため、シェーダーメモリを抑えることができます。一方でshader_featureでは実行時に処理を切り替えるような動的な分岐ができないので、それが必要な場合は全ての分岐を生成するmulti_compileを使用します。
Uber Shader統一化によるメリット
Shaderを実装するエンジニアにとっては、以下のようなメリットがありました。
・今までは僅かな機能の差があるShaderを大量に実装するコストがかかっていたが、Uber Shaderのおかげで、機能の追加、調整もひとつのShaderを変更すればよいため実装コストが削減できた
・他のプロジェクトへ移植する際は、Uber Shaderをそのまま使用すればいいので、新しくシェーダーを実装する必要がなくなった
Shaderを使うデザイナーの視点では、以下のようなメリットがあります。
・Shaderの場所や機能が統一されるのでプロジェクトが変わってもスムーズに作業に入ることができるようになった
・機能がUber Shaderに統一されているのでティーチングコストを削減することができた
・Uber Shaderを用いたエフェクト表現や技術をプロジェクトの垣根を越えて共有できるので会社全体の技術力向上につながった
制作例:炎エフェクト
炎エフェクトといえばHoudiniなどで連番素材を作ったりしますが、今回は連番素材を使わずにUber Shaderの機能で炎エフェクトを作っていきます。
テクスチャはベースとなる【BaseMap】【SubTexture】【SubTexture2】(赤枠)の3枚のテクスチャをAdditive、MUltiply、UVスクロール(緑枠)を使って組み合わせることができます。
・BaseMap →UVスクロールをするノイズテクスチャ
・SubTexture →UVスクロールをするノイズテクスチャ
・SubTexture2 →炎のシルエットを表現する為のマスクテクスチャ
炎全体が揺らぐ動きを付けたいので【Distortion or Flow】機能で歪みを追加していきます。
Distortion or Flowの効果をかける対象をチェックボックスで選ぶことが出来ます。
SubTexture2を歪ませることでエフェクト全体が揺らめいたので一気に炎感が出ました!
パラメーターを調整し煙や火の粉、照り返しのライトを追加してかがり火を制作。
炎のベースが出来たので次は地面で炎が燃え広がっていくようなエフェクトを制作していきます。
複数出したパーティクルのスケールやライフタイムでランダム要素を入れてみましたが、パーティクルのスクロールスピードが一定のため、同じテクスチャなのがバレバレです。
UVスクロールのスピードはテクスチャごとに用意されている項目の【UV Scroll】でランダムに設定することができます。流れるスピードが変わるだけでもかなりランダムな動きに見えます。
炎のシルエットにバリエーションを出すために【Texture Sheet Animation】を使用しますがSubTexture2だけではなくBaseMapとSubTexture、FlowMapにも影響が出てしまうのでTexture Sheet Animationの【Affecter UV Channels】で適用するUVを設定します。
適用させたいテクスチャに同じUVチャンネルを選ぶことでTexture Sheet Animationを反映させるか選べるようになってます。
パラメーターを調整し炎の動きをつめていき、パーティクルに燃え広がっていく動きを付けて完成です。
炎の熱波による空気の歪みや、炎で地面や草が焦げ広がっていく要素もUber Shaderを使用しています。
まとめ
今回はUber Shaderについて紹介させていただきました。
表現を作るために増えていたShaderがUber Shaderに集約されることでエンジニアとデザイナー両方に様々なメリットがありました。
エンジニアとデザイナーが協力して新しい表現を試していくのがコロプラ流です。
Uber Shader以外にもエフェクト関連のノウハウがあるので、今後もご紹介していきたいと思います。
引き続きよろしくお願いします!
コロプラでは"新しい体験"を一緒に創りだしていただけるクリエイターのご応募をお待ちしております!
https://be-ars.colopl.co.jp/recruit/