🎨
CustomRenderTextureで前回パスの結果を取得する
概要
CustomRenderTexture(以降CRTと呼ぶ)ではDouble Bufferを使用することで前回フレームの結果を_SelfTexture2Dとして取得することができます。これと同じように、1フレームの間で、前回パスの結果を_SelfTexture2Dとして取得する方法を紹介します。
環境
- Unity 2022.3.22f1
サンプルケース
今回はCRTで
- Pass1で赤色のテクスチャを取得
- Pass2でPass1の結果に緑色を加算 → 黄色になる
- Pass3でPass2の結果に青色を加算 → 白色になる
という3パスに渡った処理を行ってみます。Pass2とPass3で前回パスの結果を_SelfTexture2Dとして利用しています。
CRT用のShader
Shader "CustomRenderTextureTest"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
Name "Pass1"
CGPROGRAM
#include "UnityCustomRenderTexture.cginc"
#pragma vertex CustomRenderTextureVertexShader
#pragma fragment frag
sampler2D _MainTex;
float4 frag(v2f_customrendertexture i) : SV_Target
{
float2 iuv = i.globalTexcoord;
float4 col = tex2D(_MainTex, iuv); // 赤色のテクスチャを取得
return col;
}
ENDCG
}
Pass
{
Name "Pass2"
CGPROGRAM
#include "UnityCustomRenderTexture.cginc"
#pragma vertex CustomRenderTextureVertexShader
#pragma fragment frag
float4 frag(v2f_customrendertexture i) : SV_Target
{
float2 iuv = i.globalTexcoord;
float4 col = tex2D(_SelfTexture2D, iuv); // 前回パスの結果を取得
return col + float4(0.0, 1.0, 0.0, 0.0); // 前回パスの結果に緑色を加算
}
ENDCG
}
Pass
{
Name "Pass3"
CGPROGRAM
#include "UnityCustomRenderTexture.cginc"
#pragma vertex CustomRenderTextureVertexShader
#pragma fragment frag
float4 frag(v2f_customrendertexture i) : SV_Target
{
float2 iuv = i.globalTexcoord;
float4 col = tex2D(_SelfTexture2D, iuv); // 前回パスの結果を取得
return col + float4(0.0, 0.0, 1.0, 0.0); // 前回パスの結果に青色を加算
}
ENDCG
}
}
}
CRTの設定
CRT用のMaterialで1Pass目で使う赤色のテクスチャをアタッチしています。
また、理由はわかりませんがDouble Bufferedの他にWrap Update Zonesのチェックも必要でした。公式ドキュメントを見ると「部分的な更新ゾーンがテクスチャの境界線の周りを包むようにできます。」と書いてありましたが意味がよくわかりませんでした...
Update ZonesにはそれぞれPass1, Pass2, Pass3を追加していき、前回パスの結果を_SelfTexture2Dとして利用したいPass2, Pass3ではSwap(Double Buffer)にチェックを入れます。
描画結果
Pass1で赤色に→Pass2で緑色を加算して黄色に→Pass3で青色を加算して最終的に白色になります。
完成品 (UnityPackage)
CRTは設定がややこしいため完成品を配布します。インポート後PrefabをHierarchyにドラッグ&ドロップすれば、本記事の状態を再現できるはずです。
ライセンスはCC0 (クリエイティブ・コモンズ・ゼロ)とします。いかなる権利も保有しません。
参考
Discussion