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"
}