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的宽高,这样可以指定模糊那一块区域了。

看效果:

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • UnityShader使用图像叠加实现运动模糊

    本文实例为大家分享了UnityShader实现运动模糊的具体代码,供大家参考,具体内容如下 1.此代码挂在摄像机上,使摄像机运动起来 using UnityEngine; using System.Collections; public class Translating : MonoBehaviour { public float speed = 10.0f; public Vector3 startPoint = Vector3.zero; public Vector3 endPoint =

  • Unity shader实现高斯模糊效果

    本文实例为大家分享了Unity shader实现高斯模糊效果的具体代码,供大家参考,具体内容如下 正常图: 高斯模糊效果图: shader代码: Shader "Custom/GaoSiMoHu" { Properties { _MainTex ("Texture", 2D) = "white" {} _BlurSize("Blur size",Float)=1.0 } SubShader { ZTest Always cul

  • Unity3D UGUI特效之Image高斯模糊效果

    这几天研究了下模糊特效,看了很多文章,其原理就是拿取图片或屏幕数据,然后将周围的元素和目标位置的颜色值进行一个融合计算,然后自己写了一个小小的测试程序. 这个模糊也可以分成两种,一个是自身模糊,一个是从屏幕上取值进行模糊.第一个用于一些小的列表展示,比如未解锁时,是模糊的.第二个是凸显弹框效果的,将背景都模糊掉,自己将这个稍微加强了些可以指定模糊一个位置. 针对移动平台,使用高斯模糊,其实效率不是很高,如果要很好的效果,那么速度卡:如果要速度快,那么效果达不到要求.但是还是在这里记录下,兴许以后

  • Unity3D UGUI实现翻书特效

    本文实例为大家分享了Unity3D UGUI翻书展示的具体代码,供大家参考,具体内容如下 参考大佬的,链接找不到了,找到了再加在这. 下边是Shader代码: // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Personal/PageTurning" { Properties { _Color ("Color", Color) = (

  • iOS实现背景高斯模糊效果

    废话不多说,实现简单的高斯模糊的效果代码: UIView *bgview= [[UIViewalloc]initWithFrame:self.view.frame]; // bgview.backgroundColor = [UIColor blackColor]; // bgview.alpha = 0.9; bgview.tag =10086; [self.viewaddSubview:bgview]; UIBlurEffect *blur = [UIBlurEffecteffectWith

  • Android 动态高斯模糊效果教程

    写在前面 最近一直在做毕设项目的准备工作,考虑到可能要用到一个模糊的效果,所以就学习了一些高斯模糊效果的实现.比较有名的就是 FastBlur 以及它衍生的一些优化方案,还有就是今天要说的RenderScript . 因为这东西是现在需要才去学习的,所以关于一些图像处理和渲染问题就不提了.不过在使用的过程中确实能感受到,虽然不同的方案都能实现相同的模糊效果,但是效率差别真的很大. 本篇文章实现的高斯模糊是根据下面这篇文章学习的,先推荐一下.本文内容与其内容差不多,只是稍微讲的详细一点,并修改了代

  • Android 实现高斯模糊效果且兼容低版本

    一.效果演示 项目中用到了高斯模糊效果,查阅过一些资料,考虑到性能问题最终还是选择使用Android自带的RenderScript库来实现,关于使用RenderScript来实现高斯模糊网上也有很多类似的方法,大部分都总结的比较乱,此处算是做一个整理吧,供有类似需求的同学参考及学习. (项目效果图) 简单描述项目效果图的实现思路: ① 加载定义的xml的Layout ② 使用截屏方法获取当前窗口的Bitmap对象 ③ 将Bitmap对象进行压缩及高斯模糊处理 ④ 将处理过的模糊图对象作为①中所加

  • 一行java代码实现高斯模糊效果

    本文实例为大家分享了本地图片或者网络图片高斯模糊效果(毛玻璃效果),具体内容如下 首先看效果图 1.本地图片高斯模糊 2.网络图片高斯模糊 github网址:https://github.com/qiushi123/BlurImageQcl 下面是使用步骤 一.实现本地图片或者网络图片的毛玻璃效果特别方便,只需要把下面的FastBlurUtil类复制到你的项目中就行 package com.testdemo.blur_image_lib10; import android.graphics.Bi

  • js canvas画布实现高斯模糊效果

    最近项目中有一个需求是实现图片的局部模糊效果,看上去一个挺难的效果.在实现局部模糊效果前,首先能够实现全部模糊.经过和度娘的一番较劲后,找到了一个不错的案例,然后在他的基础上,经过一番修改,和备注,实现了当前的案例: <!doctype html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" cont

  • Android项目实战之Glide 高斯模糊效果的实例代码

    核心需要高斯模糊的库 compile 'jp.wasabeef:glide-transformations:2.0.1' 针对于3.7的版本 使用方法为: //加载背景, Glide.with(MusicPlayerActivity.this) .load(service.getImageUri()) .dontAnimate() .error(R.drawable.no_music_rotate_img) // 设置高斯模糊,模糊程度(最大25) 缩放比例 .bitmapTransform(n

  • Unity3D UGUI实现缩放循环拖动卡牌展示效果

    本文实例为大家分享了Unity3D UGUI实现缩放循环拖动卡牌展示的具体代码,供大家参考,具体内容如下 需求:游戏中展示卡牌这种效果也是蛮酷炫并且使用的一种常见效果,下面我们就来实现以下这个效果是如何实现. 思考:第一看看到这个效果,我们首先会想到UGUI里面的ScrollRect,当然也可以用ScrollRect来实现缩短ContentSize的width来自动实现重叠效果,然后中间左右的卡牌通过计算来显示缩放,这里我并没有用这种思路来实现,我提供另外一种思路,就是自己去计算当前每个卡牌的位

随机推荐