directional light shadow map tearing

I’m trying to get shadows working with my shader. My shader just takes a heightmap and offsets the verts of a plane based on it.

Everything seems ok until the angle of the directional light reaches a certain point, then the shadows seem to rip themselves apart.

Also there is the weird shadow cascade issue which you can see in there as well, but i’m less worried about that (but still curious how to fix it).

Shader "Tak/test1"
{
    Properties
    {
        _MainTex("HeightMap", 2D) = "white" {}
        _MeshYOffsetScale("Mesh Y Offset Scale", Float) = 250.0
    }
    SubShader
    {

        Pass
        {
            Tags { "LightMode" = "ShadowCaster" }
            CGPROGRAM
            #pragma vertex shadVert
            #pragma fragment shadFrag
            #pragma multi_compile_shadowcaster
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float _MeshYOffsetScale;

            struct VertexData { float4 position : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; };

            float4 shadVert(VertexData v) : SV_POSITION
            {
                v.position.y = tex2Dlod(_MainTex, float4(v.uv.x, v.uv.y, 0, 0)).r * _MeshYOffsetScale;
                v.normal = float3(0.0, 1.0, 0);
                float4 position = UnityClipSpaceShadowCasterPos(v.position.xyz, v.normal);
                return UnityApplyLinearShadowBias(position);
            }
            half4 shadFrag() : SV_TARGET
            {
                return 0;
            }
            ENDCG
        }

        Pass
        {
            Tags { "LightMode" = "ForwardBase" }
            CGPROGRAM
            #pragma multi_compile_fwdbase
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "AutoLight.cginc"

            sampler2D _MainTex;
            float _MeshYOffsetScale;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                LIGHTING_COORDS(1, 2)
            };


            v2f vert(appdata v)
            {
                v.vertex.y = tex2Dlod(_MainTex, float4(v.uv.x, v.uv.y, 0, 0)).r * _MeshYOffsetScale;
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                TRANSFER_VERTEX_TO_FRAGMENT(o);
                return o;
            }

            static const float PI = 3.14159265f;
            float4 frag(v2f i) : SV_Target
            {
                float attenuation = LIGHT_ATTENUATION(i);
                float3 color = tex2D(_MainTex, i.uv);
                return float4(color,1) * attenuation;
            }
            ENDCG
        }
    }
//Fallback "VertexLit"
}

By default Unity shaders use Cull Back. This means only front facing polygons are drawn and back facing polygons are hidden. Generally this is what you want, but in the case of your terrain, you’ve got a bit of a valley and when the light gets down to roughly horizontal there’s no front facing surfaces to cast a shadow from.

The easy fix is to change your shadow caster pass to have this extra line after Tags and before CGPROGRAM:

Cull Off

1 Like

I thought i had tried that before… there is still a problem though with just that one line change and light still comes through the bottom. I thought it might be due to the normals just pointing upwards but that doesn’t really explain the light coming through when the directional light is pointed up. Also adjusting the bias levels didn’t help.

The shadow attention only handles the shadow itself. When the light is coming up from below, there’s nothing there to cast a shadow at all. The only reason you get any shadowing at all at that point is due to shadow biasing pushing the surface downward. Basically you’re seeing artifacts that shading would normally hide because the shadow maps alone don’t handle all shading.

1 Like

oh duh :frowning: thank you so much for the help! i find a ton of the question i have being answered by you on this forum as well so MANY thanks to you, you are amazing!

here it is with some N dot L lighting and textures now: