just in case I forget how to do this shadow shader, and it also fix the repeat/unlimit shadow length projection issue.
ref: https://forum.unity3d.com/threads/add-one-pixel-border-to-a-rendertexture-result-in-shader.389121/
Shader "Cg projector shader for drop shadows" { Properties{ _ShadowTex("Projected Image", 2D) = "white" {} _ShadowStrength("Shadow Strength", Float) = 0.65 } SubShader{ Pass{ ZWrite off Blend Zero OneMinusSrcAlpha Offset -1, -1 CGPROGRAM #pragma vertex vert #pragma fragment frag // User-specified properties uniform sampler2D _ShadowTex; uniform float _ShadowStrength; // Projector-specific uniforms uniform float4x4 unity_Projector; // UnityAPI : from object space to projector space struct vertexInput { float4 vertex : POSITION; float3 normal : NORMAL; }; struct vertexOutput { float4 pos : SV_POSITION; float4 tex : TEXCOORD0; // position in projector space // From: http://en.wikibooks.org/wiki/Cg_Programming/Unity/Projectors }; vertexOutput vert(vertexInput input) { vertexOutput output; output.tex = mul(unity_Projector, input.vertex); output.pos = mul(UNITY_MATRIX_MVP, input.vertex); return output; } float4 frag(vertexOutput input) : COLOR { if (input.tex.w > 0.0) // in front of projector? { // Ref: https://forum.unity3d.com/threads/add-one-pixel-border-to-a-rendertexture-result-in-shader.389121/ // to improve the calculation speed, the if-else checking to locate the one-pixel border points on texture was combine into one checking. // by folding square texture coordinate in to triangle (math model) // ref. UV are alway between 0.0 ~ 1.0 // e.g. for the point x=1.0, y=0.0 float2 uvmasks = min(input.tex, 1.0 - input.tex); // min(Vector2(1.0,0.0), Vector2(0.0,-1.0)) // that uvmasks will result the minimum value (0.0, -1.0); in this case it's smaller then (0.0, 0.0) // and then we take the point color based on the result is bigger then zero point. // smaller than zero will return the white color by OneMinusSrcAlpha(black) return min(uvmasks.x, uvmasks.y) < 0.0 ? float4(0.0, 0.0, 0.0, 0.0) : tex2D(_ShadowTex, input.tex.xy) *_ShadowStrength; } else // behind projector { return float4(0.0, 0.0, 0.0, 0.0); } } ENDCG } } // The definition of a fallback shader should be commented out // during development: Fallback "Projector/Light" }