zoukankan      html  css  js  c++  java
  • Unity 高斯模糊

    高斯模糊(英语:Gaussian Blur),也叫高斯平滑,通常用它来减少图像噪声以及降低细节层次。这种模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同。高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)。 从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作高斯分布,所以这项技术就叫作高斯模糊。图像与圆形方框模糊做卷积将会生成更加精确的焦外成像效果。由于高斯函数的傅立叶变换是另外一个高斯函数,所以高斯模糊对于图像来说就是一个低通滤波器

    Shader:

    Shader "Unlit/GaosiBlur" 
    {
        Properties
        {
            _MainTex("Base (RGB)", 2D) = "white" {}
        _BlurSize("Blur Size", Float) = 1.0
        }
        SubShader
        {
            //使用CGINCLUDE可以在多个pass中使用同一个函数,避免重复代码
            CGINCLUDE
    
            #include "UnityCG.cginc"
    
            sampler2D _MainTex;
            half4 _MainTex_TexelSize;
            float _BlurSize;
    
            struct v2f 
            {
                float4 pos : SV_POSITION;
                half2 uv[5]: TEXCOORD0;
            };
    
            v2f vertBlurVertical(appdata_img v) 
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
    
                half2 uv = v.texcoord;
    
                o.uv[0] = uv;
                o.uv[1] = uv + float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize;
                o.uv[2] = uv - float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize;
                o.uv[3] = uv + float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize;
                o.uv[4] = uv - float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize;
    
                return o;
            }
    
            v2f vertBlurHorizontal(appdata_img v) 
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
    
                half2 uv = v.texcoord;
    
                o.uv[0] = uv;
                o.uv[1] = uv + float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize;
                o.uv[2] = uv - float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize;
                o.uv[3] = uv + float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize;
                o.uv[4] = uv - float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize;
    
                return o;
            }
    
            fixed4 fragBlur(v2f i) : SV_Target
            {
                float weight[3] = { 0.4026, 0.2442, 0.0545 };
    
                fixed3 sum = tex2D(_MainTex, i.uv[0]).rgb * weight[0];
    
                for (int it = 1; it < 3; it++) {
                    sum += tex2D(_MainTex, i.uv[it * 2 - 1]).rgb * weight[it];
                    sum += tex2D(_MainTex, i.uv[it * 2]).rgb * weight[it];
                }
    
                return fixed4(sum, 1.0);
            }
    
            ENDCG
    
            ZTest Always Cull Off ZWrite Off
    
            Pass 
            {
            NAME "GAUSSIAN_BLUR_VERTICAL"
    
                CGPROGRAM
        
                #pragma vertex vertBlurVertical  
                #pragma fragment fragBlur
    
                ENDCG
            }
    
            Pass 
            {
                NAME "GAUSSIAN_BLUR_HORIZONTAL"
    
                CGPROGRAM
    
                #pragma vertex vertBlurHorizontal  
                #pragma fragment fragBlur
    
                ENDCG
            }
        }
            FallBack "Diffuse"
    }

    脚本:

    public Shader gaosiShader;
    
        private Material gaosiMaterial;
        // 搞死模糊处理的次数
        [Range(0, 4)]
        public int iterations = 3;
    
        // 越大越模糊
        [Range(0.2f, 3.0f)]
        public float blurSpread = 0.6f;
    
        //控制搞死模糊采样的图片分辨率,提高性能降低质量
        [Range(1, 8)]
        public int downSample = 2;
        private void GaosiBlur(RenderTexture source, RenderTexture destination)
        {
                int rtW = source.width / downSample;
                int rtH = source.height / downSample;
    
                RenderTexture buffer0 = RenderTexture.GetTemporary(rtW, rtH, 0);
                buffer0.filterMode = FilterMode.Bilinear;
    
                Graphics.Blit(source, buffer0);
    
                for (int i = 0; i < iterations; i++)
                {
                    gaosiMaterial.SetFloat("_BlurSize", 1.0f + i * blurSpread);
    
                    RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);
    
                    // Render the vertical pass
                    Graphics.Blit(buffer0, buffer1, gaosiMaterial, 0);
    
                    RenderTexture.ReleaseTemporary(buffer0);
                    buffer0 = buffer1;
                    buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);
    
                    // Render the horizontal pass
                    Graphics.Blit(buffer0, buffer1, gaosiMaterial, 1);
    
                    RenderTexture.ReleaseTemporary(buffer0);
                    buffer0 = buffer1;
                }
    
                Graphics.Blit(buffer0, destination);
                RenderTexture.ReleaseTemporary(buffer0);
        }

    效果:

  • 相关阅读:
    20155203 2016-2017-3 《Java程序设计》第三周学习总结
    20155203 2016-2017-2 《Java程序设计》第2周学习总结
    20155203 2016-2017-2 《Java程序设计》第1周学习总结
    20155203杜可欣预备作业3——虚拟机的安装
    20155335俞昆《java程序设计》第七周总结
    20155335俞昆《java程序设计》第6周总结
    20155335俞昆《Java程序设计》第五周总结
    2016-2017 2 20155335《java程序设计》第四周总结
    20155335俞昆《java程序设计》第三周总结
    20155319 2016-2017-2 《Java程序设计》第九周学习总结
  • 原文地址:https://www.cnblogs.com/litmin/p/8692794.html
Copyright © 2011-2022 走看看