シェーダーグラフで実験しよう:少ないリソースで多くのことを実現する

物理ベースレンダリング(PBR)マテリアルの情報を単一のテクスチャマップにまとめたり、レイヤー化してコンパクトなシェーダーに落とし込んだりして、グラフィックス品質を落とすことなく、実行時の効率を高めることができます。本記事ではそのことを検証した実験について解説を行いました。ぜひこの後の内容をお読みください。
この実験は、ユニバーサルレンダーパイプライン(URP)と HD レンダーパイプライン(HDRP)の両方に適用できます。この記事を最大限に活用するためには、シェーダーグラフにある程度慣れている必要があります。初めてシェーダーグラフを使用する方は、このツールが視覚的にシェーダーをオーサリングするためのツールということをまず念頭に置いていただいたうえで、ツールの紹介ページと詳細の解説をご覧ください。
地形のような環境でアートアセットを扱う場合、より良いブレンド結果が得られるため、一般的には複数のタイリングして使えるマテリアルを重ねて使用することが好ましいとされています。しかし、複数のテクスチャをサンプルする時の GPU パフォーマンスのコストや、シェーダーに追加された各レイヤーでのメモリ使用量の増加は、一部のデバイスではカバーしきれないほどのものであり、また、一般に非効率です。
今回の実験の狙いは以下の通りです。
- 少ないリソースで多くのことを実現する
- メモリフットプリントを最小化し、PBR マテリアルを表現する際のテクスチャサンプリングを簡素化する
- シェーダー命令の数を最小化する
- 最小限のスプラットマップおよび頂点カラーチャンネルでレイヤーブレンディングを実現する
- スプラットマップおよび頂点カラーの機能を拡張して、いくつかおまけ機能を実現する
実験は目標を達成しましたが、いくつか注意点があります。どのトレードオフを許容するか決定する際に、自身のプロジェクトの要求に応じて優先順位を設定する必要があります。
レイヤー化を行う前に、まず最初にしなければならないことは、PBR マテリアルのパッキングを把握することです。PBR マテリアルは通常、アルベド(ベースカラー)、スムースネスマスク、アンビエントオクルージョン、メタルネス、法線のパラメーターが定義されています。
通常、5 つのマップすべてを 3 つのテクスチャマップで表現します。テクスチャの使用量を最小限に抑えるために、今回の実験ではメタルネスとアンビエントオクルージョンを犠牲にすることにしました。
残りのアルベド、スムースネス、法線の各マップの定義は、伝統的に少なくとも 2 つのテクスチャマップで表現されてきました。これを 1 つのマップに減らすには、各チャンネルの前処理が必要です。

PBR マテリアルを 1 つのテクスチャにパックした最終結果は上の画像のようになります。それぞれのチャンネルは以下のデータを表します。
Red = 法線の定義数に対する dHdu(U 軸方向の高さの導関数)
Green = 法線の定義数に対する dHdv(V 軸方向の高さの導関数)
Blue = アルベドを表す線形グレースケールのシェード(シェーダーで再構築される色情報)
Alpha = 線形スムースネスマップ(標準的なスムースネスマップ)
注意:テクスチャは sRGB のチェックを外した状態で Unity にインポートし、BC7 形式で圧縮しています。他のプラットフォームに移植する場合は、プラットフォームがサポートしている同等の 4 チャンネルテクスチャ形式に切り替えてください。
マップを処理する
アルベド
アルベドは通常、RGB テクスチャとして定義されますが、多くの地形のようなマテリアル(岩、砂、泥、草など)は限られたカラーパレットで構成されています。アルベドをグレースケールのグラデーションとして保存し、シェーダーでそれをカラーリマッピングすることで、この特性を利用することができます。
RGB アルベドをグレースケールのグラデーションに変換するための定番の方法はありません。この実験では、元のアルベドマップチャンネルとアンビエントオクルージョンを選択的にマスクしてグレースケールアルベドを作成しました。シェーダーでの色の再構成によって現れる色をマッチさせるには、手動で調整した結果を目測するだけです。

