🙌

【Unity】Adaptive Probe Volumesと他ライティング手法の負荷比較

に公開

はじめに

こんにちは、クライアントエンジニアのサックーです。
この記事では Adaptive Probe Volumes(以下 APV )の各種設定時と他ライティング手法の負荷比較検証を行なっていきます。
計測は Android スマホの実機で行いました。

端的なまとめとしては以下の通りです。

  • シナリオブレンド無しのAPVはLightmap並のGPU負荷
  • シナリオブレンド時のAPVはRealtime Light並のGPU負荷
  • APV使用時に品質ごとにほぼ固定のメモリ使用量増加あり

なお APV 本体の紹介については割愛しますので、以下のようなソースを参考にしてください。

https://tarowork.hatenablog.jp/entry/2024/12/05/000000

https://www.youtube.com/watch?v=IpVuIZYFRg4

12 月 1 日の記事で、APV でできるライティング状態のブレンドについて、12 月 7 日の記事で APV と他ライティング手法のルック比較について書いています。
本記事ではルック等については扱わないため、必要に応じて参照してください。

https://zenn.dev/ambr_inc/articles/b7a92d863203e8

https://zenn.dev/ambr_inc/articles/83d28c7b123a8a

検証環境等

ビルド環境

  • 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

取得項目

  • GPU Time
  • CPU Time(RenderCameraStack)
  • Total Resident Memory On Device
  • Unity Objects Total Memory

使用シーン


https://assetstore.unity.com/packages/3d/environments/urban/colonial-city-littlepack-church-graveyard-environment-163089

プロジェクトおよびシーンのセットアップ

基本的に前回記事で使用したプロジェクトとシーンを流用します。
シナリオのブレンドにはこちらのスクリプトを使用しています。
APV の配置については ProbeOffset を調整することで、おおむね最小の Probe 数になるように調整しました。

Probe Offset
Cell place

シーンのライティング関連容量

  • 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 程度使用しており、これが原因のようです。
APV Memory
これは URPAsset で確認できる Estimated GPU Memory cost とおおむね一致しています。
Estimate Memory
Memory Budget を Low にすることで半減を狙えそうです。
Low Badget
一方シナリオブレンドの有り無しを比較すると、UnityObjectsの消費メモリは10MB程度に収まっています。
これは1シーンに多くのシナリオを用意する場合に有利と言えるかもしれません。

また今回は Lightmap の解像度が小さく、枚数も少なかったため Realtime Light とほぼ同じ値になっていますが、大規模なシーンでは Lightmap の分メモリ使用量が増えると予想されます。

また GPUStreaming を有効にした際の Total Resident Memory On Device の値が多い内訳は以下でした。
NativeArray として Probe の情報が格納されているようですが、何やら2倍になっています。
Native Array No Streaming
非ストリーミング
Native Array Streaming
ストリーミング
また ComputeBuffer の中身も2倍になっていました。
ComputeBuffer No Streaming
非ストリーミング
ComputeBuffer Streaming
ストリーミング
おそらくストリーミングを実行するための領域確保であると考えられます。

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記事に渡って検証してきましたが、描画負荷の点で優れる一方、メモリ消費やルックの点で他手法に劣ることがあるというのが個人的な感想です。
実際には様々な要件によって最適な選択肢は変わってくると思うので、それぞれを上手く活用していきたいと思いました。

ambr Tech Blog

Discussion