高斯模糊效果

高斯模糊可以实现模糊效果,可用于眩晕,场景动画等效果

高斯模糊利用了卷积计算,把每个像素和周围的像素混合

见代码实现

c#代码 ImageEffectBase

using UnityEngine;

namespace GameBase.Effect
{
    [RequireComponent(typeof (Camera))]
    [AddComponentMenu("")]
    public class ImageEffectBase : MonoBehaviour
    {
        /// Provides a shader property that is set in the inspector
        /// and a material instantiated from the shader
        public Shader shader;

        private Material m_Material;


        protected virtual void Start()
        {
            // Disable if we don't support image effects
            if (!SystemInfo.supportsImageEffects)
            {
                enabled = false;
                return;
            }

            // Disable the image effect if the shader can't
            // run on the users graphics card
            if (!shader || !shader.isSupported)
                enabled = false;
        }


        protected Material material
        {
            get
            {
                if (m_Material == null)
                {
                    m_Material = new Material(shader);
                    m_Material.hideFlags = HideFlags.HideAndDontSave;
                }
                return m_Material;
            }
        }


        protected virtual void OnDisable()
        {
            if (m_Material)
            {
                DestroyImmediate(m_Material);
            }
        }
    }
}

c#代码 BlurEffect

using UnityEngine;

namespace GameBase.Effect
{
    public class BlurEffect : ImageEffectBase
    {

        [Range(0, 10)]
        [SerializeField]
        private int _downSample = 1;//分辨率降低值

        [SerializeField]
        [Range(0, 8)]
        private float _blurSize = 1;//取周围多远的像素

        [SerializeField]
        [Range(1, 10)]
        private int _filterCount = 1;//滤波次数(越大性能越差)

        private int ID_BlurSize;

        private void OnEnable()
        {
            ID_BlurSize = Shader.PropertyToID("_BlurSize");
        }

        void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            if(_blurSize <= 0 )
            {
                Graphics.Blit(source, destination);
                return;
            }
            int width = source.width >> _downSample;
            int height = source.height >> _downSample;
            if (width <= 0)
                width = 1;
            if (height <= 0)
                height = 1;

            if (_filterCount == 1)
            {
                RenderTexture bufferRT = RenderTexture.GetTemporary(width, height, 0, source.format);
                if (material.HasProperty(ID_BlurSize))
                {
                    material.SetFloat(ID_BlurSize, _blurSize);
                }
                Graphics.Blit(source, bufferRT, material, 0);
                Graphics.Blit(bufferRT, destination, material, 1);
                RenderTexture.ReleaseTemporary(bufferRT);
            }
            else
            {
                RenderTexture bufferRT1 = RenderTexture.GetTemporary(width, height, 0, source.format);
                RenderTexture bufferRT2 = RenderTexture.GetTemporary(width, height, 0, source.format);
               
                if (material.HasProperty(ID_BlurSize))
                {
                    material.SetFloat(ID_BlurSize, _blurSize);
                }
                Graphics.Blit(source, bufferRT1, material, 0);
                for (int i = 1; i < _filterCount; i++)
                {
                    Graphics.Blit(bufferRT1, bufferRT2, material, 1);
                    Graphics.Blit(bufferRT2, bufferRT1, material, 0);
                }

                Graphics.Blit(bufferRT1, destination, material, 1);

                RenderTexture.ReleaseTemporary(bufferRT1);
                RenderTexture.ReleaseTemporary(bufferRT2);
            }

        }
    }
}

shader代码 

Shader "mgo/blur" 
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _BlurSize("_BlurSize", range(0, 300)) = 1
    }

    SubShader
    {
        Tags{ "RenderType" = "Opaque" }
        
        ZTest Off
        cull Off
        ZWrite Off

        Pass
        {
            Name "Horizontal"
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata {
                float4 vertex:POSITION;
                float2 uv:TEXCOORD0;
            };

            struct v2f
            {
                float4 pos:SV_POSITION;
                float2 uv[5]:TEXCOORD0;
            };

            uniform sampler2D _MainTex;
            //xxx_TexelSize 是用来访问xxx纹理对应的每个文素的大小 ,如一张512*512的图该值大小为1/512≈0.001953125
            uniform float4 _MainTex_TexelSize;
            uniform half _BlurSize;

            v2f vert(appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                half2 uv = v.uv;
                o.uv[0] = uv;
                o.uv[1] = uv + _MainTex_TexelSize.xy * half2(_BlurSize, 0);
                o.uv[2] = uv + _MainTex_TexelSize.xy * half2(-_BlurSize, 0);
                o.uv[3] = uv + _MainTex_TexelSize.xy * half2(_BlurSize * 2, 0);
                o.uv[4] = uv + _MainTex_TexelSize.xy * half2(-_BlurSize * 2, 0);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed4 col = 0.4 * tex2D(_MainTex,i.uv[0]);
                col += 0.24 * tex2D(_MainTex, i.uv[1]);
                col += 0.24 * tex2D(_MainTex, i.uv[2]);
                col += 0.06 * tex2D(_MainTex, i.uv[3]);
                col += 0.06 * tex2D(_MainTex, i.uv[4]);
                return col;
            }
            ENDCG
        }

        Pass
        {
            Name "Vertical"
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata {
                float4 vertex:POSITION;
                float2 uv:TEXCOORD0;
            };

            struct v2f
            {
                float4 pos:SV_POSITION;
                float2 uv[5]:TEXCOORD0;
            };

            uniform sampler2D _MainTex;
            uniform float4 _MainTex_TexelSize;
            uniform half _BlurSize;

            v2f vert(appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                half2 uv = v.uv;
                o.uv[0] = uv;
                o.uv[1] = uv + _MainTex_TexelSize.xy * half2(0, _BlurSize);
                o.uv[2] = uv + _MainTex_TexelSize.xy * half2(0, -_BlurSize);
                o.uv[3] = uv + _MainTex_TexelSize.xy * half2(0, _BlurSize * 2);
                o.uv[4] = uv + _MainTex_TexelSize.xy * half2(0, -_BlurSize * 2);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed4 col = 0.4 * tex2D(_MainTex,i.uv[0]);
                col += 0.24 * tex2D(_MainTex, i.uv[1]);
                col += 0.24 * tex2D(_MainTex, i.uv[2]);
                col += 0.06 * tex2D(_MainTex, i.uv[3]);
                col += 0.06 * tex2D(_MainTex, i.uv[4]);
                return col;
            }
            ENDCG
        }

        
    }
}


扫描二维码关注公众号,回复: 4698138 查看本文章

猜你喜欢

转载自blog.csdn.net/PangNanGua/article/details/85261212