Unity3D-UGUI特效之Image的高斯模糊效果

这几天研究了下模糊特效,看了很多文章,其原理就是拿取图片或屏幕数据,然后将周围的元素和目标位置的颜色值进行一个融合计算,然后自己写了一个小小的测试程序。

这个模糊也可以分成两种,一个是自身模糊,一个是从屏幕上取值进行模糊。第一个用于一些小的列表展示,比如未解锁时,是模糊的。第二个是凸显弹框效果的,将背景都模糊掉,自己将这个稍微加强了些可以指定模糊一个位置。

针对移动平台,使用高斯模糊,其实效率不是很高,如果要很好的效果,那么速度卡;如果要速度快,那么效果达不到要求。但是还是在这里记录下,兴许以后能用上。

先说第一个,挂在Image下的模糊特效。

Shader "Custom/FrontBlur" {
	Properties
	{
		[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
		_Color ("Tint", Color) = (1,1,1,1)
		
		[HideInInspector]_StencilComp ("Stencil Comparison", Float) = 8
		[HideInInspector]_Stencil ("Stencil ID", Float) = 0
		[HideInInspector]_StencilOp ("Stencil Operation", Float) = 0
		[HideInInspector]_StencilWriteMask ("Stencil Write Mask", Float) = 255
		[HideInInspector]_StencilReadMask ("Stencil Read Mask", Float) = 255

		[HideInInspector]_ColorMask ("Color Mask", Float) = 15

		[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
		
		_Size ("Size", Range(0, 50)) = 5
	}

	SubShader
	{
		Tags
		{ 
			"Queue"="Transparent" 
			"IgnoreProjector"="True" 
			"RenderType"="Transparent" 
			"PreviewType"="Plane"
			"CanUseSpriteAtlas"="True"
		}
		
		Stencil
		{
			Ref [_Stencil]
			Comp [_StencilComp]
			Pass [_StencilOp] 
			ReadMask [_StencilReadMask]
			WriteMask [_StencilWriteMask]
		}

		Cull Off
		Lighting Off
		ZWrite Off
		ZTest [unity_GUIZTestMode]
		Blend SrcAlpha OneMinusSrcAlpha
		ColorMask [_ColorMask]

		Pass
		{
			Name "FrontBlurHor"
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 2.0

			#include "UnityCG.cginc"
			#include "UnityUI.cginc"

			#pragma multi_compile __ UNITY_UI_ALPHACLIP
			
			struct appdata_t
			{
				float4 vertex   : POSITION;
				float4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct v2f
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				float2 texcoord  : TEXCOORD0;
				float4 worldPosition : TEXCOORD1;
				UNITY_VERTEX_OUTPUT_STEREO
			};
			
			fixed4 _Color;
			fixed4 _TextureSampleAdd;
			float4 _ClipRect;

			v2f vert(appdata_t IN)
			{
				v2f OUT;
				UNITY_SETUP_INSTANCE_ID(IN);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
				OUT.worldPosition = IN.vertex;
				OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

				OUT.texcoord = IN.texcoord;
				
				OUT.color = IN.color * _Color;
				return OUT;
			}

			sampler2D _MainTex;
			float4 _MainTex_TexelSize;
			float _Size;

			half4 GrabPixel(v2f i, float weight, float kernelx){
				if (_Size <= 1 || weight == 0){
					return tex2D(_MainTex, half2(i.texcoord.x + _MainTex_TexelSize.x*kernelx*_Size, i.texcoord.y)) * weight;
				}else{
					half4 sum = half4(0,0,0,0);
					sum += tex2D(_MainTex, half2(i.texcoord.x + _MainTex_TexelSize.x*kernelx*_Size*0.2, i.texcoord.y))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x + _MainTex_TexelSize.x*kernelx*_Size*0.4, i.texcoord.y))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x + _MainTex_TexelSize.x*kernelx*_Size*0.6, i.texcoord.y))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x + _MainTex_TexelSize.x*kernelx*_Size*0.8, i.texcoord.y))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x + _MainTex_TexelSize.x*kernelx*_Size*1.0, i.texcoord.y))*0.2;
					return (sum + _TextureSampleAdd) * weight;
				}
			}

			half4 GrabPixely(v2f i, float weight, float kernely){
				if (_Size <= 1 || weight == 0){
					return tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size)) * weight;
				}else{
					half4 sum = half4(0,0,0,0);
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*0.2))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*0.4))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*0.6))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*0.8))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*1.0))*0.2;
					return (sum + _TextureSampleAdd) * weight;
				}
			}

			fixed4 frag(v2f IN) : SV_Target
			{
				half4 sum = half4(0,0,0,0);
				// #define GRABPIXEL(weight, kernelx) (tex2D(_MainTex, half2(IN.texcoord.x + _MainTex_TexelSize.x * kernelx*_Size, IN.texcoord.y)) + _TextureSampleAdd) * weight
				
				// sum += GrabPixel(IN, 0.05, -4.0);
				// sum += GrabPixel(IN, 0.09, -3.0);
				// sum += GrabPixel(IN, 0.12, -2.0);
				// sum += GrabPixel(IN, 0.15, -1.0);
				// sum += GrabPixel(IN, 0.18,  0.0);
				// sum += GrabPixel(IN, 0.15, +1.0);
				// sum += GrabPixel(IN, 0.12, +2.0);
				// sum += GrabPixel(IN, 0.09, +3.0);
				// sum += GrabPixel(IN, 0.05, +4.0);

				for(int i=0;i<9;i++){
					sum += GrabPixel(IN, 1.0/9, i-4.0);
				}

				// half4 sumy = half4(0,0,0,0);
				// for(int i=0;i<15;i++){
				// 	sumy += GrabPixely(IN, 1.0/15, i-7.0);
				// }
				// half4 sum = (sumx + sumy) * 0.5;

				// sum += GrabPixel(IN, 0.01, -9.0);
				// sum += GrabPixel(IN, 0.02, -8.0);
				// sum += GrabPixel(IN, 0.03, -7.0);
				// sum += GrabPixel(IN, 0.04, -6.0);
				// sum += GrabPixel(IN, 0.05, -5.0);
				// sum += GrabPixel(IN, 0.06, -4.0);
				// sum += GrabPixel(IN, 0.07, -3.0);
				// sum += GrabPixel(IN, 0.08, -2.0);
				// sum += GrabPixel(IN, 0.09, -1.0);
				// sum += GrabPixel(IN, 0.10,  0.0);
				// sum += GrabPixel(IN, 0.09, +1.0);
				// sum += GrabPixel(IN, 0.08, +2.0);
				// sum += GrabPixel(IN, 0.07, +3.0);
				// sum += GrabPixel(IN, 0.06, +4.0);
				// sum += GrabPixel(IN, 0.05, +5.0);
				// sum += GrabPixel(IN, 0.04, +6.0);
				// sum += GrabPixel(IN, 0.03, +7.0);
				// sum += GrabPixel(IN, 0.02, +8.0);
				// sum += GrabPixel(IN, 0.01, +9.0);

				sum = sum * IN.color;
				sum.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
				#ifdef UNITY_UI_ALPHACLIP
				clip (sum.a - 0.001);
				#endif
				return sum;

				// float distance = _Distance;

				// fixed4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;

				// color += (tex2D(_MainTex, half2(IN.texcoord.x + distance, IN.texcoord.y + distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x + distance, IN.texcoord.y)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x + distance, IN.texcoord.y - distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x, IN.texcoord.y - distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x - distance, IN.texcoord.y - distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x - distance, IN.texcoord.y)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x - distance, IN.texcoord.y + distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x, IN.texcoord.y + distance)) + _TextureSampleAdd) * IN.color;
				// color /= 9;
				
				// color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
				
				// #ifdef UNITY_UI_ALPHACLIP
				// clip (color.a - 0.001);
				// #endif

				// return color;
			}
		ENDCG
		}
		Pass
		{
			Name "FrontBlurVer"
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 2.0

			#include "UnityCG.cginc"
			#include "UnityUI.cginc"

			#pragma multi_compile __ UNITY_UI_ALPHACLIP
			
			struct appdata_t
			{
				float4 vertex   : POSITION;
				float4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct v2f
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				float2 texcoord  : TEXCOORD0;
				float4 worldPosition : TEXCOORD1;
				UNITY_VERTEX_OUTPUT_STEREO
			};
			
			fixed4 _Color;
			fixed4 _TextureSampleAdd;
			float4 _ClipRect;

			v2f vert(appdata_t IN)
			{
				v2f OUT;
				UNITY_SETUP_INSTANCE_ID(IN);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
				OUT.worldPosition = IN.vertex;
				OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

				OUT.texcoord = IN.texcoord;
				
				OUT.color = IN.color * _Color;
				return OUT;
			}

			sampler2D _MainTex;
			float4 _MainTex_TexelSize;
			float _Size;

			half4 GrabPixel(v2f i, float weight, float kernely){
				if (_Size <= 1 || weight == 0){
					return tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size)) * weight;
				}else{
					half4 sum = half4(0,0,0,0);
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*0.2))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*0.4))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*0.6))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*0.8))*0.2;
					sum += tex2D(_MainTex, half2(i.texcoord.x, i.texcoord.y + _MainTex_TexelSize.y*kernely*_Size*1.0))*0.2;
					return (sum + _TextureSampleAdd) * weight;
				}
			}

			fixed4 frag(v2f IN) : SV_Target
			{
				half4 sum = half4(0,0,0,0);  
				// #define GRABPIXEL(weight, kernely) (tex2D(_MainTex, half2(IN.texcoord.x, IN.texcoord.y + _MainTex_TexelSize.y * kernely*_Size)) + _TextureSampleAdd) * weight
				
				// sum += GrabPixel(IN, 0.05, -4.0);
				// sum += GrabPixel(IN, 0.09, -3.0);
				// sum += GrabPixel(IN, 0.12, -2.0);
				// sum += GrabPixel(IN, 0.15, -1.0);
				// sum += GrabPixel(IN, 0.18,  0.0);
				// sum += GrabPixel(IN, 0.15, +1.0);
				// sum += GrabPixel(IN, 0.12, +2.0);
				// sum += GrabPixel(IN, 0.09, +3.0);
				// sum += GrabPixel(IN, 0.05, +4.0);

				for(int i=0;i<9;i++){
					sum += GrabPixel(IN, 1.0/9, i-4.0);
				}

				// sum += GrabPixel(IN, 0.01, -9.0);
				// sum += GrabPixel(IN, 0.02, -8.0);
				// sum += GrabPixel(IN, 0.03, -7.0);
				// sum += GrabPixel(IN, 0.04, -6.0);
				// sum += GrabPixel(IN, 0.05, -5.0);
				// sum += GrabPixel(IN, 0.06, -4.0);
				// sum += GrabPixel(IN, 0.07, -3.0);
				// sum += GrabPixel(IN, 0.08, -2.0);
				// sum += GrabPixel(IN, 0.09, -1.0);
				// sum += GrabPixel(IN, 0.10,  0.0);
				// sum += GrabPixel(IN, 0.09, +1.0);
				// sum += GrabPixel(IN, 0.08, +2.0);
				// sum += GrabPixel(IN, 0.07, +3.0);
				// sum += GrabPixel(IN, 0.06, +4.0);
				// sum += GrabPixel(IN, 0.05, +5.0);
				// sum += GrabPixel(IN, 0.04, +6.0);
				// sum += GrabPixel(IN, 0.03, +7.0);
				// sum += GrabPixel(IN, 0.02, +8.0);
				// sum += GrabPixel(IN, 0.01, +9.0);

				sum = sum * IN.color;
				sum.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
				#ifdef UNITY_UI_ALPHACLIP
				clip (sum.a - 0.001);
				#endif
				return sum;

				// float distance = _Distance;

				// fixed4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;

				// color += (tex2D(_MainTex, half2(IN.texcoord.x + distance, IN.texcoord.y + distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x + distance, IN.texcoord.y)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x + distance, IN.texcoord.y - distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x, IN.texcoord.y - distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x - distance, IN.texcoord.y - distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x - distance, IN.texcoord.y)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x - distance, IN.texcoord.y + distance)) + _TextureSampleAdd) * IN.color;
				// color += (tex2D(_MainTex, half2(IN.texcoord.x, IN.texcoord.y + distance)) + _TextureSampleAdd) * IN.color;
				// color /= 9;
				
				// color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
				
				// #ifdef UNITY_UI_ALPHACLIP
				// clip (color.a - 0.001);
				// #endif

				// return color;
			}
		ENDCG
		}
	}
}
里面分了两个Pass来计算,这样算出的效果会好很多,然后里面试了跟多的计算,越多的分层,那么得到的效果也越高,也意味着更加的不流畅。将shader放到一个新建的材质球上,然后把材质拖到Image组件的Material属性栏上就可以了。


