【Unity】Unity6で追加されたGPU Resident Drawerとは何者なのか?セットパスコールから振り返り

Unity6で追加されたGPU Resident Drawerについてまとめます。

はじめに

Unity6 で GPU Resident Drawer という機能が追加されました。

これは機能自体が複雑なのに加えて多くの前提知識が必要なため、なかなか理解が難しいものとなっています。

そこで本記事では、GPU Resident Drawer の概要を、前提知識を含めてまとめます。

セットパスコールを減らすSRP Batcher

3Dのレンダリングを行うには、CPU から GPU に対して「セットパスコール」を行う必要があります。
これは、テクスチャやシェーダといったマテリアルの情報をGPUに設定する処理です。

light11.hatenadiary.com

この処理は重いため、セットパスコールの回数はできる限り減らす必要があります。
セットパスコールの回数は Game ウィンドウの Stats から確認することができます。

Stats

さて、URP や HDRP といった SRP をベースとしたレンダリングパイプラインには、SRP Batcher という機能が存在します。
これはシェーダキーワードが同じオブジェクトのセットパスコールをまとめて行う機能です。
この機能により、SRP ではセットパスコールの回数を抑えることができます。

light11.hatenadiary.com

DOTSから生まれたBatch Renderer Group API

さて、Unity は数年前から DOTS というシステムを開発しています。
DOTS の説明は本筋から逸れるので割愛しますが、この開発の一環で Batch Renderer Group API が開発されました。

これはレンダリングコマンドをジョブシステムを使って並列で生成したり、GPU インスタンシングを使った描画処理を行うことにより、大量のメッシュを効率的に描画できる仕組みです。
また内部的に GraphicsBuffer にデータを格納してGPU 側に描画用のデータを保持するので、GPUにデータを送信するオーバーヘッドを軽減させることができます(インスタンス情報が変わらない限り)。

Batch Renderer Group については、スマホで多数のオブジェクトを描画するサンプルをUnityが公開しています。

unity.com

より簡単に使える様にした GPU Resident Drawer

この Batch Renderer Group は、DOTS の文脈で作られたので、DOTS の Entity には対応しているものの、GameObject では使用しづらいものでした。 これを GameObject でも簡単に使えるようにしたのが GPU Resident Drawer です。

まとめると、GPU Resident Drawer により、今まで通り SRP Batcher によるセットパスコールのバッチングを効かせつつ、内部的に Batch Renderer Group を使うことで、ジョブシステムを使ったレンダリングコマンドの発行や、インスタンシングによるドローコールの削減といった恩恵を受けられるということになります。

GPU Resident Drawer の使い方

使い方は非常に簡単で、 Universal Render Pipeline Asset の Rendering > GPU Resident Drawer を Instanced Drawing に切り替えるだけです。

Instanced Drawing

URP のサンプルシーン「Garden」で ON/OFF を切り替えてみると Batches の値が顕著に変わることを確認することができます。

Batchesが変化

制約

GPU Resident Drawerを使うには以下の制約があるので注意が必要です。

  • Forward+ Renderer である必要がある
  • Compute Shaderが使える環境であること
  • MeshRendererだけが対象
  • MaterialPropertyBlockを使用しているオブジェクトは対象外
  • リアルタイムGIに影響するオブジェクトは対象外
  • シェーダが対応している必要がある

参考

www.youtube.com