Unity URPでGPU処理負荷を画面に出してみる
Unity 2020.3 + URP 10.7.0 や、Unity2021.2 + URP 12.1.0で画像のような形で、項目別にGPUの負荷を出すものをつくりました。
※動作環境によっては対応していません。
動作環境がサポートしているかどうかは SystemInfo.supportsGpuRecorderで判定可能です
こちらは、このソースをプロジェクトの何処かに格納したのち、PlayerSettingsでDefineに「UNITY_USE_RECORDER」を定義することで利用が可能になっています。(画像を参照)
※ソース側に表示用のUIオブジェクトの生成など諸々入っていますので、ソースコードいれるだけで利用できます。
■実現方法について
UnityのAPI CustomSamplerでは実は関連したGPU処理負荷を収集するかどうかを指定することが出来ます。
CustomSampler.Createの引数でGPUを集めるかどうかという事が指定可能です。そして、GPUを集めるCustomSamplerからGetRecorderして、Recorder.gpuElapsedNanosecondsにてGPUの処理時間を取得することが可能となっています。
今回はこの辺の仕組みから値を取得するようになっています。
■URPでの事
Unityのcom.unity.render-pipelines.coreパッケージにあるUnityEngine.Rendering.ProfilingSamplerというクラスがこの辺をラップしています。
つまり、このProfilingSamplerをひたすら集めていって、それをもとに出せば良さそうです。
ちなみに自分で書いたPassでも計測したい場合は、URPのDrawObjectsPass.csとかが参考になります。
1.ProfilerSamplerをメンバー変数として作成
2.ProfilingScopeをusing ブロックで括る
こんな感じで、計測可能になります。
■そして実装
InternalやPrivateの壁があり、ProfilingSampler一覧をそのままでは取得できなかったので、Reflectionを駆使して集めて回っていくという事をやっただけです。
このような形でGPU負荷を表示することが出来ました。
※あと諸注意ですが・・・。今回は「ソースコード一つで完結する&さっくり作る」ことを目指してたので、GC Allocフリーということまではしていません。UIの数字更新ごとに、GC Allocします。ご注意を…
あと毎フレーム書き換えだと人類には速すぎたので、1秒に1度しか変えてません。頻度を変更したい場合はソース書き換えて下さい。
最後にソースコード載せておきます。