Unity眨眼特效

**

Unity眨眼特效

**

效果如图

新建脚本AwakeScreenEffect,挂载在MainCamera上

[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class AwakeScreenEffect : MonoBehaviour
{

    [Range(0f, 1f)]
    [Tooltip("苏醒进度")]
    public float progress;
    [Range(0, 4)]
    [Tooltip("模糊迭代次数")]
    public int blurIterations = 3;
    [Range(.2f, 3f)]
    [Tooltip("每次模糊迭代时的模糊大小扩散")]
    public float blurSpread = .6f;

    public Shader shader;

    // 序列化字段
    [SerializeField]
    Material material;
    // 获取材质
    Material Material
    {
        get
        {
            // 如果材质为空
            if (material == null)
            {
                // 创建一个新的材质
                material = new Material(shader);
                // 隐藏标志
                material.hideFlags = HideFlags.DontSave;
            }
            // 返回材质
            return material;
        }
    }

    // 在组件被禁用时执行
    void OnDisable()
    {
        // 如果material不为空
        if (material)
        {
            // 销毁material
            DestroyImmediate(material);
        }
    }

    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        // 设置进度值
        Material.SetFloat("_Progress", progress);

        // 如果进度值小于1
        if (progress < 1)
        {
            // 获取源纹理宽和高
            int rtW = src.width;
            int rtH = src.height;

            // 创建临时渲染纹理
            var buffer0 = RenderTexture.GetTemporary(rtW, rtH, 0);
            buffer0.filterMode = FilterMode.Bilinear;

            // 渲染到临时渲染纹理
            Graphics.Blit(src, buffer0, Material, 0);

            // 计算模糊大小
            float blurSize;
            for (int i = 0; i < blurIterations; i++)
            {
                // 将进度值(0~1)映射到模糊大小(blurSize~0)
                blurSize = 1f + i * blurSpread;
                blurSize = blurSize - blurSize * progress;
                Material.SetFloat("_BlurSize", blurSize);

                // 创建临时渲染纹理
                var buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);
                // 渲染
                Graphics.Blit(buffer0, buffer1, Material, 1);

                // 释放临时渲染纹理
                RenderTexture.ReleaseTemporary(buffer0);
                buffer0 = buffer1;
                buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);
                // 渲染
                Graphics.Blit(buffer0, buffer1, Material, 2);

                // 释放临时渲染纹理
                RenderTexture.ReleaseTemporary(buffer0);
                buffer0 = buffer1;
            }
            // 渲染到目标渲染纹理
            Graphics.Blit(buffer0, dest);
            // 释放临时渲染纹理
            RenderTexture.ReleaseTemporary(buffer0);
        }
        else
        {
            // 渲染到目标渲染纹理
            Graphics.Blit(src, dest);
        }
    }

}

新建shader:Awake Screen Effect

Shader "Custom/Awake Screen Effect"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _Progress("Progress", Range(0, 1)) = 1
        _ArchHeight("Arch Height", Range(0, .5)) = .2
        _BlurSize("Blur Size", Float) = 1
    }
        SubShader
        {
            ZTest Always ZWrite Off Cull Off

            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                #include "UnityCG.cginc"

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

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

                sampler2D _MainTex;
                float _Progress;
                float _ArchHeight;

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

                fixed4 frag(v2f i) : SV_Target
                {
                    half2 uv = i.uv;
                    fixed4 col = tex2D(_MainTex, uv);

                    // 上眼皮与下眼皮边界
                    float upBorder = .5 + _Progress * (.5 + _ArchHeight);
                    float downBorder = .5 - _Progress * (.5 + _ArchHeight);
                    upBorder -= _ArchHeight * pow(uv.x - .5, 2);
                    downBorder += _ArchHeight * pow(uv.x - .5, 2);

                    // 可视区域
                    float visibleV = (1 - step(upBorder, uv.y)) * (step(downBorder, uv.y));
                    col *= visibleV;
                    col *= _Progress;
                    return col;
                }
                ENDCG
            }

            UsePass "Custom/Gaussian Blur/GAUSSIAN_BLUR_VERTICAL"

            UsePass "Custom/Gaussian Blur/GAUSSIAN_BLUR_HORIZONTAL"

        }

            Fallback Off
}

新建shader:Gaussian Blur

Shader "Custom/Gaussian Blur"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _BlurSize("Blur Size", Float) = 1
    }
        SubShader
        {
            CGINCLUDE
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            half4 _MainTex_TexelSize;
            float _BlurSize;

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

            struct v2f
            {
                half2 uv[5] : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vertBlurVertical(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);

                half2 uv = v.uv;

                // XXX_TexelSize (1 / width, 1 / height, width, height)
                o.uv[0] = uv;
                o.uv[1] = uv + float2(0, _MainTex_TexelSize.y * 1.0) * _BlurSize;
                o.uv[2] = uv - float2(0, _MainTex_TexelSize.y * 1.0) * _BlurSize;
                o.uv[3] = uv + float2(0, _MainTex_TexelSize.y * 2.0) * _BlurSize;
                o.uv[4] = uv - float2(0, _MainTex_TexelSize.y * 2.0) * _BlurSize;

                return o;
            }

            v2f vertBlurHorizontal(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);

                half2 uv = v.uv;

                o.uv[0] = uv;
                o.uv[1] = uv + float2(_MainTex_TexelSize.x * 1.0, 0) * _BlurSize;
                o.uv[2] = uv - float2(_MainTex_TexelSize.x * 1.0, 0) * _BlurSize;
                o.uv[3] = uv + float2(_MainTex_TexelSize.x * 2.0, 0) * _BlurSize;
                o.uv[4] = uv - float2(_MainTex_TexelSize.x * 2.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);
            }

            ENDCG

            ZTest Always ZWrite Off Cull 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 Off
}

在相机上拖上对应的组件,设置参数
在这里插入图片描述
新建Animatior 根据喜好录制成眨眼动画即可实现对应效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼头汤の

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值