📸

URPでも任意のタイミングでGrabPassする

2023/04/03に公開

Built-in Render PipelineからURP(Universal Render Pipeline)でなくなった機能の一つにGrabPassがあります。

フレームバッファをテクスチャに保存し後続のレンダリングパスで参照できる非常に有用な機能だったのですが、Unity的にはパフォーマンスの悪さを気にしているよう[1]でURPではサポートされなくなっています

CameraOpaqueTexture

URPではGrabPassのかわりとしてCameraOpaqueTextureが用意されています。Opaque(不透明オブジェクト)をレンダリングした直後の絵がCameraOpaqueTextureに保存されており後段のレンダリングパスで使用できます

GrabPassの用途としては大抵Transparent(透明オブジェクト)で使用するのでこれで大部分はまかなえるだろうという考えのようです

URPGrabPass

Haruma-Kさんが公開されているURPGrabPassではTransparent後のタイミングでのキャプチャも可能です

https://github.com/Haruma-K/URPGrabPass

もっと細かいタイミングでキャプチャしたい

自分のケースでは

背景オブジェクト描画 → GrabPass → 背景以外の不透明オブジェクト描画 → 透明オブジェクト描画

としたかったので上記の方法では対応できなさそうでした

URPではRenderObjectsRendererFeatureというオブジェクト描画用のRendererFeatureを用意してくれているので、これでOpaqueの内容を分けることにしました

また、単純にキャプチャするだけのRendererFeatureも作成しました

https://gist.github.com/fuqunaga/a0b12ea3175aa7144e4431024329d77d

手順

上記GrabColorRendererFeature.csをプロジェクトに追加しておきます

キャプチャ対象のオブジェクトを識別するレイヤーを追加し(ここではGrabTargetとしています)、対象オブジェクトのレイヤーをGrabTargetにしておきます

RendererアセットのInspectorでOpaque Layer MaskからGrabTargetを除外します。これでURPデフォルトのOpaque描画の対象から外れます

Rendererアセットが行方不明な場合

Edit → ProjectSettings → Graphics → ScriptableRenderPipelineSettingsでレンダーパイプラインアセットを探し、そのInspectorのRenderer Listから見つけることができます

同じくRendererアセットのInspectorからAdd Renderer FeatureボタンでRender Objectsを追加し、次のように設定します

  • Event: BeforeRenderingOpaques
  • Filters:
    • Queue: Opaque
    • LayerMask: GrabTarget

同様にGrabColorRendererFeatureも追加、設定します

  • RenderPassEvent: 上記RenderObjectsと同じものにする
  • Grabbed Texture Name: シェーダーから参照するキャプチャしたテクスチャ名

これでGrabTargetレイヤーのオブジェクトを先に描画し、その後Opaqueでもキャプチャしたテクスチャを参照できるようになりました

感想

GrabPass的な処理をより細かいタイミングで差し込みたいと調べていくうちに、RenderObjectsRendererFeatureを知ったことであまり特別なコードを書かずともできることがわかりました。GrabPassを差し込むというよりかは、デフォルトの描画を分割していける、といった印象でしょうか。応用すればかなり柔軟に描画処理をカスタイマイズしていけそうですね

参考

https://redhologerbera.hatenablog.com/entry/2022/04/01/222158
https://github.com/Haruma-K/URPGrabPass
https://zenn.dev/ruccho/articles/cda6d291ed9947

脚注
  1. https://forum.unity.com/threads/grabpass-and-multi-pass-shaders-in-urp.1342121/ ↩︎

Discussion