我们在大多数时候,是不需要考虑物体投射下来的影子是什么样的,但是难免会有这种情况。
比如我需要改变某个物体影子的颜色,今天就来说说这个该怎么写。
这里我把几个关键的点列出来。
首先如果是前向渲染,这句一定要有,否则光线的颜色可能输出的是一个黑色
Tags { "LightMode"="ForwardBase" }
前向光照的变体,没它连影子都不会有
#pragma multi_compile_fwdbase
SHADOW_COORDS 用来装影子坐标
struct VertexOutput
{
float4 pos : SV_POSITION;
float2 uv0 : TEXCOORD0;
SHADOW_COORDS(1)
UNITY_FOG_COORDS(2)
};
TRANSFER_SHADOW 填充影子坐标
VertexOutput vert (VertexInput v)
{
VertexOutput o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv0 = v.texcoord0;
UNITY_TRANSFER_FOG(o, o.pos);
TRANSFER_SHADOW(o) // 填充阴影坐标
return o;
}
在 frag 着色器中,用 SHADOW_ATTENUATION 就可以取得阴影的衰减系数,
用它就可以表示出那些地方在阴影中,哪些在阴影外面,
0=阴影内,1=阴影外,
根据需求,我们就可以用一个 lerp 来实现 if 的逻辑,并将我们自定义的阴影颜色乘到物体本身的颜色上去。
这样我们就可以自己控制别的物体投射到我们物体上影子的颜色了。
fixed4 frag (VertexOutput i) : COLOR
fixed shadowAttenuation = SHADOW_ATTENUATION(i);
fixed4 finalRGBA = lerp(targetRGBA * _ShadowColor, targetRGBA, shadowAttenuation);
有接受,自然就有投射了,如果想往别的物体上投射阴影,它是一个单独的Pass
// Pass to render object as a shadow caster
Pass
{
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
ZWrite On ZTest LEqual Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
struct v2f
{
V2F_SHADOW_CASTER;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata_base v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
return o;
}
float4 frag (v2f i) : SV_Target
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}