unity 3 dはGraphicsを理解する.BlitMultiTap
3215 ワード
unity 3 d公式のImage EffectsパッケージのShaderを勉強すると、この方法が見えるかもしれません.Unityのドキュメントには明確な説明はありません(リンク)
公式の例ではcsでは、このように使用されています.
対応するShaderにSubShaderとこのコードの組み合わせがあります.
以前、友人が発表した研究によると、以上のコードの意味はGraphics.BlitMultiTapが入力する各オフセット値は、テクスチャサンプリングを1回行い、前のステップのレンダリング結果と重ね合わせます.また、C#にベクトルを追加し、固定パイプラインSubShaderにSetTexture文を1行追加すれば、独自のサンプリング数を追加することもできます.
しかし,プログラマブルパイプラインと結合すると,状況は大きく異なる.公式の例のBlurEffectConeTaps.Shaderには、プログラマブルパイプラインを使用してBlueを実装するSubShaderがもう1つ用意されています.(デフォルトでは、固定パイプラインのSubShaderは以前に選択されていたため、有効になりません.固定パイプラインのSubShaderを注釈すると、プログラマブルパイプラインのSubShaderが有効になります.)このSubShaderで最初に見つかったBlitMultiTapに関するコードは、ここにあるはずです.
次にVSで、この4つの配列の各項目に値を付けます.
最終的にFSで読み取り、使用します.
このシナリオでは、taps[]配列のデータソースはC#コードで指定された4つのオフセットではなく、Shader自身が結合しています.BlurOffsets変数で計算されました._BlurOffsetsは特殊なuniform変数で、C#コードでGraphicsが呼び出された場合.BlitMultiTapが後処理を行うために使用されると、この方法によって入力された最初のoffsetsパラメータが_に割り当てられます.BlurOffsetsのxyは、後続のoffsetsは無視されます.
だから、実はGraphics.BlitMultiTapは、固定パイプラインに合わせて動作する方法です.プログラマブルパイプラインでは、最も基本的な互換性を提供しています.しかし、プログラム可能なパイプラインが提供できる柔軟性については、BlitMultiTapが提供する機能も全く必要ありません.私たちがカスタマイズできるMultiTap方式は、この方法よりはるかに豊富です.現代GPUプログラミングを行う際,我々はそれが時代遅れの方法であると考えることができる.
公式の例ではcsでは、このように使用されています.
// Performs one blur iteration.
public void FourTapCone (RenderTexture source, RenderTexture dest, int iteration)
{
float off = 0.5f + iteration*blurSpread;
Graphics.BlitMultiTap (source, dest, material,
new Vector2(-off, -off),
new Vector2(-off, off),
new Vector2( off, off),
new Vector2( off, -off)
);
}
対応するShaderにSubShaderとこのコードの組み合わせがあります.
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off Fog { Mode Off }
SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant alpha}
SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
}
}
以前、友人が発表した研究によると、以上のコードの意味はGraphics.BlitMultiTapが入力する各オフセット値は、テクスチャサンプリングを1回行い、前のステップのレンダリング結果と重ね合わせます.また、C#にベクトルを追加し、固定パイプラインSubShaderにSetTexture文を1行追加すれば、独自のサンプリング数を追加することもできます.
しかし,プログラマブルパイプラインと結合すると,状況は大きく異なる.公式の例のBlurEffectConeTaps.Shaderには、プログラマブルパイプラインを使用してBlueを実装するSubShaderがもう1つ用意されています.(デフォルトでは、固定パイプラインのSubShaderは以前に選択されていたため、有効になりません.固定パイプラインのSubShaderを注釈すると、プログラマブルパイプラインのSubShaderが有効になります.)このSubShaderで最初に見つかったBlitMultiTapに関するコードは、ここにあるはずです.
struct v2f {
float4 pos : POSITION;
half2 uv : TEXCOORD0;
half2 taps[4] : TEXCOORD1;
};
次にVSで、この4つの配列の各項目に値を付けます.
half4 _MainTex_TexelSize;
half4 _BlurOffsets;
v2f vert( appdata_img v ) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord - _BlurOffsets.xy * _MainTex_TexelSize.xy; // hack, see BlurEffect.cs for the reason for this. let's make a new blur effect soon
o.taps[0] = o.uv + _MainTex_TexelSize * _BlurOffsets.xy;
o.taps[1] = o.uv - _MainTex_TexelSize * _BlurOffsets.xy;
o.taps[2] = o.uv + _MainTex_TexelSize * _BlurOffsets.xy * half2(1,-1);
o.taps[3] = o.uv - _MainTex_TexelSize * _BlurOffsets.xy * half2(1,-1);
return o;
}
最終的にFSで読み取り、使用します.
sampler2D _MainTex;
half4 frag(v2f i) : COLOR {
half4 color = tex2D(_MainTex, i.taps[0]);
color += tex2D(_MainTex, i.taps[1]);
color += tex2D(_MainTex, i.taps[2]);
color += tex2D(_MainTex, i.taps[3]);
return color * 0.25;
}
このシナリオでは、taps[]配列のデータソースはC#コードで指定された4つのオフセットではなく、Shader自身が結合しています.BlurOffsets変数で計算されました._BlurOffsetsは特殊なuniform変数で、C#コードでGraphicsが呼び出された場合.BlitMultiTapが後処理を行うために使用されると、この方法によって入力された最初のoffsetsパラメータが_に割り当てられます.BlurOffsetsのxyは、後続のoffsetsは無視されます.
だから、実はGraphics.BlitMultiTapは、固定パイプラインに合わせて動作する方法です.プログラマブルパイプラインでは、最も基本的な互換性を提供しています.しかし、プログラム可能なパイプラインが提供できる柔軟性については、BlitMultiTapが提供する機能も全く必要ありません.私たちがカスタマイズできるMultiTap方式は、この方法よりはるかに豊富です.現代GPUプログラミングを行う際,我々はそれが時代遅れの方法であると考えることができる.