看看效果:



然后说第二个方式,它是将背景都给模糊的效果。

Shader "Custom/BackBlur"
{
	Properties
	{
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
		_Color ("Main Color", Color) = (1,1,1,1)
        _Size ("Size", Range(0, 20)) = 1
	}
	Category {  
  
        // We must be transparent, so other objects are drawn before this one.  
        Tags { 
			"Queue"="Transparent" 
			"IgnoreProjector"="True" 
			"RenderType"="Transparent"
			"PreviewType" = "Plane"
			"CanUseSpriteAtlas" = "True"
		}  
  
  
        SubShader {  
  
            // Horizontal blur  
            GrabPass {                      
                Tags { "LightMode" = "Always" }  
            }  
            Pass {
                Tags { "LightMode" = "Always" }  

                Name "BackBlurHor"
                CGPROGRAM  
                #pragma vertex vert  
                #pragma fragment frag  
                #pragma fragmentoption ARB_precision_hint_fastest  
                #include "UnityCG.cginc"  
  
                struct appdata_t {  
                    float4 vertex : POSITION;  
                    float2 texcoord : TEXCOORD0;
					float4 color    : COLOR;
                };  
  
                struct v2f {  
                    float4 vertex : POSITION;  
                    float4 uvgrab : TEXCOORD0;
					float4 color    : COLOR;
                };
  
                v2f vert (appdata_t v) {  
                    v2f o; 
                    o.vertex = UnityObjectToClipPos(v.vertex);  
                    #if UNITY_UV_STARTS_AT_TOP  
                    float scale = -1.0;  
                    #else  
                    float scale = 1.0;  
                    #endif  
                    o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;  
                    o.uvgrab.zw = o.vertex.zw;  

					o.color = v.color;
                    return o;  
                }  
  
                sampler2D _GrabTexture;  
                float4 _GrabTexture_TexelSize;
			    float4 _MainTex_TexelSize;
                float _Size;
                uniform float4 _Color;

                // static float GaussianKernel[9] = {
                //     0.05, 0.09, 0.12,
                //     0.15, 0.18, 0.15,
                //     0.12, 0.09, 0.05
                // };

                // static float GaussianKernel[19] = {
                //     0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09,
                //     0.1,
                //     0.09, 0.08, 0.07, 0.06, 0.05, 0.04, 0.03, 0.02, 0.01,
                // };
                // static float GaussianKernelD[19] = {
                //     -9.0, -8.0, -7.0, -6.0, -5.0, -4.0, -3.0, -2.0, -1.0,
                //     0.0,
                //     +1.0, +2.0, +3.0, +4.0, +5.0, +6.0, +7.0, +8.0, +9.0,
                // };

                half4 GrabPixel(v2f i, float weight, float kernelx){
                    if (i.uvgrab.x == 0 && i.uvgrab.y == 0){
                        kernelx = 0;
                    }
                    return tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x*kernelx*_Size, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight;
                }
                half4 frag( v2f i ) : COLOR {  
                 	half4 sum = half4(0,0,0,0);
                    // #define GRABPIXEL(weight, kernelx) tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx*_Size, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight
                    
                    sum += GrabPixel(i, 0.05, -4.0);
                    sum += GrabPixel(i, 0.09, -3.0);
                    sum += GrabPixel(i, 0.12, -2.0);
                    sum += GrabPixel(i, 0.15, -1.0);
                    sum += GrabPixel(i, 0.18,  0.0);
                    sum += GrabPixel(i, 0.15, +1.0);
                    sum += GrabPixel(i, 0.12, +2.0);
                    sum += GrabPixel(i, 0.09, +3.0);
                    sum += GrabPixel(i, 0.05, +4.0);

                    // sum += GrabPixel(i, 0.01, -9.0);
                    // sum += GrabPixel(i, 0.02, -8.0);
                    // sum += GrabPixel(i, 0.03, -7.0);
                    // sum += GrabPixel(i, 0.04, -6.0);
                    // sum += GrabPixel(i, 0.05, -5.0);
                    // sum += GrabPixel(i, 0.06, -4.0);
                    // sum += GrabPixel(i, 0.07, -3.0);
                    // sum += GrabPixel(i, 0.08, -2.0);
                    // sum += GrabPixel(i, 0.09, -1.0);
                    // sum += GrabPixel(i, 0.10,  0.0);
                    // sum += GrabPixel(i, 0.09, +1.0);
                    // sum += GrabPixel(i, 0.08, +2.0);
                    // sum += GrabPixel(i, 0.07, +3.0);
                    // sum += GrabPixel(i, 0.06, +4.0);
                    // sum += GrabPixel(i, 0.05, +5.0);
                    // sum += GrabPixel(i, 0.04, +6.0);
                    // sum += GrabPixel(i, 0.03, +7.0);
                    // sum += GrabPixel(i, 0.02, +8.0);
                    // sum += GrabPixel(i, 0.01, +9.0);

                    float4 col5 = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
					float decayFactor = 1.0f;
					if (i.uvgrab.x == 0 && i.uvgrab.y == 0){
						decayFactor = 0;
					}
					sum = lerp(col5, sum, decayFactor) * i.color * _Color;
  
                    return sum;  
                }  
                ENDCG  
            }  
            // Vertical blur  
            GrabPass {                          
                Tags { "LightMode" = "Always" }  
            }  
            Pass {  
                Tags { "LightMode" = "Always" }

                Name "BackBlurVer"
                CGPROGRAM  
                #pragma vertex vert  
                #pragma fragment frag  
                #pragma fragmentoption ARB_precision_hint_fastest  
                #include "UnityCG.cginc"  
  
                struct appdata_t {  
                    float4 vertex : POSITION;  
                    float2 texcoord: TEXCOORD0;  
					float4 color    : COLOR;
                };  
  
                struct v2f {  
                    float4 vertex : POSITION;  
                    float4 uvgrab : TEXCOORD0;  
					float4 color    : COLOR;
                };  
  
                v2f vert (appdata_t v) {  
                    v2f o;  
                    o.vertex = UnityObjectToClipPos(v.vertex);  
                    #if UNITY_UV_STARTS_AT_TOP  
                    float scale = -1.0;  
                    #else  
                    float scale = 1.0;  
                    #endif  
                    o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;  
                    o.uvgrab.zw = o.vertex.zw;  

					o.color = v.color;
                    return o;  
                }  
  
                sampler2D _GrabTexture;  
                float4 _GrabTexture_TexelSize;  
                float _Size;
                uniform float4 _Color;

                half4 GrabPixel(v2f i, float weight, float kernely){
                    if (i.uvgrab.x == 0 && i.uvgrab.y == 0){
                        kernely = 0;
                    }
                    return tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _GrabTexture_TexelSize.y*kernely*_Size, i.uvgrab.z, i.uvgrab.w))) * weight;
                }
  
                half4 frag( v2f i ) : COLOR {
                    half4 sum = half4(0,0,0,0);  
                    // #define GRABPIXEL(weight,kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely*_Size, i.uvgrab.z, i.uvgrab.w))) * weight  
  
                    sum += GrabPixel(i, 0.05, -4.0);
                    sum += GrabPixel(i, 0.09, -3.0);
                    sum += GrabPixel(i, 0.12, -2.0);
                    sum += GrabPixel(i, 0.15, -1.0);
                    sum += GrabPixel(i, 0.18,  0.0);
                    sum += GrabPixel(i, 0.15, +1.0);
                    sum += GrabPixel(i, 0.12, +2.0);
                    sum += GrabPixel(i, 0.09, +3.0);
                    sum += GrabPixel(i, 0.05, +4.0);

                    // sum += GrabPixel(i, 0.01, -9.0);
                    // sum += GrabPixel(i, 0.02, -8.0);
                    // sum += GrabPixel(i, 0.03, -7.0);
                    // sum += GrabPixel(i, 0.04, -6.0);
                    // sum += GrabPixel(i, 0.05, -5.0);
                    // sum += GrabPixel(i, 0.06, -4.0);
                    // sum += GrabPixel(i, 0.07, -3.0);
                    // sum += GrabPixel(i, 0.08, -2.0);
                    // sum += GrabPixel(i, 0.09, -1.0);
                    // sum += GrabPixel(i, 0.10,  0.0);
                    // sum += GrabPixel(i, 0.09, +1.0);
                    // sum += GrabPixel(i, 0.08, +2.0);
                    // sum += GrabPixel(i, 0.07, +3.0);
                    // sum += GrabPixel(i, 0.06, +4.0);
                    // sum += GrabPixel(i, 0.05, +5.0);
                    // sum += GrabPixel(i, 0.04, +6.0);
                    // sum += GrabPixel(i, 0.03, +7.0);
                    // sum += GrabPixel(i, 0.02, +8.0);
                    // sum += GrabPixel(i, 0.01, +9.0);

					float4 col5 = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
					float decayFactor = 1.0f;
					if (i.uvgrab.x == 0 && i.uvgrab.y == 0){
						decayFactor = 0;
					}
					sum = lerp(col5, sum, decayFactor) * i.color * _Color;
  
                    return sum;  
                }  
                ENDCG  
            }
        }  
    } 
}
计算是一样的,不过这个相对来说要慢,毕竟是将整个屏幕那来计算的,肯定会慢很多。用法也一样,shader放到一个新建的材质球上,然后将材质球拖到一个Image组件的Material属性栏中即可,这里你可以调整Image的宽高,这样可以指定模糊那一块区域了。

