美文网首页Unity技术分享
shader实现屏幕高斯模糊

shader实现屏幕高斯模糊

作者: 陈_筱英 | 来源:发表于2017-11-23 18:52 被阅读17次

         实现屏幕模糊的方法有很多种,有均值模糊,中值模糊和高斯模糊。相信了解 过图像处理的对这些都会有一定的了解。这篇文章要实现屏幕的高斯模糊效果。

           讲起来可能有点复杂,还是上代码吧。

    1.新建一个C#脚本,改脚本必须挂在摄像机上,同事也是继承自PostEffectsBase(上面一篇文章有,就不再上代码了)

    public class GaussianBlur : PostEffectsBase {

    public Shader gaussianBlurShader;

    private Material gaussianBlurMaterial = null;

    public Material material {

    get {

    gaussianBlurMaterial = CheckShaderAndCreateMaterial(gaussianBlurShader, gaussianBlurMaterial);

    return gaussianBlurMaterial;

    }

    }

    // Blur iterations - larger number means more blur.

    [Range(0, 4)]

    public int iterations = 3;

    // Blur spread for each iteration - larger value means more blur

    [Range(0.2f, 3.0f)]

    public float blurSpread = 0.6f;

    [Range(1, 8)]

    public int downSample = 2;

    void OnRenderImage (RenderTexture src, RenderTexture dest) {

    if (material != null) {

    int rtW = src.width/downSample;

    int rtH = src.height/downSample;

    RenderTexture buffer0 = RenderTexture.GetTemporary(rtW, rtH, 0);

    buffer0.filterMode = FilterMode.Bilinear;

    Graphics.Blit(src, buffer0);

    for (int i = 0; i < iterations; i++) {

    material.SetFloat("_BlurSize", 1.0f + i * blurSpread);

    RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);

    // Render the vertical pass

    Graphics.Blit(buffer0, buffer1, material, 0);

    RenderTexture.ReleaseTemporary(buffer0);

    buffer0 = buffer1;

    buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);

    // Render the horizontal pass

    Graphics.Blit(buffer0, buffer1, material, 1);

    RenderTexture.ReleaseTemporary(buffer0);

    buffer0 = buffer1;

    }

    Graphics.Blit(buffer0, dest);

    RenderTexture.ReleaseTemporary(buffer0);

    } else {

    Graphics.Blit(src, dest);

    }}}

    2.新建一个顶点着色器的shader,实现高斯模糊的shader代码如下:

    Shader "Unity Shaders Book/Chapter 12/Gaussian Blur" {

    Properties {

    _MainTex ("Base (RGB)", 2D) = "white" {}

    _BlurSize ("Blur Size", Float) = 1.0

    }

    SubShader {

    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 = mul(UNITY_MATRIX_MVP, 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 = mul(UNITY_MATRIX_MVP, 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"

    }

    注:还是一样的,直接拖一张texture到场景中,但texture的格式要改为Sprite。

    最后实现效果:

    相关文章

      网友评论

        本文标题:shader实现屏幕高斯模糊

        本文链接:https://www.haomeiwen.com/subject/wiqtbxtx.html