How to make Receive shadow shader in URP

So I fallowed the Unity manual Unity - Manual: Custom shader fundamentals , section “Receiving shadows”. And it works well.

But I want TODO the same thing in URP, but it simply not working with this code. Here is my try until now:

Shader "Unlit/Kaka"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline" }
        LOD 100

        Pass
        {
            Tags{ "LightMode" = "UniversalForward" }

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            #pragma multi_compile_fwdbase// nolightmap nodirlightmap nodynlightmap novertexlight
            #include "AutoLight.cginc"

            /*struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };*/

            struct v2f
            {
                float2 uv : TEXCOORD0;
                //UNITY_FOG_COORDS(1)
                SHADOW_COORDS(1)
                float4 pos : SV_POSITION;                               
                fixed3 diff : COLOR0;
                fixed3 ambient : COLOR1;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);

                //UNITY_TRANSFER_FOG(o,o.vertex);
               
                half3 worldNormal = UnityObjectToWorldNormal(v.normal);
                half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz));
                o.diff = nl * _LightColor0.rgb;
                o.ambient = ShadeSH9(half4(worldNormal, 1));
               
                TRANSFER_SHADOW(o)

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                //UNITY_APPLY_FOG(i.fogCoord, col);

                fixed shadow = SHADOW_ATTENUATION(i);
                fixed3 lighting = i.diff * shadow + i.ambient;

                col.rgb *= lighting;

                return col;
            }
            ENDCG
        }

        // shadow casting support
        UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
    }
}

I hope somebody can help :slight_smile:

So my new version:

Shader "Universal Render Pipeline/Unlit2"
{
    Properties
    {
        _BaseMap("Texture", 2D) = "white" {}
        _BaseColor("Color", Color) = (1, 1, 1, 1)
        _Cutoff("AlphaCutout", Range(0.0, 1.0)) = 0.5

            // BlendMode
            [HideInInspector] _Surface("__surface", Float) = 0.0
            [HideInInspector] _Blend("__blend", Float) = 0.0
            [HideInInspector] _AlphaClip("__clip", Float) = 0.0
            [HideInInspector] _SrcBlend("__src", Float) = 1.0
            [HideInInspector] _DstBlend("__dst", Float) = 0.0
            [HideInInspector] _ZWrite("__zw", Float) = 1.0
            [HideInInspector] _Cull("__cull", Float) = 2.0

            // Editmode props
            [HideInInspector] _QueueOffset("Queue offset", Float) = 0.0

            // ObsoleteProperties
            [HideInInspector] _MainTex("BaseMap", 2D) = "white" {}
            [HideInInspector] _Color("Base Color", Color) = (0.5, 0.5, 0.5, 1)
            [HideInInspector] _SampleGI("SampleGI", float) = 0.0 // needed from bakedlit
    }
        SubShader
            {
                Tags { "RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" }
                LOD 300

                Pass
                {
               
                Name "Unlit"
                Tags { "LightMode" = "UniversalForward" }

                // Use same blending / depth states as Standard shader
                Blend[_SrcBlend][_DstBlend]
                ZWrite[_ZWrite]
                Cull[_Cull]

                HLSLPROGRAM
                // Required to compile gles 2.0 with standard srp library
                #pragma prefer_hlslcc gles
                #pragma exclude_renderers d3d11_9x
                #pragma target 2.0

                #pragma vertex vert
                #pragma fragment frag
                #pragma shader_feature _ALPHATEST_ON
                #pragma shader_feature _ALPHAPREMULTIPLY_ON

                // -------------------------------------
                // Unity defined keywords
                #pragma multi_compile_fog
                #pragma multi_compile_instancing

                #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

                struct Attributes
                {
                    float4 positionOS       : POSITION;
                    float2 uv               : TEXCOORD0;
                    float3 normalOS     : NORMAL;
                    float4 tangentOS    : TANGENT;
                    UNITY_VERTEX_INPUT_INSTANCE_ID
                };

                struct Varyings
                {
                    float2 uv        : TEXCOORD0;
                    float fogCoord : TEXCOORD1;
                    float4 vertex : SV_POSITION;                   
                    half3  normalWS : TEXCOORD2;
                    float4 shadowCoord : TEXCOORD3;

                    UNITY_VERTEX_INPUT_INSTANCE_ID
                    UNITY_VERTEX_OUTPUT_STEREO
                };

                Varyings vert(Attributes input)
                {
                    Varyings output = (Varyings)0;

                    UNITY_SETUP_INSTANCE_ID(input);
                    UNITY_TRANSFER_INSTANCE_ID(input, output);
                    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

                    VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
                    output.vertex = vertexInput.positionCS;
                    output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
                    output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
                    output.shadowCoord = GetShadowCoord(vertexInput);
                   
                    VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
                    output.normalWS = vertexNormalInput.normalWS;

                    return output;
                }

                half4 frag(Varyings input) : SV_Target
                {
                    UNITY_SETUP_INSTANCE_ID(input);
                    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

                                    

                    half2 uv = input.uv;
                    half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
                    half3 color = texColor.rgb * _BaseColor.rgb;
                    half alpha = texColor.a * _BaseColor.a;
                    AlphaDiscard(alpha, _Cutoff);

    #ifdef _ALPHAPREMULTIPLY_ON
                    color *= alpha;
    #endif
                    Light mainLight = GetMainLight(input.shadowCoord);

                    half3 attenuatedLightColor = mainLight.color * (mainLight.distanceAttenuation * mainLight.shadowAttenuation);
                    half3 diffuseColor = LightingLambert(attenuatedLightColor, mainLight.direction, input.normalWS);             

                    color *= diffuseColor; //mainLight.shadowAttenuation;
                    color = MixFog(color, input.fogCoord);

                    return half4(color, alpha);
                }
                ENDHLSL
            }
            Pass
            {
                Tags{"LightMode" = "DepthOnly"}

                ZWrite On
                ColorMask 0

                HLSLPROGRAM
                    // Required to compile gles 2.0 with standard srp library
                    #pragma prefer_hlslcc gles
                    #pragma exclude_renderers d3d11_9x
                    #pragma target 2.0

                    #pragma vertex DepthOnlyVertex
                    #pragma fragment DepthOnlyFragment

                    // -------------------------------------
                    // Material Keywords
                    #pragma shader_feature _ALPHATEST_ON

                    //--------------------------------------
                    // GPU Instancing
                    #pragma multi_compile_instancing

                    #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
                    #include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
                    ENDHLSL
                }

                    // This pass it not used during regular rendering, only for lightmap baking.
                    Pass
                    {
                        Name "Meta"
                        Tags{"LightMode" = "Meta"}

                        Cull Off

                        HLSLPROGRAM
                    // Required to compile gles 2.0 with standard srp library
                    #pragma prefer_hlslcc gles
                    #pragma exclude_renderers d3d11_9x
                    #pragma vertex UniversalVertexMeta
                    #pragma fragment UniversalFragmentMetaUnlit

                    #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
                    #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl"

                    ENDHLSL
                }

                UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
            }
                FallBack "Hidden/Universal Render Pipeline/FallbackError"
}

