UnityのHDRPでのGrabPassの代替表現

はじめに

Unityの従来のレンダーパイプラインではGrabPassという特殊なパスが存在しました。 このパスを利用することで、それまでにレンダリングした絵をテクスチャとして利用できました。 このパスを利用することで屈折表現やその他特殊な表現を実装することもありました。 このパスは便利だったのですが、 LWRPやHDRPなどのSRPではGrabPassが廃止されてしまいました。 今回はHDRPでのGrabPassの代替表現について軽く調べたのでまとめます。

2019 05 25 15 20 57

  • Unity : 2019.2.0b1
  • HDRP : 6.7.1-preview

屈折及び歪みの表現

SRPではGrabpassがなくなっています。 次のページの制限事項の項目にサラッと書かれています。

すべてのスクリプタブルレンダーパイプライン(SRP)に言えることですが、ライトのレンズフレアなど、以前 Overlay レイヤーでレンダーされたものにはすべて非対応です。Grabpass はなくなっています。

HDRPではこの廃止されたGrabPassの機能のうち屈折などの表現の代わりとなる機能が LitシェーダおよびUnlitシェーダに実装されているようです。

Litシェーダ

まずはLitシェーダから見ていきます。 Litシェーダのマテリアルを作成して「Surface Type」を「Transparent」に変更します。

2019 05 25 14 24 06

「Base Color」を透明にします。

2019 05 25 14 26 41

「Transparency Inputs」の「Refraction Model」を「None」から変更します。

2019 05 25 14 28 29

「Smoothness」の値によってぼかしのかかったような透明の表現になります。

2019 05 25 14 28 45

「Smoothness」を1に、「Index Of Refraction」を1.04にすると次のようになりました。

2019 05 25 14 30 39

スクリーンスペースで屈折を表現しているためなのか、IORの値などによっては 屈折が欠けることもあるようです。

2019 05 25 14 32 33

「Transparency Inputs」ではIORなどを設定する前述の方法の他に もう1つ屈折のような表現を行う方法が用意されています。 「Distortion」のチェックボックスをオンにします。

2019 05 25 14 34 17

Distortion Vector Mapというのが登録できるようになっています。 このマップはRとGにxy方向へのズレを、bにブラー成分を入れたものとなっています。

試しにこのようなテクスチャを入れてみました。

2019 05 25 14 37 10

2019 05 25 14 37 44

Quadにこのマテリアルを貼り付けてみると次のようになりました。

2019 05 25 14 38 06

Unlitシェーダ

Unlitシェーダには「Distortion」があります。

2019 05 25 14 39 32

2019 05 25 14 39 49

透明のオブジェクトにライティング効果がかかるとガラスのようになります。 単純に空間を歪ませたい場合にはUnlitが使えそうです。

エフェクトの周囲の空間を歪ませるのに使ってみました。

Shader Graph

Shader Graphでもこれらの表現は使えます。 次の例はHDRP用のUnlitシェーダグラフでDistortionを使っています。 歯車アイコンから「Distortion」をオンにすることでMasterノードにDistortionの項目が生えます。

2019 05 25 14 43 23

ノイズをRG成分に割り当ててみました。

2019 05 25 14 43 53

これで次のようになりました。

その他の表現

屈折のような表現はできましたがもう少し自由な表現を行おうとすると 画面をテクスチャとして直接いじりたくなります。

HDRPでは内部で_ColorPyramidTextureというテクスチャに描画内容を書き出しています。 ShaderVariables.hlsl内部に_ColorPyramidTextureから色をサンプルしてくる SampleCameraColorという関数が用意されています。

2019 05 25 14 54 03

この関数をTransparent以降の描画タイミングで利用すると従来のGrabPassのようなことが 行えます。

試しにShaderGraphからSampleCameraColorを利用してみます。 HDRPのUnlitなShaderGraqphを用意します。 「Surface Type」を「Transparent」に変更します。

2019 05 25 14 56 14

Screen Positionノードを作成します。 Custom Functionノードを生成して、SampleCameraColor(uv)とします。

2019 05 25 14 58 01

uv.y = 1 - uv.y;
Out = SampleCameraColor(uv);
Out.rgb *= 0.2;

uvのy座標を反転し、色を取得してからそれを0.2倍にして暗くしています。

Custom FunctionノードでSampleCameraColorが存在しないとのことで警告されています。 しかし、生成されるコードではShaderVariables.hlslが読み込まれており問題なく動きます。

この_ColorPyramidTextureはHDRとなっているようです。 そのため色調をいじろうとしても思ったような色にならないこともありそうですが、 おおよそGrabPassと同じ感覚で使えるようになったのではないでしょうか。

2019/09/21追記

こんなややこしいことをしなくてもHD Scene Colorという レンダリングした絵をとってくるノードがズバリ存在しました。

2019 09 21 21 36 21

おわりに

HDRPでのGrabPassの代替手段をまとめました。 歪ませたい場合はHDRPのLitおよびUnlitシェーダに用意されている機能で十分そうです。 さらに特殊なことをしたい場合にはSampleCameraColorを利用すると良さそうです。