【Unity】Adaptive Probe Volumesと他ライティング手法の負荷比較
はじめに
こんにちは、クライアントエンジニアのサックーです。
この記事では Adaptive Probe Volumes(以下 APV )の各種設定時と他ライティング手法の負荷比較検証を行なっていきます。
計測は Android スマホの実機で行いました。
端的なまとめとしては以下の通りです。
- シナリオブレンド無しのAPVはLightmap並のGPU負荷
- シナリオブレンド時のAPVはRealtime Light並のGPU負荷
- APV使用時に品質ごとにほぼ固定のメモリ使用量増加あり
なお APV 本体の紹介については割愛しますので、以下のようなソースを参考にしてください。
12 月 1 日の記事で、APV でできるライティング状態のブレンドについて、12 月 7 日の記事で APV と他ライティング手法のルック比較について書いています。
本記事ではルック等については扱わないため、必要に応じて参照してください。
検証環境等
ビルド環境
- Unity 6000.0.58f2
- Universal Render Pipeline 17.0.4
- Forward+
- Memory Budget(Light Probe System) : Medium
- Memory Budget(Blending) : Medium
- OpenGLES3
- Development Build
- Target Frame Rate : 120
- Fixed DPI : 236
使用デバイス
- Xperia XZ2 Premium
- Snapdragon 845
- Android 10
比較対象
- Lightmap
- Realtime Light
- Additional Lights:Per Vertex・Per Pixel
- Adaptive Probe Volume
- Scenario Blending:あり・なし
- GPU Streaming:あり・なし
- Additional Lights:Per Vertex・Per Pixel
- Scenario Blending:あり・なし
取得項目
- GPU Time
- CPU Time(RenderCameraStack)
- Total Resident Memory On Device
- Unity Objects Total Memory
使用シーン
プロジェクトおよびシーンのセットアップ
基本的に前回記事で使用したプロジェクトとシーンを流用します。
シナリオのブレンドにはこちらのスクリプトを使用しています。
APV の配置については ProbeOffset を調整することで、おおむね最小の Probe 数になるように調整しました。


シーンのライティング関連容量
- Lightmap
- 1 baked lightmap: 1×(512×512px) 496.1KB
- APV(Scenario 無し)
- Baking Set Size : 0.6MB
- APV(Scenario 2つ)
- Scenario Size : 0.3MB
- Baking Set Size : 0.9MB
測定結果
Profiler においてもっともらしい時点を選択して抽出した値であることをご了承ください。
| GPU Time | CPU Time (RenderCameraStack) | Total Resident Memory On Device | Unity Objects Total Memory | |
|---|---|---|---|---|
| Lightmap | 8.50ms | 5.42ms | 512MB | 111.9MB |
| Realtime_PerVertex | 17.61ms | 7.57ms | 501MB | 112.8MB |
| Realtime_PerPixel | 22.30ms | 10.04ms | 522MB | 114.8MB |
| APV_PerVertex | 8.80ms | 4.56ms | 584MB | 206.7MB |
| APV_PerPixel | 9.21ms | 5.61ms | 584MB | 206.7MB |
| APV_Scenario_PerVertex ブレンド時 | 17.20ms | 6.18ms | 573MB | 216.7MB |
| APV_Scenario_PerVertex 非ブレンド時 | 9.75ms | 5.76ms | 同上 | 同上 |
| APV_Scenario_PerVertex_Streaming ブレンド時 | 17.28ms | 4.46ms | 645MB | 216.9MB |
| APV_Scenario_PerVertex_Streaming 非ブレンド時 | 9.54ms | 5.67ms | 同上 | 同上 |
| APV_Scenario_PerPixel ブレンド時 | 22.86ms | 5.34ms | 584MB | 216.7MB |
| APV_Scenario_PerPixel 非ブレンド時 | 13.17ms | 5.82ms | 同上 | 同上 |
考察
GPU Time
GPU Time について見ると、Lightmap と APV(シナリオ無し)がほぼ同じで、Realtime Light は倍以上の値になっています。
しかし APV もシナリオブレンド中は Realtime Light 並の値となっています。
Lightmap と Realtime Light については想定通りだという印象ですが、非ブレンディング中の APV が Lightmap 並の GPU Time なのは想定より速くて驚きました。
シーンの規模によっては Lightmap ではテクスチャが増えすぎてしまう場合などに、 APV で代替しても負荷的には遜色ないと言えるかもしれません。
逆にブレンディング中の APV は Realtime Light と同等の GPU 負荷がかかっているのは想定より高負荷でした。
時々切り替えるような形なら良いですが、常時ブレンドし続ける場合は Realtime Light の方が良い選択肢になるかもしれません。
CPU Time (RenderCameraStack)
この値についてはフレームごとのばらつきが大きく、比較するのが難しいと感じました。
おおむね Lightmap と APV が同様で、Realtime Light はその 1.5~2 倍程度大きい傾向があると言えそうです。
メモリ使用量
メモリ使用量について見ると Lightmap と Realtime Light がほぼ同じで、APV はかなり多くなっています。特に UnityObject が使用しているメモリが2倍近くになっています。
内訳をみると RenderTexture として APV 用のものを 100MB 程度使用しており、これが原因のようです。

これは URPAsset で確認できる Estimated GPU Memory cost とおおむね一致しています。

Memory Budget を Low にすることで半減を狙えそうです。

一方シナリオブレンドの有り無しを比較すると、UnityObjectsの消費メモリは10MB程度に収まっています。
これは1シーンに多くのシナリオを用意する場合に有利と言えるかもしれません。
また今回は Lightmap の解像度が小さく、枚数も少なかったため Realtime Light とほぼ同じ値になっていますが、大規模なシーンでは Lightmap の分メモリ使用量が増えると予想されます。
また GPUStreaming を有効にした際の Total Resident Memory On Device の値が多い内訳は以下でした。
NativeArray として Probe の情報が格納されているようですが、何やら2倍になっています。

非ストリーミング

ストリーミング
また ComputeBuffer の中身も2倍になっていました。

非ストリーミング

ストリーミング
おそらくストリーミングを実行するための領域確保であると考えられます。
Per Vertex・Per Pixel
この項目については Lightmap において差はありませんでした。
Realtime Light と APV については一貫して PerPixel の方が GPU Time が大きくなる傾向があると言えそうです。
ルックに関しては前回の記事で言及しましたが、APV においては差が見られなかった一方、Realtime Light では影の出方などに大きな差がありました。
APV の GPU Streaming
前提としてこの機能は APV の Cell ごとにデータを Streaming するというものであり、今回配置の最適化によって Cell が1つしかないシーンのためおそらく処理は行われなかったと思われます。そのため処理時間や UnityObject のメモリ使用量に差は見られませんでした。
一方で前述のとおり Total Resident Memory On Device が大きく増える結果も観測されています。
Cell が複数に分かれる大規模シーンではメモリ使用量を削減できる可能性がありますが、1つしか Cell が無い場合は使用しない方が良さそうです。
おわりに
比較的新しいライティング手法である APV について3記事に渡って検証してきましたが、描画負荷の点で優れる一方、メモリ消費やルックの点で他手法に劣ることがあるというのが個人的な感想です。
実際には様々な要件によって最適な選択肢は変わってくると思うので、それぞれを上手く活用していきたいと思いました。
Discussion