No Shadow on Custom Surface Shader

Hi There, I have a problem with this Shader.

This shader do the simple shore line, but it didn’t cast any shadow from the environment.

Shader "Grim Pros/Water Shore Line" {
    // SOME LINES ARE COMMENTED FOR THE SAKE OF SIMPLICITY IN ISOMETRIC CAMERA
    Properties{
        _Color("Color", Color) = (1,1,1,1)
        _BlendColor("Blend Color", Color) = (1,1,1,1)
        _MainTex("Albedo (RGB)", 2D) = "white" {}

        // _Glossiness("Smoothness", Range(0,1)) = 0.5
        // _Metallic("Metallic", Range(0,1)) = 0.0
        // _InvFade("Soft Factor", Range(0.01,3.0)) = 1.0
        _FadeLimit("Fade Limit", Range(0.00,1.0)) = 0.3
    }
   
    SubShader{
        Tags{
            "Queue" = "Transparent"
            "RenderType" = "TransparentCutout"
            //"LightMode" = "ForwardAdd"
        }
        LOD 200

        CGPROGRAM
       
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Lambert vertex:vert alpha:fade nolightmap fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
            float4 screenPos;
            float eyeDepth;
            float4 color : COLOR;
        };

        // half _Glossiness;
        // half _Metallic;
        fixed4 _Color;
        fixed4 _BlendColor;
        sampler2D_float _CameraDepthTexture;
        float4 _CameraDepthTexture_TexelSize;

        float _FadeLimit;
        // float _InvFade;

        void vert(inout appdata_full v, out Input o) {
            UNITY_INITIALIZE_OUTPUT(Input, o);
            COMPUTE_EYEDEPTH(o.eyeDepth);
        }

        void surf(Input IN, inout SurfaceOutput o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            // o.Metallic = _Metallic;
            // o.Smoothness = _Glossiness;

            float rawZ = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos));
            float sceneZ = LinearEyeDepth(rawZ);
            float partZ = IN.eyeDepth;

            float fade = 1.0;
            if (rawZ > 0.0) // Make sure the depth texture exists
                fade = 0; // saturate(_InvFade * (sceneZ - partZ));
            //o.Alpha = c.a * fade; //(original line)
            //the rest are lines I've input
            o.Alpha = 1;
            if (fade < _FadeLimit) {
                o.Albedo = c.rgb * fade + _BlendColor * (1 - fade);
                o.Alpha = 0.8;
            }
        }
        ENDCG
    }
    Fallback "VertexLit"
}

I already surf through the internet, and try many possible answer that works for someone, but it didn’t for me.

I tried modify the basic diffuse shader.

// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "Legacy Shaders/Diffuse" {
    Properties {
        _Color ("Main Color", Color) = (1,1,1,1)
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;
        fixed4 _Color;

        struct Input {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o) {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }

    Fallback "Legacy Shaders/VertexLit"
}

I changed the code step by step into above shader, and the shadow disappear when I add this code

// Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Lambert vertex:vert alpha:fade nolightmap fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
            float4 screenPos;
            float eyeDepth;
            float4 color : COLOR;
        };

        // half _Glossiness;
        // half _Metallic;
        fixed4 _Color;
        fixed4 _BlendColor;
        sampler2D_float _CameraDepthTexture;
        float4 _CameraDepthTexture_TexelSize;

        float _FadeLimit;
        // float _InvFade;

        void vert(inout appdata_full v, out Input o) {
            UNITY_INITIALIZE_OUTPUT(Input, o);
            COMPUTE_EYEDEPTH(o.eyeDepth);
        }


Here’s what basic diffuse looks like. There’s a shadow on the water.

And here’s the current shader. There’s a white line on the edge of the ground, but there’s no shadow at all that casts on the water.

And I attached my shader on the water plane only.

Any help would be appreciated.
Thanks

Unity doesn’t support real time shadows on transparent objects.

I see, I can get rid of the alpha:fade one and still get the same effect that I want. But still there’s no shadow. I found that maybe the problem is on “Queue” = “Transparent” .

When I comment it out, all back to normal. There’s shadow. But no white edge on the shore as I want it.

But thanks for point it out.

If you’re using the forward rendering path you can get the depth texture on opaque objects, as the depth texture is rendered as a pass before the main rendering begins. If you’re using deferred, the depth doesn’t exist until after the opaque objects are drawn. Either way, the main directional shadows in Unity actually cast into that “depth texture” rather than the scene geometry, so in this case you can have either the shadows or the water edge, but never both!

To resolve this you would need to use something other than Unity’s built in shadow system, or render out the depth of your “islands” manually, but I would actually suggest maybe just adding the water edge with geometry rather than doing it in a shader.

I see, I never thought of that.

Thanks for your explanation. I’ll take the second option :))