Problem is that mainLight.shadowAttenuation is always 1,1,1. Why?

Solved by adding

#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
                #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
2 Likes

Hi!
Did it works?
Thank you for sharing, but where did you add the la piece of code? Can you post the complete Shadar?
Thank you!!!

Sorry I discarded it and started to work with Shader graph.

I am actually in the same situation…
Had a receiver shadow only shader working with default render pipeline as below :

Shader "ShadowOnly" {
    Properties{
        _Color("Shadow Color", Color) = (1,1,1,1)
        _ShadowInt("Shadow Intensity", Range(0,1)) = 1.0
        _Cutoff("Alpha cutoff", Range(0,1)) = 0.5
    }
        SubShader{
            Tags
            {
                "Queue" = "AlphaTest"
                "IgnoreProjector" = "True"
                "RenderType" = "Transparent"
            }
            LOD 200
            ZWrite Off
            Blend zero SrcColor
        CGPROGRAM
        //        #pragma surface surf ShadowOnly alphatest:_Cutoff noambient approxview halfasview novertexlights nolightmap nodynlightmap nodirlightmap nofog nometa noforwardadd nolppv noshadowmask 
                #pragma surface surf ShadowOnly alphatest:_Cutoff NoLighting noambient
                fixed4 _Color;
                float _ShadowInt;
                struct Input {
                    float2 uv_MainTex;
                };
                inline fixed4 LightingShadowOnly(SurfaceOutput s, fixed3 lightDir, fixed atten)
                {
                    fixed4 c;
                    c.rgb = lerp(s.Albedo, float3(1.0,1.0,1.0), atten);
                    c.a = 1.0 - atten;
                    return c;
                }
                void surf(Input IN, inout SurfaceOutput o) {
                    o.Albedo = lerp(float3(1.0,1.0,1.0), _Color.rgb, _ShadowInt);
                    o.Alpha = 1.0;
                }
                ENDCG
    }
        Fallback "Transparent/Cutout/VertexLit"
}

And then showing pink with URP…
I am searching/testing…

It seems someone gave a solution there :

2 Likes