Recieving and Casting Shadows on Clipped Surfaces

Hi,
my problem is the following:
I am using a modified Standard Surface Shader and clip it using a Singed Distance Function, but I guess that does not matter.
However depending on the chosen Render-Queue the clipped surface blocks shadows behind it and recieves shadows (Geometry) or does not recieve shadows at all (Transparent). I know this makes sense, since transparent Objects are drawn last (?) back to front.

In Geometry Queue

In Transparent Queue

The effect I desire is that shadows can be seen through the clipped surface and that the still visible part of the surface is able to recieve shadows and that the shadow that the clipped surface casts is also clipped.

Maybe this is impossible, but I guess this is the best place to ask. I allready tried to make it work with stencils, but it had the same effect. I found this entry ( Why do clipped pixels still receive shadows (in a Surface Shader)? ), but couldn’t really figure out what was going on.

Regards
Peter

P.S.: this is my code so far

Shader "Custom/SDF_Test"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
        Cull Off   

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0

        struct Input
        {
            float3 worldPos;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
     
        float sdBox(float3 p, float3 b)
        {
            float3 q = abs(p) - b;
            return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
        }

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = fixed4(IN.worldPos, 1.0);
           
            float d = sdBox(IN.worldPos, float3(1.0, 1.0, 1.0));
            clip(-d);

            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;

        }
        ENDCG
    }
    FallBack "Standard"
}

In the post you linked to they were trying to have an object that was clipped with shadows that were not clipped. This is possible, but difficult and not straightforward. It also has some caveats. It’s also not what you want.

You want both clipped, and that’s quite straightforward. The problem is you’re using a custom surface shader that’s clipping, but the shadow caster pass is coming from the fallback shader, and that default shadow caster isn’t doing any clipping. So instead you just want the surface shader to generate its own shadow caster pass that does do the clipping. For that, just add addshadow to the #pragma surface line.

As for why this affects the shadow receiving, that’s because the way Unity does shadows for the main directional light, at least on PC and consoles, is to cast the shadow on the camera depth texture. The camera depth texture is generated using all opaque objects’ shadow caster pass.

1 Like

Thanks for your reply, I added addshadow to my shader and it indeed worked as you described. I guess I learned something about fallback shaders…