怎么在 Unity Shader 中自定义阴影的颜色

我们在大多数时候,是不需要考虑物体投射下来的影子是什么样的,但是难免会有这种情况。
比如我需要改变某个物体影子的颜色,今天就来说说这个该怎么写。
这里我把几个关键的点列出来。


首先如果是前向渲染,这句一定要有,否则光线的颜色可能输出的是一个黑色

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
}

你可能感兴趣的:(Shader)