Unity 2021.2 のリリースでは、ユニバーサルレンダーパイプライン(URP)でのサーフェスオプションのサポートやカスタムインターポレーター、それにアーティストのワークフローとシェーダーのパフォーマンスを大幅に改善する Blackboard のカテゴリが追加されました。
このブログ記事では、過去にリリースした Unity プロジェクト「Viking Village」を使って、このプロジェクトで使用されているシェーダーの一部を、前述した新しいシェーダーグラフの機能を使って再現するプロセスをご紹介します。
最初にご紹介するのは、URP のサーフェスオプションのサポートです。この機能を使うと、Lit または Unlit のシェーダーグラフシェーダーのサーフェスオプションのプロパティをマテリアルインスペクターに公開することができます。「Allow Material Override」オプションを有効にすると、表面のタイプ、アルファクリッピング、シャドウなどの一般的なプロパティを、マテリアルインスペクターのレベルで選択できるようになります。今回のサンプルプロジェクト内で、このオプションを詳しく見てみましょう。
この Viking Village URP パッケージには、さまざまなマテリアルが含まれています。多くの場合、マテリアルごとに表面のオプション設定が異なります。しかし、マテリアルに使われているシェーダーは、あまり大きな違いがないかもしれません。グラフインスペクターに新しく追加された「Allow Material Override」オプションによって、マテリアルのインスタンスごとにシェーダーグラフの Surface Opiton をオーバーライドすることができます。これを使って、1 つのシェーダーグラフアセットを元に、異なる設定のマテリアルを作成することができます。
いくつかの例を見てみましょう。プロジェクト内で、Mat_fence_02.mat は、standard.shadergraph を使用しており、Mat_strawroof_01.mat は、standard_AlphaClip.shadergraph を使用しています。これは、standard.shadergraph のアルファクリッピング対応バージョンです。グラフのインスペクターで「Allow Material Override」オプションを有効にすると、同じシェーダーでも、マテリアルレベルでアルファクリップを制御することで、さまざまなバリエーションのマテリアルを作成することができます。
また、「Allow Material Override」オプションを有効にすると、マテリアルインスペクター上で Metallic と Roughness のワークフローと、Specular と Glossiness のワークフローを簡単に切り替えることができます。以下は、2 つのワークフローの違いを示す簡単な表です。詳しくは、こちらのページ をご覧ください。
プロジェクト内の Lit_SSS_Cutout.shadergraph を例に挙げます。このシェーダーは、プロジェクト内のさまざまな植物のマテリアルに使用され、デフォルトでは Metallic ワークフローに設定されています。シェーダーを使用しているある特定のマテリアルだけを Specular ワークフローに変換したい場合は、「Allow Material Override」オプションを有効にすると、シェーダーを使用している他のマテリアルには影響を与えずに、マテリアルインスペクターの設定を上書きすることができます。
さて、プロジェクトとシェーダーアセットの一部を理解していただいたところで、次はシェーダーグラフに追加された素晴らしい機能、カスタムインターポレーターをご紹介します。
カスタムインターポレーターを使うと、それが頂点データであるか頂点ステージで行われたカスタムされた計算の結果であるかに関わりなく、頂点ステージからフラグメントステージに情報を渡すことができるようになり、シェーダーのパフォーマンスを向上させることができます。
今回は、こちらのマスタースタックを紹介しているブログ記事から、水のシェーダーを借りてデモを行います。水のシェーダーを Viking Village の環境にうまく調和させるために、反射と屈折を追加します。
マスタースタックのデモとは違いますが、泡に改良を加え、水辺から離れた場所にも泡が出るようにしました。
Simple Noise ノードを使って UV をタイリングし、オフセット値を定めて、泡のテクスチャーに歪み効果を与えています。泡のテクスチャー自体は、RGB チャンネルを利用して、さまざまな密度の泡のテクスチャーを格納して作っています。よりリアルな結果を得るために、異なるチャンネルは別の方向に歪ませています。泡が固い感じにならないように、波の法線マップをマスクとして使用し、泡が自然に波に溶け込むようにしています。水辺から離れた場所にある泡の計算は、シェーダーのパフォーマンスを向上させるために、頂点ステージで行われます。
ここでは、シェーダーにおける法線マップのタイリングを見てみましょう。より波らしい結果を得るために、オリジナルのシェーダーは 2 つの法線マップを異なる方向にタイリングしており、計算はすべてピクセル単位で行われています。ここで、カスタムインターポレーターのサポートにより、UV タイリング部分を頂点ステージに移動させることができるようになりました。
カスタムインターポレーターの使用によるパフォーマンスの向上を確認するために、水のシェーダーのみを入れ替えた 2 つのビルドを作成しました。一方の水のシェーダーではカスタムインターポレーターを使い、もう一方では使用しませんでした。PIX を使って各ビルドのフレームをキャプチャし、GPUでのレンダリングコストを分析しました。非常に顕著な変化として、カスタムインターポレーターを使用したシェーダーでは、水のシェーダーの描画呼び出し時間が大幅に短縮され、33% も短くなっていることが挙げられます。
カスタムインターポレーターを使用する際に注意しなければならないのは、フラグメントステージで実行される操作は、頂点ステージで実行される操作よりも頻繁に実行されるということです。場合によっては、計算を頂点ステージに移すことで、ビジュアルから細かいディテールが失われることがあります。カスタムインターポレーター機能は、最大で 32 チャンネルまで対応しています。プラットフォームや GPU によって、インターポレーター変数の限界が異なります。詳しくは、シェーダーグラフのマニュアルをご覧ください。
シェーダーが複雑になってくると、無数のプロパティが存在するようになり、Blackboard 上でそれらを管理するのが困難になることがあります。新しく用意された Blackboard のカテゴリを使い、マテリアルのインスペクターで展開可能なセクションとして公開することで、Blackboard のプロパティをグループ化できるようになりました。
引き続き、水のシェーダーを例に説明します。シェーダーグラフ内の Blackboard で、すべての法線マップのプロパティを「Wave Normal」というカテゴリーにまとめました。そうすれば、シーンで作業しているときに、マテリアルのインスペクターでプロパティ値を調整したいときに、このグループに簡単に移動することができます。また、インスペクターのスペースを節約するために折りたたむこともできます。