GrabPassの説明とシェーダの実装例です。
Unity2018.2.0
GrabPass?
GrabPassは、このパスが実行される時点のレンダリング結果を取得できる特殊なパスです。
次のように書くことで使えます。
SubShader { // 描画結果をテクスチャに書き込みたいタイミングに応じてQueueを調整する Tags { "Queue" = "Transparent" } // GrabPass GrabPass { } Pass { /*** 略 ***/ // GrabPass以降のパスに_GrabTextureという変数を定義しておくとGrabPassの結果が取得できる sampler2D _GrabTexture; /*** 略 ***/ } }
ただしこの処理は重いので、何回も呼ぶときには次のように書きます。
最初に呼ばれたときのレンダリング結果がすべてのパスで使いまわされますが、
1Frameにつき1回しか処理が行われないので処理負荷が小さくなります。
SubShader { // 描画結果をテクスチャに書き込みたいタイミングに応じてQueueを調整する Tags { "Queue" = "Transparent" } // GrabPassをテクスチャ名を指定して定義 GrabPass { "_GrabPassTexture" } Pass { /*** 略 ***/ // GrabPass以降のパスに指定した名前のテクスチャを定義しておくとGrabPassの結果が取得できる sampler2D _GrabPassTexture; /*** 略 ***/ } }
実装例
例として、GrabPassで取得したテクスチャを_Shift分だけずらすシェーダを実装します。
Shader "GrabPassDistortion" { Properties { _Shift ("Shift", Range(0.0, 1.0)) = 0 } SubShader { // 描画結果をテクスチャに書き込みたいタイミングに応じてQueueを調整する Tags { "Queue" = "Transparent" } GrabPass { "_GrabPassTexture" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _GrabPassTexture; float _Shift; struct v2f { half4 vertex : SV_POSITION; half4 grabPos : TEXCOORD0; }; v2f vert (float4 vertex : POSITION) { v2f o = (v2f)0; // まずUnityObjectToClipPos o.vertex = UnityObjectToClipPos(vertex); // GrabPassのテクスチャをサンプリングするUV座標はComputeGrabScreenPosで求める o.grabPos = ComputeGrabScreenPos(o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // w除算が必要なのでtex2Dprojを使う return tex2Dproj(_GrabPassTexture, i.grabPos + _Shift); } ENDCG } } }
説明はコメントの通りです。
フラグメントシェーダのw除算についてはこの記事では説明しませんが、次の記事で説明しています。
結果
Quadにこのシェーダを適用すると次のような結果になります。
レンダリング結果を使って処理ができていることがわかります。