AR Multi Directional light shadows

Hi ,

I am working on an AR project these days and I was using this shader provided by Unity to cast shadows in my scene.

Today I wanted to add a second directional light (which should also cast shadows) so I followed the comments written in the shader. I added a new pass with Light Mode set to ForwardAdd and changed the pragma to multi_compile_fwdadd. It didn’t seem to do the trick and I couldn’t find a solution anywhere to cast the shadow of my second light. Am I missing something obvious when following the comments?

Here the shader :

Shader "Custom/Matte Shadow" {
Properties
{
    _Fade ("Wave scale", Range (0,1)) = 0.5 // sliders
         _FadeMarkerDist ("Wave scale", Range (0,1)) = 0.5 // sliders
}

SubShader {
        Pass {
        
            // 1.) This will be the base forward rendering pass in which ambient, vertex, and
            // main directional light will be applied. Additional lights will need additional passes
            // using the "ForwardAdd" lightmode.
            // see: http://docs.unity3d.com/Manual/SL-PassTags.html
            Tags { "LightMode" = "ForwardBase" "RenderType"="Opaque" "Queue"="Geometry+1" "ForceNoShadowCasting"="True"  }
                       
                        LOD 150
                        Blend Zero SrcColor
                        ZWrite On
       
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            // 2.) This matches the "forward base" of the LightMode tag to ensure the shader compiles
            // properly for the forward bass pass. As with the LightMode tag, for any additional lights
            // this would be changed from _fwdbase to _fwdadd.
            #pragma multi_compile_fwdbase
            // 3.) Reference the Unity library that includes all the lighting shadow macros
            #include "AutoLight.cginc"
                       
                        float _Fade;
                        float _FadeMarkerDist;
            struct v2f
            {
                float4 pos : SV_POSITION;
                                float3 worldPos : TEXCOORD2;
                float3 objWorldPos : TEXCOORD3;

                // 4.) The LIGHTING_COORDS macro (defined in AutoLight.cginc) defines the parameters needed to sample
                // the shadow map. The (0,1) specifies which unused TEXCOORD semantics to hold the sampled values -
                // As I'm not using any texcoords in this shader, I can use TEXCOORD0 and TEXCOORD1 for the shadow
                // sampling. If I was already using TEXCOORD for UV coordinates, say, I could specify
                // LIGHTING_COORDS(1,2) instead to use TEXCOORD1 and TEXCOORD2.
                LIGHTING_COORDS(0,1)
            };
            v2f vert(appdata_base v) {
                v2f o;
                o.pos = UnityObjectToClipPos (v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                                o.objWorldPos = mul(unity_ObjectToWorld,float4(0,0,0,1));

                // 5.) The TRANSFER_VERTEX_TO_FRAGMENT macro populates the chosen LIGHTING_COORDS in the v2f structure
                // with appropriate values to sample from the shadow/lighting map
                TRANSFER_VERTEX_TO_FRAGMENT(o);
                
                return o;
            }
            fixed4 frag(v2f i) : COLOR {
            
                // 6.) The LIGHT_ATTENUATION samples the shadowmap (using the coordinates calculated by TRANSFER_VERTEX_TO_FRAGMENT
                // and stored in the structure defined by LIGHTING_COORDS), and returns the value as a float.
                float attenuation = LIGHT_ATTENUATION(i);


                                float dist = distance(i.worldPos, i.objWorldPos);

                return  min(1,fixed4(1.0,1.0,1.0,1.0) * attenuation + (dist * (_Fade/_FadeMarkerDist)));
            }
            ENDCG
        }

                Pass {
        
            Tags { "LightMode" = "ForwardAdd" "RenderType"="Opaque" "Queue"="Geometry+1" "ForceNoShadowCasting"="True"  }
                        LOD 150
                        Blend Zero One
                        ZWrite On
       
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdadd
            #include "AutoLight.cginc"
                       
                        float _Fade;
                        float _FadeMarkerDist;
            struct v2f
            {
                float4 pos : SV_POSITION;
                                float3 worldPos : TEXCOORD2;
                float3 objWorldPos : TEXCOORD3;

                LIGHTING_COORDS(0,1)
            };
            v2f vert(appdata_base v) {
                v2f o;
                o.pos = UnityObjectToClipPos (v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                                o.objWorldPos = mul(unity_ObjectToWorld,float4(0,0,0,1));
                TRANSFER_VERTEX_TO_FRAGMENT(o);
                
                return o;
            }
            fixed4 frag(v2f i) : COLOR {
                float attenuation = LIGHT_ATTENUATION(i);
                                float dist = distance(i.worldPos, i.objWorldPos);
                return  min(1,fixed4(1.0,1.0,1.0,1.0) * attenuation + (dist * (_Fade/_FadeMarkerDist)));
            }
            ENDCG
        }
    }
    Fallback "VertexLit"
}

Thanks :slight_smile:

Somehow replacing the LightMode by ForwardAdd in the first pass did the trick

I have the same question too, but is trying to make it work with other lights, e.g. spotlight, point light.
Do you figure out how to add additional pass properly?

1 Like