Shader "Unlit/TransparentDissolveEased"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _DissolveTex("Dissolve Texture", 2D) = "white" {}
        _Color("Tint", Color) = (1, 1, 1, 1)
        _EdgeColor ("Edge Color", Color) = (1, 1, 1, 1)
        _Duration ("Duration", Float) = 1
        _AgeSecs ("AgeSecs", Float) = 0
        _EdgeWidth ("Edge Width", Float) = 0.1
        
        [Enum(Linear,0, EaseInQuad,1, EaseInCubic,2, EaseOutQuad,3, EaseOutCubic,4, EaseInOutQuad,5, EaseInOutQuintic,6)] 
        _EaseType ("Easing Type", Int) = 0
    }
    
    SubShader
    {
        Tags
        {
            "IGNOREPROJECTOR" = "true"
            "QUEUE" = "Transparent-100"
            "RenderType" = "Transparent"
        }
        
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha
            ZWrite Off
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _DissolveTex;
            float4 _DissolveTex_ST;
            float4 _Color;
            float _Duration;
            float _AgeSecs;
            float _EdgeWidth;
            float4 _EdgeColor;
            int _EaseType;
            
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            
            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }
            
            float easing_functions(float x, int easeType)
            {
                switch (easeType)
                {
                    case 1: return x * x;                                    // Ease In Quad
                    case 2: return x * x * x;                                // Ease In Cubic
                    case 3: return 1.0 - (1.0 - x) * (1.0 - x);              // Ease Out Quad
                    case 4: return 1.0 - pow(1.0 - x, 3.0);                  // Ease Out Cubic
                    case 5: return x * x * (3.0 - 2.0 * x);                  // Ease In-Out Quad
                    case 6: return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);// Ease In-Out Quintic
                    default: return x;                                       // Linear (default case)
                }
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                float dissolveProgress = saturate(_AgeSecs / _Duration);
                dissolveProgress = easing_functions(dissolveProgress, _EaseType);
                
                float dissolveMask = tex2D(_DissolveTex, i.uv).r;
                float edgeFactor = smoothstep(dissolveProgress - _EdgeWidth, dissolveProgress + _EdgeWidth, dissolveMask);
                
                fixed4 texColor = tex2D(_MainTex, i.uv) * _Color;
                texColor.rgb = lerp(_EdgeColor.rgb, texColor.rgb, edgeFactor);
                texColor.a *= edgeFactor;
                texColor.a *= 1.0 - step(_Duration, _AgeSecs);
                
                return texColor;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}