Add transparency to sprite shader with cast shadows and receive shadows and lighting

Alright… I give up and I preface this with saying I know next to nothing about writing shaders. The following is a frankenstein conglomerate of some examples I found people post. I need a shader for my 2.5D game for sprites that casts and receives shadows, has ZWrite On, is affected by lighting, and allows transparency

Right now, it seems to do all but allow transparency.

Any help is appreciated!

    Shader "Sprites/Bumped Diffuse with Shadows"
    {
Properties
{
	[PerRendererData]  _MainTex ("Color (RGB) Alpha (A)", 2D) = "white"{}
	//_BumpMap ("Normalmap", 2D) = "bump" {}
	_Color ("Tint", Color) = (1,1,1,1)
	[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
			_Cutoff ("Alpha Cutoff", Range (0,1)) = 0.5

}

SubShader
{
	Tags
	{ 
		"Queue"="Transparent" 
		"IgnoreProjector"="True" 
		"RenderType"="Transparent" 
		"PreviewType"="Plane"
		"CanUseSpriteAtlas"="True"
		
	}
		LOD 300

	Cull Off
	Lighting On
	ZWrite On
	Fog { Mode Off }
	

	CGPROGRAM
	#pragma surface surf Lambert alpha vertex:vert addshadow alphatest:_Cutoff 
	#pragma multi_compile DUMMY PIXELSNAP_ON 

	sampler2D _MainTex;
	sampler2D _BumpMap;
	fixed4 _Color;

	struct Input
	{
		float2 uv_MainTex;
		float2 uv_BumpMap;
		fixed4 color;
	};
	
	void vert (inout appdata_full v, out Input o)
	{
		#if defined(PIXELSNAP_ON) && !defined(SHADER_API_FLASH)
		v.vertex = UnityPixelSnap (v.vertex);
		#endif
		v.normal = float3(0,0,-1);
		v.tangent =  float4(1, 0, 0, 1);
		
		UNITY_INITIALIZE_OUTPUT(Input, o);
		o.color = _Color;
	}

	void surf (Input IN, inout SurfaceOutput o)
	{
		fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * IN.color;
		o.Albedo = c.rgb;
		o.Alpha = c.a;
		o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
	}
	ENDCG
}

    Fallback "Transparent/Cutout/Diffuse"
    }

This is a hard problem to solve (and it’s not specific to Unity). I’ll try to explain my understanding of it:

The shadowing process which Unity follows is firstly to loop through each light and calculate the shadows it casts to create a shadow “buffer” in screenspace. Then, when objects that receive shadows are rendered, they sample from this buffer, again in screenspace. The assumption is therefore that any given pixel drawn to the screen corresponds to a unique position in the world, and this is what the shadow buffer uses to represent whether a point lies in shadow or not.

The problem is that, as soon as you introduce semi-transparent objects, this assumption no longer holds true: any given pixel when seen through a semi-transparent object is a composite of at least two objects at different depths, but the shadow buffer is unable to represent this. In the rendering pipeline, the problem is solved by transparent objects being sorted furthest to closest before rendering to make them appear correct, but the shadowmap processes lights in an arbitrary order - no sorting is done.

The reason why Transparent/Cutout shaders work is because they have no transparency, as such - they’re opaque but with some discarded fragments.

It is possible to fix, but it’s not on the current Unity roadmap, and the performance might be horrible. Aras has said that it certainly won’t be coming any time in the next few months. See here for a full discussion.

@kernjiro Did you find a solution for this problem?