Shader "UNSLOW/Grassland/Curved Tuft"
{
    Properties
    {
        _RootColor("Root Color", Color) = (0.20, 0.34, 0.08, 1)
        _TipColor("Tip Color", Color) = (0.58, 0.76, 0.32, 1)
        _WindStrength("Wind Strength", Range(0, 0.2)) = 0.045
        _WindSpeed("Wind Speed", Range(0, 5)) = 1.4
    }

    SubShader
    {
        Tags { "RenderPipeline" = "UniversalPipeline" "RenderType" = "Opaque" "Queue" = "Geometry" }
        Pass
        {
            Tags { "LightMode" = "UniversalForward" }
            Cull Back
            ZWrite On

            HLSLPROGRAM
            #pragma target 3.0
            #pragma vertex Vert
            #pragma fragment Frag
            #pragma multi_compile_instancing

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

            CBUFFER_START(UnityPerMaterial)
                half4 _RootColor;
                half4 _TipColor;
                float _WindStrength;
                float _WindSpeed;
            CBUFFER_END

            struct Attributes
            {
                float3 positionOS : POSITION;
                float3 normalOS : NORMAL;
                float2 uv : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct Varyings
            {
                float4 positionCS : SV_POSITION;
                half3 color : COLOR;
            };

            Varyings Vert(Attributes input)
            {
                UNITY_SETUP_INSTANCE_ID(input);
                Varyings output;
                float3 rootWS = TransformObjectToWorld(float3(0, 0, 0));
                float3 positionWS = TransformObjectToWorld(input.positionOS);
                float t = saturate(input.uv.y);

                float phase = _Time.y * _WindSpeed + rootWS.x * 0.8 + rootWS.z * 1.15;
                float wave = sin(phase) + 0.35 * sin(phase * 1.8 + 1.2);
                positionWS.xz += float2(1, 0.45) * wave * _WindStrength * t * t;
                output.positionCS = TransformWorldToHClip(positionWS);

                float randomValue = frac(sin(dot(rootWS.xz, float2(12.9898, 78.233))) * 43758.5453);
                float patchValue = sin(rootWS.x * 1.3) * sin(rootWS.z * 0.95);
                half3 normalWS = normalize(TransformObjectToWorldNormal(input.normalOS));
                Light sun = GetMainLight();
                half diffuse = saturate(dot(normalWS, sun.direction));
                half3 ambient = SampleSH(half3(0, 1, 0)) * 0.85;
                half3 direct = sun.color * diffuse * 0.7;
                half variation = (half)(0.85 + 0.16 * randomValue + 0.06 * patchValue);
                output.color = lerp(_RootColor.rgb, _TipColor.rgb, smoothstep(0, 0.95, t))
                    * (ambient + direct) * variation;
                return output;
            }

            half4 Frag(Varyings input) : SV_Target
            {
                return half4(input.color, 1);
            }
            ENDHLSL
        }
    }
}
