I need help with a custom shader!

I’m trying to make a foliage shader based on The Witness (reference image below) and the edges of my texture are transparent. When I apply the shader to a bush, the edges are solid. I’m a beginner at shader scripting and would appreciate any help.


The Witness
Bush
My Shader

Shader Script:

Shader "Custom/WitnessLeaves" {
    Properties {
        _Color ("Tint", Color) = (1, 1, 1, 1) // Leaf color
        _Cutoff ("Alpha Cutoff", Range (0, 1)) = 0.5 // Adjust this threshold for leaf transparency
        _EdgeTransparency ("Edge Transparency", Range (0, 1)) = 0.3 // Control edge transparency
        _MainTex ("Leaf Texture", 2D) = "white" // Texture for the leaves
    }
    SubShader {
        Tags {
            "Queue"="Transparent"
            "RenderType"="TransparentCutout"
        }
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata_t {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

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

            sampler2D _MainTex;
            float4 _Color;
            float _Cutoff;
            float _EdgeTransparency;

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

            half4 frag (v2f i) : SV_Target {
                half4 texColor = tex2D(_MainTex, i.uv);
                half alpha = texColor.a * _EdgeTransparency;
                half4 finalColor = _Color * texColor;
                finalColor.a = step(_Cutoff, alpha);
                return finalColor;
            }
            ENDCG
        }
    }
}

You may want to only discard pixels that are considered transparent, but not do any blending. In this approach, depth test still works, therefore no sorting is required (but sorting front to back is still beneficial for performance).
Set queue to "Queue"="AlphaTest" for proper sorting.
In your fragment shader, call clip(alpha - _Cutoff);. Clip will discard any pixels if negative value is passed in. You don’t need to return texture alpha from your fragment shader.

Mobile tiled GPUs don’t like pixel discarding, it breaks their optimizations. If you want to use alpha blending instead, then return the alpha from your shader (as you are doing), add blend srcAlpha oneMinusSrcAlpha (tells the pass what to do with the returned alpha) and zwrite off (don’t write transparent pixels to depth) to your pass, set both Queue and RenderType tags to “Transparent”. But keep in mind that writing to depth is also important for many post-processing effects and that transparent foliage might cause a ton of overdraw.

If you are rendering with MSAA, search forAlpha to Coverage for antialiased edges. You might be eligible for benefits of both clipping (still writes to depth) and smooth edges that would be produced by the alpha-blend approach.