Shader "Custom/DynamicMatcap"
{
    Properties
    {
        _MainTex ("Material Texture", 2D) = "white" {}
        _Border ("Border", Range(0.1, 0.5)) = 0.43
        _MatcapLightDir ("Texture Light Direction", Vector) = (0,-1,0)

        _ShadowIntensity ("Shadow intensity", Range(0.0, 1.0)) = 0.5
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            Tags { "LightMode"="ForwardBase" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight

            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
            #include "Lighting.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 texcoord : TEXCOORD;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD1;
                float2 cap: TEXCOORD2;
                float3 normal : TEXCOORD3;
                SHADOW_COORDS(0) //Put shadow data into TEXCOORD0
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            half _Border;
            float4 _MatcapLightDir;

            half _ShadowIntensity;

            float3x3 light_matrix(float3 v)
            {
                v.x = -v.x;
                float r = sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
                float phi = atan2(v.z, v.x);
                float theta = atan2(v.y, sqrt(v.x*v.x + v.z*v.z));

                float3 i = float3(sin(phi),   cos(phi)*cos(theta),    cos(phi)*sin(theta) );
                float3 j = float3(0.0,        sin(theta),             -cos(theta)         );
                float3 k = float3(-cos(phi),  sin(phi)*cos(theta),    sin(phi)*sin(theta) );

                return float3x3(i,j,k);
            }

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord;

                float3 lightDir = (_WorldSpaceLightPos0.w == 0) ? _WorldSpaceLightPos0.xyz : normalize(mul((float3x3)UNITY_MATRIX_M, v.vertex) - _WorldSpaceLightPos0.xyz);
                float3x3 lightMatrix = light_matrix(lightDir);

                // float3 w_normal = normalize(mul((float3x3)UNITY_MATRIX_M, v.normal));
                float3 w_normal = UnityObjectToWorldNormal(v.normal);
                // w_normal = mul(lightMatrix, w_normal); //Offset the normal by the light direction
                w_normal = normalize(mul((float3x3)unity_WorldToShadow[0], w_normal));
                w_normal.y = -w_normal.y;
                o.cap = (w_normal * _Border + 0.5f).xy;
                o.normal = w_normal;

                TRANSFER_SHADOW(o)
                // TRANSFER_VERTEX_TO_FRAGMENT(o)

                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float4 col = tex2D(_MainTex, i.cap);
                // float4 col = float4(i.normal, 1.0);
                float attenuation = min(SHADOW_ATTENUATION(i) + (1.0 - _ShadowIntensity), 1.0);
                return col * attenuation;
            }
            ENDCG
        }
        // UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
        Pass
        {
            Tags {"LightMode"="ShadowCaster"}

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_shadowcaster
            #include "UnityCG.cginc"

            struct v2f {
                V2F_SHADOW_CASTER;
            };

            v2f vert(appdata_base v)
            {
                v2f o;
                TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                SHADOW_CASTER_FRAGMENT(i)
            }
            ENDCG
        }
    }
}