スムースネス
スムースネスは PBR マテリアルの定義において非常に重要であると考えられています。スムースネスをより正確に定義するために、スムースネス専用のチャンネルが存在します。 シェーダーのスムースネスに単純な乗算器を追加して、マテリアルに多少のバリエーションを持たせるようにしました。

法線マップの定義
法線マップは、表面の詳細な特性を示すために重要です。典型的な PBR マテリアルでは、接線空間法線マップを使用します。この実験では、以下の理由から、表面勾配フレームワークを使用した事前変換済みの導関数マップを選択しました。詳細は Morten Mikkelsen による表面勾配フレームワークに関する記事を参照してください。
接線空間法線マップを導関数マップに事前変換するには、この Photoshop アクションを使用します。
事前変換済み導関数マップを使うことにはいくつかの利点があります。
- シェーダー内で導関数への変換が必要な標準的な接空間法線マップよりも少ない命令数で、表面勾配マップに直接変換できます。
- 2 つのチャンネル(dHdu と dHdv)に保存することができ、実行時のメモリとテクスチャキャッシュのフットプリントを削減することができます。
- 表面勾配フレームワークが法線の再構成を行うので、接線空間法線マップを処理する際に典型的に必要だった、シェーダーでのブルーチャンネルの再構築が必要なくなります(シェーダー命令が少なくなります)。
- Photoshop で強度をブレンドしたり、マスクしたり、減らしたりして調整した場合にも正しく動作し、かつ正規化を再度行う必要がありません。たとえば、強度を下げるにはマップに対して RGB(128,128,0) をブレンドするだけです。
表面勾配フレームワークと組み合わせると、さらに以下のような利点が生じます。
- 法線バンプマップの情報は、アルベドのブレンドおよびコンポジットと同じようにシェーダーでブレンドとコンポジットができ、正しい結果が得られます。
- バンプマップの寄与を増やしたり、減らしたり、逆転させたりすることが簡単かつ正確にできます。
ただし、接空間法線マップから事前に変換された導関数には、いくつかの欠点もあります。
- Photoshop 変換を使用すると、8 ビットテクスチャの精度のバランスを取るために、角度が 45 度を超える範囲では法線の定義がクランプされます。
- アーティストは接空間の法線マップでの作業に慣れているので、ワークフローの一部として Photoshop を介してマップを事前に変換する必要があります。
注:45 度を超える角度でのクランプは、シェーダーベースの導関数変換には適用されません。
ユースケースに応じて、制限の影響の程度は変わります。今回の実験では、45 度未満の法線方向は、最終結果に目立った悪影響を及ぼしません。それどころかこの場合、極端な法線方向からの不要な反射を減らすという利点があります。





完全なアンパックの手順



この実験では、単一チャンネルの再マップに関して、層ベースで重ね合わせを行う方法を選択しました。サブグラフは、5 つの線形補間を実行します(ベースを加えて、6 つのレイヤーを形成します)。 レイヤーの重みづけをブレンドする方法はたくさんあります。この方法は、単一のベクトル入力で済むという単純さがあり、これは実験の目標と合致しています。これにより、スプラットマップまたは頂点チャンネルの複数のチャンネルを使い切ることなく、多くのレイヤーの重ね合わせが可能になりました。
この方法の欠点は、個別のレイヤーの寄与の重みを制御できないことです。ブレンディングは常に前のレイヤーからの遷移になります。ユースケースによっては、これは従来のチャンネルごとのブレンドと比較して制限を与える要因になることもあります。




