UnityのLWRPで_CameraOpaqueTextureを利用してGrabPassのようなことをする
はじめに
Unityの従来のレンダーパイプラインではGrabPass
という特殊なパスを利用して
それまでにレンダリングした絵をテクスチャとして利用できました。
LWRPを含むSRPではGrabPass
が使えなくなります。
LWRPではGrabPass
の代替として_CameraOpaqueTexture
というものが用意されています。
このテクスチャをShader Graphから利用してみます。
- Unity:2018.3.0b8
- LWRP:4.1.0-preview
_CameraOpaqueTexture
SRPではGrabpassがなくなっています。 次のページの制限事項の項目にサラッと書かれています。
すべてのスクリプタブルレンダーパイプライン(SRP)に言えることですが、ライトのレンズフレアなど、以前 Overlay レイヤーでレンダーされたものにはすべて非対応です。Grabpass はなくなっています。
それではGrabpassの代わりになる表現はないのかと調べたところ、
_CameraOpaqueTexture
というものがあるそうです。
Shader Graphから扱っているツイートがありました。
In ShaderGraph, you can get the OpaqueTexture of the screen by just declaring a Property called _CameraOpaqueTexture. The LW pipeline will fill it in the final shader.
— Ciro Continisio ☕️ (@CiroContns) 2018年7月31日
With it, you can create refraction shaders super easy!!#unitytips #unity3d #shader pic.twitter.com/uh5NMSERvh
_CameraOpaqueTexture
を使う
さきほどのツイートでほとんど説明されていますが、 微妙足りていない部分があるので補足します。
_CameraOpaqueTexture
を使うには
LWRPの設定で「Opaque Texture」を有効にする必要があります。
後はさきほどのツイートの動画のとおりに進めればOKです。
プロパティを作成し「Reference」に「_CameraOpaqueTexture」と入力します。
「Exposed」は必要ないのでオフにしました。
適当にPBR Masterにつなげてみます。
RenderQueueは「Transparent」に設定します。
これで次のようになります。
これで生成されるコードは次のようになります。
...
TEXTURE2D(_CameraOpaqueTexture); SAMPLER(sampler_CameraOpaqueTexture); float4 _CameraOpaqueTexture_TexelSize;
...
SurfaceDescription PopulateSurfaceData(SurfaceDescriptionInputs IN)
{
SurfaceDescription surface = (SurfaceDescription)0;
float4 _ScreenPosition_4567259E_Out = float4(IN.ScreenPosition.xy / IN.ScreenPosition.w, 0, 0);
float4 _SampleTexture2D_DC5F7424_RGBA = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, (_ScreenPosition_4567259E_Out.xy));
float _SampleTexture2D_DC5F7424_R = _SampleTexture2D_DC5F7424_RGBA.r;
float _SampleTexture2D_DC5F7424_G = _SampleTexture2D_DC5F7424_RGBA.g;
float _SampleTexture2D_DC5F7424_B = _SampleTexture2D_DC5F7424_RGBA.b;
float _SampleTexture2D_DC5F7424_A = _SampleTexture2D_DC5F7424_RGBA.a;
surface.Albedo = (_SampleTexture2D_DC5F7424_RGBA.xyz);
surface.Normal = IN.TangentSpaceNormal;
surface.Emission = IsGammaSpace() ? float3(0, 0, 0) : SRGBToLinear(float3(0, 0, 0));
surface.Metallic = 0;
surface.Smoothness = 0.5;
surface.Occlusion = 1;
surface.Alpha = 1;
surface.AlphaClipThreshold = 0;
return surface;
}
...
適当にUVをずらしてReflection Probeと合成してみました。
おわりに
LWRPでGrabpass的なことをしてみました。 従来のレンダーパイプラインといろいろと勝手が違ってわからないことばかりで大変です。