边缘闪烁效果

作者:追风剑情 发布于:2022-10-7 13:15 分类:Shader

工程截图

22222.png

一、创建Shader

//将官方的Bumped Specular Shader,增加边缘发光功能
Shader "Custom/RimEmission-Bumped Specular" {
    Properties{
        _Color("Main Color", Color) = (1,1,1,1)
        _SpecColor("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
        [PowerSlider(5.0)] _Shininess("Shininess", Range(0.03, 1)) = 0.078125
        _MainTex("Base (RGB) Gloss (A)", 2D) = "white" {}
        _BumpMap("Normalmap", 2D) = "bump" {}
        //增加边缘
        [PerRendererData]
        _RimColor("Rim Color", Color) = (1,1,1,1)
    }

    CGINCLUDE
    sampler2D _MainTex;
    sampler2D _BumpMap;
    fixed4 _Color;
    half _Shininess;

    fixed4 _RimColor;
    float _RimPower;

    struct Input {
        float2 uv_MainTex;
        float2 uv_BumpMap;
        float3 viewDir;
    };

    void surf(Input IN, inout SurfaceOutput o) {
        fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
        o.Albedo = tex.rgb * _Color.rgb;
        o.Gloss = tex.a;
        o.Alpha = tex.a * _Color.a;
        o.Specular = _Shininess;
        //o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    }
    ENDCG

    SubShader{
        Tags { "RenderType" = "Opaque" }
        LOD 400

        CGPROGRAM
        //增加finalColor函数
        #pragma surface surf BlinnPhong finalcolor:RimColor
        #pragma target 3.0

        void RimColor(Input IN, SurfaceOutput o, inout fixed4 color)
        {
            //求法线与视线的夹角cos
            half rim = 1.0 - saturate(dot(normalize(IN.viewDir),o.Normal));
            color = lerp(color * _RimColor, color, rim);
        }
        ENDCG
    }

    SubShader{
        Tags { "RenderType" = "Opaque" }
        LOD 400

        CGPROGRAM
        #pragma surface surf BlinnPhong nodynlightmap
        ENDCG
    }

    FallBack "Legacy Shaders/Specular"
}


二、创建闪烁控制脚本

using UnityEngine;
/// <summary>
/// 控制材质边缘闪烁效果
/// </summary>
public class RimTwinkleEffect : MonoBehaviour
{
    public Renderer render;
    public Color startColor;
    public Color endColor;
    public float speed = 1.0f;
    public bool active = true;
    private MaterialPropertyBlock property;
    private float t=0;
    private bool reverse = false;

    private void Awake()
    {
        property = new MaterialPropertyBlock();
    }

    void Update()
    {
        if (!active)
            return;

        if (reverse)
        {
            t -= speed * Time.deltaTime;
            if (t <= 0)
                reverse = false;
        }
        else
        {
            t += speed * Time.deltaTime;
            if (t >= 1)
                reverse = true;
        }

        Color color = Color.Lerp(startColor, endColor, t);
        SetRimColor(color);
    }

    public void SetRimColor(Color color)
    {
        property.SetColor(
            "_RimColor", color
        );
        render.SetPropertyBlock(property);
    }

    public void Begin()
    {
        active = true;
        SetRimColor(startColor);
    }

    public void Stop()
    {
        active = false;
        SetRimColor(startColor);
    }
}


效果
111.gif

标签: Shader

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号