Unity PostProcess Effect – Radial Blur

实现体现速度感的径向模糊 冲鸭
原理


1.首先设定一个径向模糊的中心点
2.然后图上的像素点沿该点到中心点的方向,取n个点采样,目标点的颜色就是这些采样点颜色的均值。
3.所以离中心点越近越密集,越远越稀疏。

实现

1.C#部分代码

[ExecuteInEditMode]
public class RadialBlur : MonoBehaviour
{
    public Shader shader;

    public int samples = 16;
    [Range(0,1)] public float effectAmount = 0.01f;
    public Vector2 centerPos = Vector2.one/2;
    public float radius = 0.1f;
    public float falloff = 0.1f;

    private Material material = null;

    private Material GetMaterial()
    {
        if (material == null)
        {
            material = new Material(shader);
            material.hideFlags = HideFlags.HideAndDontSave;
        }
        return material;
    }

    void Start()
    {
        if (shader == null)
        {
            shader = Shader.Find("Hidden/RadialBlur");
        }
    }

    void OnRenderImage(RenderTexture source, RenderTexture dest)
    {
        var mat = GetMaterial();
        mat.SetInt("_Samples", samples);
        mat.SetFloat("_EffectAmount", effectAmount);
        mat.SetFloat("_CenterX", centerPos.x);
        mat.SetFloat("_CenterY", centerPos.y);
        mat.SetFloat("_Radius", radius);
        mat.SetFloat("_FallOff", falloff);

        Graphics.Blit(source, dest, mat);
    }
}

2.Shader部分

Shader "Hidden/RadialBlur"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Samples("Samples", Range(4, 32)) = 16
        _EffectAmount("Effect amount", Range(0, 1)) = 0.2
        _CenterX("Center X", float) = 0.5
        _CenterY("Center Y", float) = 0.5
        _FallOff("Center Y", float) = 0.1
    }

    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float _Samples;
            float _EffectAmount;
            float _CenterX;
            float _CenterY;
            float _Radius;
            float _FallOff;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = fixed4(0,0,0,0);
                float2 dir = i.uv - float2(_CenterX, _CenterY);

                for(int j = 0; j < _Samples; j++) {
                    col += tex2D(_MainTex, i.uv-dir*j*_EffectAmount);
                }
                col /= _Samples;
                col = lerp(tex2D(_MainTex, i.uv),col,saturate((length(dir)) / _FallOff));
                return col;
            }
            ENDCG
        }
    }
}
效果预览

添加中心清晰的效果

简单修改一下公式就可以,原理如图

只看0到1部分,0.2是衰减速度。
左图是从0直接开始衰减,到1之后取1。
右图是有一个0.5范围,在0-0.5之间都是0,0.5之后开始衰减,到1之后取1。

映射到效果上就是
原来的效果是从中心点向外直接做径向模糊效果。
现在减去了一个阈值,从这个阈值外才开始出现模糊效果。

更新公式
// 添加属性
Properties
{
    ……
    _FallOff("Center Y", float) = 0.1
}

float _FallOff;

// 修改公式
fixed4 frag (v2f i) : SV_Target
{
    ……
    col = lerp(tex2D(_MainTex, i.uv),col,saturate((length(dir)-_Radius) / _FallOff));
    return col;
}
添加了中心清晰的效果预览


Done!(๑•̀ㅂ•́)و✧

One Comment

Add a Comment

您的电子邮箱地址不会被公开。 必填项已用*标注