模糊-毛玻璃

效果

Shader "UI/UiObscure"
{
    Properties
    {
        _Radius("Radius", Range(1, 255)) = 1
        _MainTex("Tint Color (RGB)", 2D) = "white" {}
        _Interval("Blur Nuance",Range(0.1, 100)) = 1
        [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("Stencil Comparison", Float) = 8
        [HideInInspector] _Stencil ("Stencil ID", Float) = 0
        [HideInInspector][Enum(UnityEngine.Rendering.StencilOp)] _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

        // Outline properties are drawn via custom editor.
        [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0
        [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1)
        [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024
        [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25
        [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0
        [HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1
        [HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0
    }
 
    Category
    {
        Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" }
 
        SubShader
        { 
        
            Stencil
            {
            	Ref [_Stencil]
            	Comp [_StencilComp]
            	Pass [_StencilOp]
            	ReadMask [_StencilReadMask]
            	WriteMask [_StencilWriteMask]
            }
            
            Cull Off
            Lighting Off
            ZWrite Off
            ZTest [unity_GUIZTestMode]
            Fog { Mode Off }
            Blend One OneMinusSrcAlpha
            ColorMask [_ColorMask]
            
        	GrabPass
            {
        	    Tags{ "LightMode" = "Always" }
            }
    
        	Pass
            {
        	    Tags{ "LightMode" = "Always" }
    
        	    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;
                };
    
                struct v2f
                {
                	float4 vertex : POSITION;
                	float4 uvgrab : TEXCOORD0;
                };
    
                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;
                    return o;
                }
    
                sampler2D _GrabTexture;
                float4 _GrabTexture_TexelSize;
                float _Radius;
                float _Interval;
                half4 frag(v2f i) : COLOR
                {
                    half4 sum = half4(0,0,0,0);
             
                    #define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))
             
                    sum += GRABXYPIXEL(0.0, 0.0);
                    int measurments = 1;
             
                    for (float range = _Interval; range <= _Radius; range += _Interval)
                    {
                        sum += GRABXYPIXEL(range, range);
                        sum += GRABXYPIXEL(range, -range);
                        sum += GRABXYPIXEL(-range, range);
                        sum += GRABXYPIXEL(-range, -range);
                        measurments += 4;
                    }
                    return sum / measurments;
                }
        	    ENDCG
            }
        	GrabPass
            {
            	Tags{ "LightMode" = "Always" }
            }
    
        	Pass
            {
        	    Tags{ "LightMode" = "Always" }
    
        	    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;
                };
    
                struct v2f
                {
                	float4 vertex : POSITION;
                	float4 uvgrab : TEXCOORD0;
                };
    
                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;
                	return o;
                }
    
                sampler2D _GrabTexture;
                float4 _GrabTexture_TexelSize;
                float _Radius;
    
                half4 frag(v2f i) : COLOR
                {
            
                	half4 sum = half4(0,0,0,0);
                	float radius = 1.41421356237 * _Radius;
            
                    #define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))
            
                	sum += GRABXYPIXEL(0.0, 0.0);
                	int measurments = 1;
            
                	for (float range = 1.41421356237f; range <= radius * 1.41; range += 1.41421356237f)
                	{
                		sum += GRABXYPIXEL(range, 0);
                		sum += GRABXYPIXEL(-range, 0);
                		sum += GRABXYPIXEL(0, range);
                		sum += GRABXYPIXEL(0, -range);
                		measurments += 4;
                	}
            
                	return sum / measurments;
                }
        	    ENDCG
            }
        }
    }
}