UnityのHDRPでのGrabPassの代替表現
はじめに
Unityの従来のレンダーパイプラインではGrabPass
という特殊なパスが存在しました。
このパスを利用することで、それまでにレンダリングした絵をテクスチャとして利用できました。
このパスを利用することで屈折表現やその他特殊な表現を実装することもありました。
このパスは便利だったのですが、
LWRPやHDRPなどのSRPではGrabPass
が廃止されてしまいました。
今回はHDRPでのGrabPass
の代替表現について軽く調べたのでまとめます。
- Unity : 2019.2.0b1
- HDRP : 6.7.1-preview
屈折及び歪みの表現
SRPではGrabpassがなくなっています。 次のページの制限事項の項目にサラッと書かれています。
すべてのスクリプタブルレンダーパイプライン(SRP)に言えることですが、ライトのレンズフレアなど、以前 Overlay レイヤーでレンダーされたものにはすべて非対応です。Grabpass はなくなっています。
HDRPではこの廃止されたGrabPass
の機能のうち屈折などの表現の代わりとなる機能が
LitシェーダおよびUnlitシェーダに実装されているようです。
Litシェーダ
まずはLitシェーダから見ていきます。 Litシェーダのマテリアルを作成して「Surface Type」を「Transparent」に変更します。
「Base Color」を透明にします。
「Transparency Inputs」の「Refraction Model」を「None」から変更します。
「Smoothness」の値によってぼかしのかかったような透明の表現になります。
「Smoothness」を1に、「Index Of Refraction」を1.04にすると次のようになりました。
スクリーンスペースで屈折を表現しているためなのか、IORの値などによっては 屈折が欠けることもあるようです。
「Transparency Inputs」ではIORなどを設定する前述の方法の他に もう1つ屈折のような表現を行う方法が用意されています。 「Distortion」のチェックボックスをオンにします。
Distortion Vector Mapというのが登録できるようになっています。 このマップはRとGにxy方向へのズレを、bにブラー成分を入れたものとなっています。
試しにこのようなテクスチャを入れてみました。
Quadにこのマテリアルを貼り付けてみると次のようになりました。
Unlitシェーダ
Unlitシェーダには「Distortion」があります。
透明のオブジェクトにライティング効果がかかるとガラスのようになります。 単純に空間を歪ませたい場合にはUnlitが使えそうです。
エフェクトの周囲の空間を歪ませるのに使ってみました。
HDRPのTransparentなUnlitのDistortionを使ってみた例 pic.twitter.com/lNeb3nf0nv
— 折登 いつき (@MatchaChoco010) 2019年5月22日
Shader Graph
Shader Graphでもこれらの表現は使えます。 次の例はHDRP用のUnlitシェーダグラフでDistortionを使っています。 歯車アイコンから「Distortion」をオンにすることでMasterノードにDistortionの項目が生えます。
ノイズをRG成分に割り当ててみました。
これで次のようになりました。
Shader GraphでDistortionをスクロールするTransparentなUnlitのマテリアルを作ってSphereに割り当ててみた。 pic.twitter.com/i4gy3rWmsN
— 折登 いつき (@MatchaChoco010) 2019年5月22日
その他の表現
屈折のような表現はできましたがもう少し自由な表現を行おうとすると 画面をテクスチャとして直接いじりたくなります。
HDRPでは内部で_ColorPyramidTexture
というテクスチャに描画内容を書き出しています。
ShaderVariables.hlsl
内部に_ColorPyramidTexture
から色をサンプルしてくる
SampleCameraColor
という関数が用意されています。
この関数をTransparent以降の描画タイミングで利用すると従来のGrabPass
のようなことが
行えます。
試しにShaderGraphからSampleCameraColor
を利用してみます。
HDRPのUnlitなShaderGraqphを用意します。
「Surface Type」を「Transparent」に変更します。
Screen Positionノードを作成します。
Custom Functionノードを生成して、SampleCameraColor(uv)
とします。
uv.y = 1 - uv.y;
Out = SampleCameraColor(uv);
Out.rgb *= 0.2;
uvのy座標を反転し、色を取得してからそれを0.2倍にして暗くしています。
Custom FunctionノードでSampleCameraColor
が存在しないとのことで警告されています。
しかし、生成されるコードではShaderVariables.hlsl
が読み込まれており問題なく動きます。
HDRPでGrabPass的なことをやる方法がだいたいわかった。 pic.twitter.com/Ivi3g22lQy
— 折登 いつき (@MatchaChoco010) 2019年5月25日
この_ColorPyramidTexture
はHDRとなっているようです。
そのため色調をいじろうとしても思ったような色にならないこともありそうですが、
おおよそGrabPass
と同じ感覚で使えるようになったのではないでしょうか。
2019/09/21追記
こんなややこしいことをしなくてもHD Scene Colorという レンダリングした絵をとってくるノードがズバリ存在しました。
おわりに
HDRPでのGrabPass
の代替手段をまとめました。
歪ませたい場合はHDRPのLitおよびUnlitシェーダに用意されている機能で十分そうです。
さらに特殊なことをしたい場合にはSampleCameraColor
を利用すると良さそうです。