Simple drop shadow shader.

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

 

,

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *

*