Pass
{
Tags{ "LightMode" = "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)
return o;
}
float4 frag(v2f i) : SV_Target
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
上述shader是使物体能够投射阴影,添加到阴影贴图。
#pragma multi_compile_shadowcaster用途是使shader支持关于shadowcaster的一些宏定义,以便支持point light与其他光源的不同处理
V2F_SHADOW_CASTER; 宏定义相当于float3 vec : TEXCOORD0; float4 pos : SV_POSITION
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)可以在UnityCG.cginc找到相当于两个函数:
opos = UnityClipSpaceShadowCasterPos(v.vertex, v.normal); \
opos = UnityApplyLinearShadowBias(opos);
UnityClipSpaceShadowCasterPos(v.vertex, v.normal)
float4 UnityClipSpaceShadowCasterPos(float4 vertex, float3 normal)
{
float4 wPos = mul(unity_ObjectToWorld, vertex);
if (unity_LightShadowBias.z != 0.0)
{
float3 wNormal = UnityObjectToWorldNormal(normal);
float3 wLight = normalize(UnityWorldSpaceLightDir(wPos.xyz));
// apply normal offset bias (inset position along the normal)
// bias needs to be scaled by sine between normal and light direction
// (http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1/)
//
// unity_LightShadowBias.z contains user-specified normal offset amount
// scaled by world space texel size.
float shadowCos = dot(wNormal, wLight);
float shadowSine = sqrt(1-shadowCos*shadowCos);
float normalBias = unity_LightShadowBias.z * shadowSine;
wPos.xyz -= wNormal * normalBias;
}
return mul(UNITY_MATRIX_VP, wPos);
}
函数传入appdata_base v的顶点与法线,把pos(裁剪空间下坐标)进行法线方向的偏移,为的是消除Shadow acne(阴影瑕疵)
UnityApplyLinearShadowBias(float4 clipPos)是对pos增加裁剪空间中的Z坐标的值。