Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Transparent shader receive shadows

Discussion in 'Shaders' started by patrikspacek, May 14, 2015.

  1. patrikspacek

    patrikspacek

    Joined:
    Apr 10, 2014
    Posts:
    13
    Hi Guys,

    I am looking for Transparent shader which receives shadows! This is for Unity 5.

    I need to hide geometry, which has visible shadows from other objects.

    Thank you
     
  2. patrikspacek

    patrikspacek

    Joined:
    Apr 10, 2014
    Posts:
    13
    Oops, nobody can code shaders here? I guess wrong community o_O
     
  3. echo4papa

    echo4papa

    Joined:
    Mar 26, 2015
    Posts:
    158
    This should work:

    Code (CSharp):
    1. Shader "Custom/TransparentShadowCollector"
    2. {
    3.     Properties
    4.     {
    5.         _ShadowIntensity ("Shadow Intensity", Range (0, 1)) = 0.6
    6.     }
    7.  
    8.  
    9.     SubShader
    10.     {
    11.  
    12.         Tags {"Queue"="AlphaTest" }
    13.  
    14.         Pass
    15.         {
    16.             Tags {"LightMode" = "ForwardBase" }
    17.             Cull Back
    18.             Blend SrcAlpha OneMinusSrcAlpha
    19.             CGPROGRAM
    20.             #pragma vertex vert
    21.             #pragma fragment frag
    22.             #pragma multi_compile_fwdbase
    23.  
    24.             #include "UnityCG.cginc"
    25.             #include "AutoLight.cginc"
    26.             uniform float _ShadowIntensity;
    27.  
    28.             struct v2f
    29.             {
    30.                 float4 pos : SV_POSITION;
    31.                 LIGHTING_COORDS(0,1)
    32.             };
    33.             v2f vert(appdata_base v)
    34.             {
    35.                 v2f o;
    36.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    37.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    38.                
    39.                 return o;
    40.             }
    41.             fixed4 frag(v2f i) : COLOR
    42.             {
    43.                 float attenuation = LIGHT_ATTENUATION(i);
    44.                 return fixed4(0,0,0,(1-attenuation)*_ShadowIntensity);
    45.             }
    46.             ENDCG
    47.         }
    48.  
    49.     }
    50.     Fallback "VertexLit"
    51. }
     
  4. patrikspacek

    patrikspacek

    Joined:
    Apr 10, 2014
    Posts:
    13
    Thanks it works ... 90% .. I am just wondering, why the shadow is also on wrong side of the object. There is a light going from the left... and it shouldnt go through the whole 3d object. Also could you add main color into it?

    (the table has shadow off, because the painting has its own shadow.)

    image:
    https://dl.dropboxusercontent.com/u/39935592/Echo_shader.jpg
     
    Last edited: May 15, 2015
    sskenth likes this.
  5. echo4papa

    echo4papa

    Joined:
    Mar 26, 2015
    Posts:
    158
    Could that shadow be caused by that figure standing there?

    A transparent shadow receiving object can be difficult sometimes to allow for all cases.

    Here's two to try, first is the same but with a main color:

    Code (CSharp):
    1. Shader "Custom/TransparentShadowCollector"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Color", Color) = (1,1,1,.5)
    6.         _ShadowIntensity ("Shadow Intensity", Range (0, 1)) = 0.6
    7.     }
    8.     SubShader
    9.     {
    10.         Tags {"Queue"="AlphaTest" }
    11.         Pass
    12.         {
    13.             Tags {"LightMode" = "ForwardBase" }
    14.             Cull Back
    15.             Blend SrcAlpha OneMinusSrcAlpha
    16.             CGPROGRAM
    17.             #pragma vertex vert
    18.             #pragma fragment frag
    19.             #pragma multi_compile_fwdbase
    20.             #include "UnityCG.cginc"
    21.             #include "AutoLight.cginc"
    22.             uniform fixed4  _Color;
    23.             uniform float _ShadowIntensity;
    24.             struct v2f
    25.             {
    26.                 float4 pos : SV_POSITION;
    27.                 LIGHTING_COORDS(0,1)
    28.             };
    29.             v2f vert(appdata_base v)
    30.             {
    31.                 v2f o;
    32.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    33.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    34.              
    35.                 return o;
    36.             }
    37.             fixed4 frag(v2f i) : COLOR
    38.             {
    39.                 float attenuation = LIGHT_ATTENUATION(i);
    40.                 return fixed4(0,0,0,(1-attenuation)*_ShadowIntensity) * _Color;
    41.             }
    42.             ENDCG
    43.         }
    44.     }
    45.     Fallback "VertexLit"
    46. }
    This is the same but is at a different render queue which can sometimes get better transparency results, but you might have some depth sorting issues:


    Code (CSharp):
    1. Shader "Custom/TransparentShadowCollector"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Color", Color) = (1,1,1,.5)
    6.         _ShadowIntensity ("Shadow Intensity", Range (0, 1)) = 0.6
    7.     }
    8.  
    9.  
    10.     SubShader
    11.     {
    12.  
    13.         Tags {"Queue"="Geometry" }
    14.  
    15.         Pass
    16.         {
    17.             Tags {"LightMode" = "ForwardBase" }
    18.             Cull Back
    19.             Blend SrcAlpha OneMinusSrcAlpha
    20.             CGPROGRAM
    21.             #pragma vertex vert
    22.             #pragma fragment frag
    23.             #pragma multi_compile_fwdbase
    24.  
    25.             #include "UnityCG.cginc"
    26.             #include "AutoLight.cginc"
    27.             uniform fixed4  _Color;
    28.             uniform float _ShadowIntensity;
    29.  
    30.             struct v2f
    31.             {
    32.                 float4 pos : SV_POSITION;
    33.                 LIGHTING_COORDS(0,1)
    34.             };
    35.             v2f vert(appdata_base v)
    36.             {
    37.                 v2f o;
    38.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    39.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    40.              
    41.                 return o;
    42.             }
    43.             fixed4 frag(v2f i) : COLOR
    44.             {
    45.                 float attenuation = LIGHT_ATTENUATION(i);
    46.                 return fixed4(0,0,0,(1-attenuation)*_ShadowIntensity) * _Color;
    47.             }
    48.             ENDCG
    49.         }
    50.  
    51.     }
    52.     Fallback "VertexLit"
    53. }
     
  6. echo4papa

    echo4papa

    Joined:
    Mar 26, 2015
    Posts:
    158
    Eek, sorry, that should + _Color not * _Color.
     
  7. patrikspacek

    patrikspacek

    Joined:
    Apr 10, 2014
    Posts:
    13
    Thank you for the main color.

    They both does same thing... no difference here.

    Yes, the person needs to stay there to show how it works.
    The table (3D object) should block the cast shadow as well. So only visible shadow from the character should be on top of the table. Not underneath, not on the side.

    : Now we have matte shader receiving shadows, which is cool! Correct. But the shadows arent blocked by the 3d objects as well.
     
  8. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,115
    I don't understand why you don't use shadows only property of mesh renderer? Why do you need a shader?
     
  9. patrikspacek

    patrikspacek

    Joined:
    Apr 10, 2014
    Posts:
    13
    Because it cast shadows only, not receives shadows.
     
  10. patrikspacek

    patrikspacek

    Joined:
    Apr 10, 2014
    Posts:
    13
    by changing * to + all shadows and matte is gone. So I keep * (46th line)
     
  11. patrikspacek

    patrikspacek

    Joined:
    Apr 10, 2014
    Posts:
    13
    Is there a way to have that hidden geometry occlude Indy??
     
  12. Flens

    Flens

    Joined:
    Sep 18, 2013
    Posts:
    1
    For the record, it's working, you have just to set the alpha of the main color to 0.
    Wonderful shader, thank you so much Echo4papa !
     
    echo4papa likes this.
  13. echo4papa

    echo4papa

    Joined:
    Mar 26, 2015
    Posts:
    158
    No problem. :D
     
  14. ThatBulgarian

    ThatBulgarian

    Joined:
    Jul 2, 2013
    Posts:
    7
    @echo4papa This works with directional lights but not spot lights...do you know how I can make it work with spot lights?
     
  15. nekitamotip

    nekitamotip

    Joined:
    Mar 19, 2017
    Posts:
    2
  16. Klaus-Eiperle

    Klaus-Eiperle

    Joined:
    Mar 10, 2012
    Posts:
    33
    I think the second shader from post number 5 is working best. But is there a way to add a texture color to the shadow?
     
  17. paleajed

    paleajed

    Joined:
    Aug 22, 2017
    Posts:
    1
    Hi there, I tried the two last shaders to get a working shadow catcher when using Kudan for Unity, building for the Android platform. But alas, I see no shadow in the resulting app. I do have a shadow showing in the Unity viewport.

    Any ideas?
     
  18. ivank

    ivank

    Joined:
    Nov 16, 2013
    Posts:
    37
    @echo4papa
    @paleajed
    @Klaus-Eiperle
    Hello, do I understand correctly that the subject of the question (and answers) is something in 3D graphics called as matte shadow?

    I run into great matte shader from Unity guy Keigiro Takahashi, which also allows to adjust the color and transparency of the shadows: https://github.com/keijiro/ShadowDrawer

    It has however the drawback probably common for all similar shaders - it does not work against skyboxes - only against the solid color or another object (plane - floor, wall). Unfortunately it seems to be caused by Unity design itself :-(

    Does anybody know if Unity addressed this issue in the latest versions (2017.1 or 2)?
    Such feature is imho very useful for things like product visualization or AR and I really miss it...
     
  19. ezonecom

    ezonecom

    Joined:
    Jul 23, 2013
    Posts:
    17
    Yes, it would be very useful to have a shader like this that works with skyboxes. AFAIK 2017.2 does not address this.
     
  20. JelmerV

    JelmerV

    Joined:
    Nov 29, 2012
    Posts:
    170
    Hmm so a "solution" could be to make a big inside-out sphere around your scene with the skybox on it? :p not the best though..
     
  21. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    844
    2017.3 and the new HD Render pipeline does semi-transparent shadow receiving/casting by default. Right now you have to add the scriptable render loop assets to your project though from the git.
     
    n97968 likes this.
  22. iavetoshkin

    iavetoshkin

    Joined:
    Apr 4, 2018
    Posts:
    3

    The first code doesn't work... renders just black plane, nothing more. What can be wrong?
     

    Attached Files:

    Last edited: Apr 5, 2018
    develop-ahhoh likes this.
  23. Aaron-Meyers

    Aaron-Meyers

    Joined:
    Dec 8, 2009
    Posts:
    128
    Working on an AR project where we want to have the floors of our scenes be semi-transparent... some parts fully opaque fade to complete video background as well. At first I was struggling to get the floor to receive shadows, but in this thread, I saw the suggestion to use the Alpha-Test queue and after setting the render queue to 2500, the mesh receives shadows!

    However, there appears to be a big difference between DirectX 11 and Metal platforms: on Metal, the alpha of the fragment appears to effect the strength of the shadow... if the alpha is zero, you won't see ANY shadow at all... if alpha is .5, you see a half-way faded shadow, etc.

    On Windows (DirectX 11) the shadows show on all fragments, which is the effect I want so that the scenery can cast shadows on the cg floor as well as the real-world surface that the scene is placed on.

    I realize its a bit hack-y that putting the transparent shader on 2500 works to begin with, but I wonder if anyone can offer any suggestions that could make the shadows work regardless of the frag's alpha on Metal?