1. 向其他物体投射阴影需要ShadowCaster的Pass
Diffuse的Fallback调用的VertexLit中的ShadowCaster Pass来实现向其他物体投射阴影
Pass{
Name"ShadowCaster"
Tage{"LightMde" = "ShadowCaster"}

CGPROGRAM
#pragma vertex vert
#pragma fragment frag    
#pragma multi_compile_shadowcaster    
#include "UnityCG.cginc"

Struct v2f {
V2F SHADOW CASTER; 
);

v2f vert(appdata_base v)
{
        v2f o;
        TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)//需要v中含有顶点位置与法线信息
        return o;
}
float4 frag(v2f i) : SV_Target
{
        SHADOW_CASTER_FRAGMENT(i)
    }

ENDCG
}
对物体添加顶点动画或局部剔除时要使阴影与变化一致:需要在ShadowCaster的Pass中做出相应的调整
#例如:在顶点动画中
Pass
{
Tags{"LightMode" = "ShadowCaster"}
CGPROGRAM

	float _Manitude;
	float _Frequency;
	float _InvWaveLength;
	float _Speed;

	#pragma vertex vert
	#pragma fragment frag

	#pragma multi_compile_shadowcaster
	#include "UnityCG.cginc"

	struct a2v{
		float4 vertex : POSITION;			
		float4 normal :NORMAL;
	};

	struct v2f{
		V2F_SHADOW_CASTER;
	};

	v2f vert(a2v v)
	{
		v2f o;
		float4 offset ;
		offset.xzw = float3(0.0,0.0,0.0);
		offset.y = sin(_Frequency*_Time.y + v.vertex.x * _InvWaveLength + v.vertex.y*_InvWaveLength + v.vertex.z*_InvWaveLength )*_Manitude;
		v.vertex = v.vertex+offset;

		TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);//
		return o;
	}
	fixed4 frag(v2f i):SV_Target
	{
		SHADOW_CASTER_FRAGMENT(i)
	}
	ENDCG
}

#例如:存在部分剔除时
Pass
{
Tags{"LightMode" = "ShadowCaster"}
CGPROGRAM

	float _ResAmount;
	sampler2D _ResMap;
	float4 _ResMap_ST;

	#pragma vertex vert
	#pragma fragment frag

	#pragma multi_compile_shadowcaster
	#include "UnityCG.cginc"

	struct v2f{
		V2F_SHADOW_CASTER;
		float2 uvBurnMap:TEXCOORD1;
	};

	v2f vert(appdata_base v)
	{
		v2f o;
		TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
		o.uvBurnMap = TRANSFORM_TEX(v.texcoord,_ResMap);
		return o;
	}
	fixed4 frag(v2f i):SV_Target
	{
		fixed3 burn = tex2D(_ResMap,i.uvBurnMap).rgb;
		clip(burn.r-_ResAmount);
		SHADOW_CASTER_FRAGMENT(i)
	}
	ENDCG
}

2. 接收其他物体阴影
(1)首先需要引入内置文件:包含计算阴影时所包含的宏
#include "AutoLight.cginc"
(2)在v2f中添加内置的SHADOW_COORDS宏(用于声明一个用于阴影采样的坐标)
struct v2f {
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD0;
float3 worldPos : TEXCOORD1;
SHADOW_COORDS(2) //参数为下一个可用的寄存器
}
(3)在顶点着色器中用TRANSFER_SHADOW计算阴影纹理坐标
v2f vert(atv v){
v2f o;
......
TRANSFER_SHADOW(o);//使用上一步在v2f中定义的SHADOW_COORD
}
(4)在片原着色器中使用计算阴影
fixed shadow = SHADOW_ATTENUATION(i)//参数为v2f,得到阴影值与漫反、高光相乘即可实现接收阴影

3.使用UNITY_LIGHT_ATTENUATION统一计算阴影与光衰
代码基本同上引用
#include "Lighting.cginc"
#include "AutoLight.cginc"
在片元着色器中使用宏同时计算光衰与阴影
fixed4 frag(v2f i):SV_Target{
......
UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);//第一各参数主动生成,第二个参数v2f用于SHADOW_ATTENUATION计算阴影,第三个参数为世界空间坐标
return fixed4(ambient+(diffuse+specular)*atten,1);
}
FallBack "Transparent/VertexLit"//对于混合实现的透明物体很难实现投射与接收阴影