Search code examples
unity-game-engineaugmented-realityshadowfragment-shadershaderlab

Unity transparent shadow receiving plane for AR app to receive only shadows and not light reflections


I'm working on a transparent shadow receiving shader for Augmented Reality app in Unity, that is put into a plane which will receive shadows from point light or spotlight. It works fine, but the plane receives light also as you can see in the image.

Output Screenshots

I'm using unity 5.6.3p4. Please tell me what could be the problem in this script or what should I change in this code to receive only shadows and not light reflections on the plane?

The Shader Script is below:

Shader "SP/InvisibleShadowCasterForPLight" { 
 Properties { 
     _MainTex("Base (RGB)", 2D) = "white" {} 
 } 

 SubShader {
     Pass {
         Blend One One
         Tags { "LightMode" = "ForwardAdd" } 
         CGPROGRAM 
         #pragma vertex vert 
         #pragma fragment frag 
         #include "UnityCG.cginc" 
         #pragma multi_compile_fwdadd_fullshadows 
         #include "AutoLight.cginc" 
         sampler2D _MainTex;
         float4 _MainTex_ST;

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

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

         fixed4 frag(v2f i) : COLOR
         { 
             float attenuation = LIGHT_ATTENUATION(i); 
             return tex2D (_MainTex, i.uv) * attenuation; 
         } 
         ENDCG 
     }
 }

 Fallback "VertexLit" 

}


Solution

  • Replace:

    LIGHTING_COORDS(0,1) 
    

    with:

    UNITY_SHADOW_COORDS(0)
    

    Then replace:

    TRANSFER_VERTEX_TO_FRAGMENT(0) 
    

    with:

    TRANSFER_SHADOW(o);
    

    Finally, in your fragment function, use this:

    half shadow = SHADOW_ATTENUATION(i);
    return tex2D (_MainTex, i.uv) * shadow; 
    

    That should do it! Oh, and you may or may not also want to change blendmode to multiplicative... If the above doesn't work, try changing:

    Blend One One
    

    with:

    Blend DstColor Zero