レイヤーブレンディングに必要なのは、チャンネル 1 つ(赤の頂点チャンネル)だけです。残りの 3 つの頂点チャンネルは、追加の機能を提供します。
最終的なシェーダーグラフは、残りの頂点チャンネルを使用して結果を生成します。
この実験では、Polybrush(パッケージマネージャーから入手可能)を使用して Unity エディター内で頂点ペイントを実行しました。
このシェーダーで推奨される VertexPaint カラーパレットは以下の通りです。
赤:レイヤーの寄与を重み付けするために使用されます。
赤の頂点チャンネルでペイントを行うデモ
緑:表面のグラデーションプロパティを設定して、法線バンプの寄与を反転、削減、または追加します(-1 および 1 に再マップされます)。
- 0 は法線バンプを反転します(-1)
- 0.5 は、法線バンプをゼロにします(0)
- 1 は、法線バンプを元の値(+1)に設定します
緑の頂点チャンネルでペイントを行うデモ
青:スムースネスと表面のグラデーションバンプスケールを制御して、水で湿った外観を作成します
- 0 = 変更なし
- 255 = 最大のスムースネスとフラットな法線マップ(湿った外観)
青の頂点チャンネルでペイントを行うデモ
アルファ:アルベドレイヤーの重みを制御し、ベースカラーを白に設定します。寄与は表面の法線の y 軸に基づいています。スムースネスを変えることはなく、元の表面レイヤーのスムースネスとバンプのプロパティを利用します。
- 0 = 雪なし
- 255 = 完全に雪で覆われている
すべてのレイヤーが雪とどのように相互作用するかを示すために、ここまで示した 3 つのチャンネルと組み合わせてアルファ頂点チャンネルでペイントを行う
上記の様々な頂点ペイントチャンネルの結果を組み合わせたものを以下に示します。
プロジェクトの要件に応じて、シェーダーのブレンド方法と頂点チャンネルおよびスプラットマップのさまざまな機能の設定を調整できます。
この実験の目的は、リソースを最小限に抑えながら、シェーダーグラフの機能を拡張することでした。テクスチャは前処理されてアンパックされましたが、実行時の効率への見返りはあるでしょうか。
パフォーマンスプロファイリングは、これらの取り組みが生み出した効率を示しています。
コンパクトな 6 つのレイヤーからなるブレンドシェーダーと比較するために、標準的な 6 つのレイヤーを持つブレンドシェーダーを作成しました。両方のシェーダーは、同じ機能を持つ同じブレンド方法を使用して作成されました。主な違いは、標準のシェーダーが 3 つの異なるテクスチャを使用して単一のレイヤーを表すことです。 プロファイリングでは、ターゲットプラットフォームでユニバーサルレンダーパイプラインを使用して、ブレンドされたマテリアルを使用して単一のメッシュを画面にレンダリングしました。
モバイルメモリとパフォーマンスプロファイル
モバイル用のテクスチャ圧縮(Android):
モバイル用の 1024×1024 のアルベド、マスク、法線マップを備えた標準 PBR:
- 6 枚のアルベドマップ ASTC 10x10 = 6 x 222.4 KB
- 6 枚のマスクマップ ASTC 8x8 = 6 x 341.4 KB
- 6 枚の法線マップ ASTC 8x8 = 6 x 341.4 KB
テクスチャの合計メモリ使用量 = 5.431MB
モバイル用の 1024×1024 のコンパクト PBR:
- 6 枚の PackedPBR テクスチャ ASTC8x8 = 6 x 341.4 KB
テクスチャの合計メモリ使用量 2.048MB
コンパクトな 6 つのレイヤーからなるマテリアルにより、モバイル(Android)でのテクスチャメモリ消費量が約 62% 削減と、半分以上のメモリが節約されました。 Adreno 630(Snapdragon 845)を搭載したモバイル Android / Vulcan で、Snapdragon プロファイルを行った結果::
- 実行時のテクスチャメモリリードが約 70% 少なくなりました。
- 標準的なマテリアル(Standard)は、レンダリングに 9971020 クロックかかりました。
- コンパクトなマテリアル(Compact)は、レンダリングに 6951439 クロックかかりました。
コンパクトなマテリアルは、画面上で約 30% 速くレンダリングされます。
Snapdragon プロファイラーからのプロファイリング結果。
PC のメモリとパフォーマンスプロファイル
1024 x 1024 のアルベド、マスク、法線マップを備えた標準 PBR:
- 6 枚のアルベド DTX1 = 6 x 0.7 MB
- 6 枚のマスク DXT5 / BC7 = 6 x 1.3 MB
- 6 枚の法線マップ DXT5 / BC7 = 6 x 1.3 MB テクスチャの合計メモリ使用量 19.8MB
1024 x 1024 のコンパクト PBR:
- 6 枚の PackedPBR テクスチャ BC7 = 6 x 1.3 MB
テクスチャの合計メモリ使用量 7.8MB
コンパクトな 6 レイヤーのマテリアルを使うと、PC でのテクスチャメモリ消費量が 60% 削減されました(メモリ消費量を半分以上節約)。
2880 x 1800 でレンダリングされた Radeon460Pro を搭載した PC ラップトップで、RenderDoc プロファイルを行った結果:
- 6 つのレイヤーをブレンドした標準的なマテリアルによる不透明色の描画:5.186 ミリ秒
- 6 つのレイヤーをブレンドしたコンパクトなマテリアルによる不透明色の描画:3.632 ミリ秒 コンパクトなマテリアルは、画面上で約 30%* 速くレンダリングされます。 * RenderDoc プロファイル値は変動します。30% はサンプルの平均です。
nVidia GTX1080 を搭載した PC デスクトップで、2560 x 1440 でレンダリングした場合の、nSight プロファイルの結果:
- 6 つのレイヤーからなる標準的なマテリアルによる不透明色のレンダリング:0.87 ミリ秒
- 6 つのレイヤーからなるコンパクトなマテリアルによる不透明色のレンダリング:0.48 ミリ秒
コンパクトなマテリアルは、画面上で約 45% 速くレンダリングされます。
nSight のプロファイリング結果。
コンソールのパフォーマンスプロファイル
PlayStation 4 では、コンパクトなマテリアルを使用すると 60% のメモリ節約になります。PS4 は PC と同じ圧縮形式を使うため、結果が同じになっています。
1920 x 1080 での PS4 ベースレンダリングで、Razer プロファイルを行った結果:
- 6 つのレイヤーからなる標準的なマテリアルによる不透明色のレンダリング:2.11 ミリ秒
- 6 つのレイヤーからなるコンパクトなマテリアルによる不透明色のレンダリング:1.59 ミリ秒
コンパクトなマテリアルは、画面上で約 24.5% 高速にレンダリングされます。
PS4Razor プロファイラーのプロファイリング結果。
要約すると、6 つのレイヤーからなるコンパクトな PBR シェーダーを使用すると、パフォーマンスが向上し、メモリが大幅に節約されます。GPU パフォーマンスの変動は興味深いものですが、あらかじめ予見できたことでもあります。マテリアルのアンパックには、テクスチャを多数サンプリングするよりも多くの ALU が消費されるためです。
ユニバーサルレンダーパイプライン版プロジェクトからのスクリーンショット。
この実験の主な構成要素は以下のとおりです。
- カスタムマテリアルのシェーダーグラフ
- 事前に変換された導関数
- 表面勾配フレームワーク
- アルベドカラーの再構成
- 単一チャンネルのレイヤーブレンディング
- UpVector ブレンド手法、頂点チャンネルのブレンドによるスムースネスとバンプの制御
この実験では、シェーダーグラフを使用して、システムリソースの使用効率がよく、かつ美しいグラフィックを作成する方法を紹介しました。このサンプルがアーティストや開発者に刺激を与え、Unity プロジェクトにおける美的表現の限界を押し上げる活力を生むことを期待します。
Rinaldo Tjan(テクニカルアートディレクター、R&D、Spotlight チーム)は、リアルタイムライティングとレンダリングシステムに尋常ならざる情熱を注ぐリアルタイム 3D アーティストです。
PlayStation 2 の時代にキャリアをスタートさせ、それからテクスチャリングから最終レンダリングされたシーンの制作まで通して、アーティストワークフローの知識を 10 年以上にわたって積み上げてきました。Unity Technologies に入社する前は、『BioShock2』、『The Bureau: XCOM Declassified』、『Mafia III』などの AAA タイトルのリリースを支える立場にいました。
現在は、Unity の顧客と協力してプロジェクトを強化し、Unity を使って顧客の真の可能性を引き出す支援を行うとともに、Unity のレンダリング機能の内部開発と標準化を推進しています。