看效果:

然后我移动和调整宽高之后:


当然也可以调成整屏模糊:






  • 15
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
Unity-UGUIUnity游戏引擎中的一个UI系统,可以用来创建和管理用户界面。它提供了丰富的功能和工具,使得开发者能够轻松地制作各种表格。 使用Unity-UGUI制作表格的步骤如下: 1. 创建Canvas对象:在Unity中,首先需要创建一个Canvas对象,作为UI渲染的容器。选择GameObject -> UI -> Canvas,即可创建一个Canvas对象。 2. 添加Table组件:选择Canvas对象,在Inspector面板中点击"Add Component"按钮,然后在搜索栏中输入"Table",选择适合的Table组件,点击添加。 3. 设置表格的行列数:在Table组件的Inspector面板中,设置表格所需的行数和列数。 4. 设置表格样式:可以在Inspector面板中设置表格的颜色、大小等属性,以满足具体需求。 5. 添加表格内容:可以通过代码或者拖拽方式,向表格中添加所需的文本或图片。可以通过操作表格的行列索引,将内容放置在特定的位置。 6. 设置表格的交互性:可以为表格中的每个单元格添加点击事件或其他交互效果,提升用户体验。 7. 调整表格布局:可以通过调整Canvas的大小、位置,或者改变组件之间的层次关系,来调整表格的布局。 8. 完善表格功能:可以根据具体需求,添加更多表格的功能,比如排序、过滤、搜索等。 9. 测试和优化:在表格制作完成后,可以进行测试,查看表格的显示效果和交互效果,并进行优化。 总之,使用Unity-UGUI制作表格,只需简单的操作和设置,就能够创建出各种样式、功能丰富的表格,满足游戏或应用程序的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苏小败在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值