若是你學習unity3d官方的Image Effects包中的Shader,可能會看到這個方法。
unity的文檔對它並無一個很明確的描述(連接)php
在官方範例的BlurEffect.cs裏,它是被這樣使用的:html
// 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所傳入的每個偏移值,進行一次紋理採樣,而且與前一步的渲染結果進行疊加。你還能夠額外增長本身的採樣(tap)數,只要在C#中添加一個向量,而且在固定管線SubShader中添加一行SetTexture語句就能夠。數組
可是,當與可編程管線結合的時候,狀況就不大同樣了。
官方範例的BlurEffectConeTaps.shader中就提供了另一個使用可編程管線實現Blur的SubShader。
(默認狀況下它是不生效的,由於固定管線的SubShader在它以前,通常狀況下它不會被選擇激活。若是咱們把固定管線的SubShader註釋掉,那麼可編程管線的SubShader就能夠生效。)
在這個SubShader中最早找到的和BlitMultiTap有關的代碼應該是這裏:app
struct v2f { float4 pos : POSITION; half2 uv : TEXCOORD0; half2 taps[4] : TEXCOORD1; };
接下來在VS裏,對這個四項數組的每一項都進行了賦值:學習
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中讀取並使用:this
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#代碼中指定的四個偏移量,而是Shader本身結合_BlurOffsets變量計算出來的。
_BlurOffsets是一個特殊的uniform變量,若是在C#代碼中調用了Graphics.BlitMultiTap來進行後期處理,那麼這個方法傳入的第一個offsets參數會被賦值到_BlurOffsets的xy,然後續的更多offsets會被忽略。3d
因此,其實Graphics.BlitMultiTap是一個用來配合固定管線工做的方法。對於可編程管線,它只是提供了最基本的兼容性。不過對於可編程管線能夠提供的靈活性來講,BlitMultiTap所提供的功能也是徹底沒有必要的,咱們所可以定製的MultiTap方式遠遠比這個方法提供的要豐富。在進行當代GPU編程時,咱們能夠認爲它是一個過期的方法。code