はじめに
みなさんはシェーダーのプロファイリングをしたくなったとき、どうやっていますか?
FPS 測定?でもオーバヘッドが大きいし、具体的にどこが重いのかわからない……
みたいな悩みを、 NVIDIA Nsight Graphics で解決できるかもしれません。
ほかにいい手段をご存知の方はぜひご連絡ください……
手順
まずは こちら から NVIDIA Nsight Graphics をインストールします。
インストールの待ち時間に、 Unity プロジェクトの用意をします。
対象となるシェーダーを書いて、マテリアルを作成、それを適用した Plane なり Cube なりを配置します。
カメラに写ってさえいれば OK です。むしろ余計なものがあると解析の邪魔になるので最低限で大丈夫です。

シェーダーですが、以下の #pragma が必要となるので、シェーダーコードに書いておきます。
// #pragma fragment の下あたりに入れる // デバッグシンボルを含める #pragma enable_d3d11_debug_symbols // shader model 6.0 を使う #pragma use_dxc
これがないと詳細な解析ができません。
なお、
#pragma enable_d3d11_debug_symbolsはパフォーマンスに若干の悪影響を与える可能性があります。 ( →参照 )
デバッグが終わったら消しておくのが無難です。
なんでuse_dxcで SM6.0 が使えるのかは こちら を参照してください。
ビルドしたアプリを解析することになるので、アプリビルドの準備をします。
まずは Project Settings / Player / Other Settings / Rendering から Auto Graphics API for Windows のチェックを外し、一番上に Direct3D12 が来るようにします。
デフォルトの
Direct3D11だと解析に失敗します。
Vulkanでも動作しますが、デコンパイル結果などが異なり、見慣れない感じになります。
そちらに慣れている方は Vulkan のほうがいいかもしれませんが、私は DirectX をお勧めします。
そうしたら、 Windows 用にアプリをビルドします。
Development Build で大丈夫です。
ビルドしたら、 NVIDIA Nsight Graphics を 管理者権限で 実行します。
管理者権限でないと一部データの取得に失敗します。
起動したら、 Start Activity... を選んでください。

Application Executable: にさっきビルドしたアプリのパスを入れます。
そうしたら右下の Launch Frame Debugger を押します。
ここで Steam を起動していると
Interfering Processes Detectedと表示され、 Steam のアプリが干渉するとか言われるのですが、気にせずKeepを押して大丈夫です。
うまくいけば、ビルドしたアプリが起動します。
ここで
Direct3D11on12 is unsupportedみたいな警告が出ますが、とりあえずは無視しても大丈夫そうです。
アプリ上で F11 キーを押すとキャプチャできるので、押します。
すると、 Unity の Profiler みたいな画面が開きますので、解析をします。

まずは Events タブから、描画していそうなイベントを探します。
色がついているので、それを見ながら探してください。
私の場合は DrawIndexedInstanced というイベントがそれでした。検索フィルタもあるのでそれを活用すると見つけやすいかもです。
クリックすると、 API Inspector タブが更新されます。
PS (Pixel Shader) ボタンを押して Profile Shaders ↗ を押します。
すると Shader Profiler が開きます。
ここでは命令数やその内訳、かかった時間などを見ることができます。
カーソルを合わせると詳細な説明がありますので適宜見てください。

ここで、
Correlation行に警告が出ていた場合はたぶんシェーダーコードの設定を書き忘れています。
#pragmaをちゃんと書いたか確認してください。詳しい説明は 本家の説明書 を参照してください。
ストールの種類と説明 (MIO Throttle とは何ぞや、みたいなの) は こちら 。
処理にかかった時間は下段の Events / GPU Duration のほか、 Events タブの GPU ms から確認できます。
Hot Spots からは重い処理がどこかを突き止めることができます。

動的にシェーダーを編集することもできる (!) らしいですが、一度編集してしまうとソースコードと照らし合わせた解析ができなくなるっぽいので、あまり有効ではなさそうです。
おわりに
シェーダーのプロファイリングなんもわからん状態だったのでとても感動して記事にしました。
とりあえず導入してみた感じですが、プロファイリングが詳しいしいろんな機能があるようなのでいろいろ触ってみたいと思います。
参考文献
User Guide — NsightGraphics 2024.3 documentation
公式のユーザーガイドです。