Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Alpha Blended ShadowCaster

Discussion in 'Shaders' started by IndreamsStudios, Apr 26, 2015.

  1. IndreamsStudios

    IndreamsStudios

    Joined:
    Jun 4, 2013
    Posts:
    9
    I'm trying to get certain objects to alpha blend, but also include a ShadowCaster pass. So far, I've only been able to get one or the other in the same SubShader.

    With the tags in the snippet below, the depth texture is written to, but when it is rendered, there's no alpha blending occuring. If I change the queue to "Geometry+501" (the first value considered "transparent"), then the depth texture is not written to, but the content renders with alpha blending.

    Is there a way to get ShadowCaster to work for objects in the transparent queue? I can workaround this by cloning the objects and doing the depth texture writes with a separate material, but I'd love to avoid doing that.

    Using Unity 5.0.0f4. Thanks for any help in advance.

    Code (CSharp):
    1. SubShader
    2. {
    3.     Tags
    4.     {
    5.         "RenderType" = "Transparent"
    6.         "IgnoreProjector" = "True"
    7.         "Queue" = "Geometry+500"
    8.     }
    9.  
    10.     Pass
    11.     {
    12.         Name "ShadowCaster"
    13.         Tags
    14.         {
    15.             "LightMode" = "ShadowCaster"
    16.         }
    17.         ZWrite On
    18.         Cull Off
    19.  
    20.         CGPROGRAM
    21.         // Vertex/fragment program, same as VertexLit's ShadowCaster pass, but with texture read and clipping based on low alpha
    22.         ENDCG
    23.     }
    24.  
    25.     Pass
    26.     {
    27.         Name "Draw"
    28.  
    29.         ZWrite On
    30.         Blend SrcAlpha OneMinusSrcAlpha
    31.         Cull Off
    32.  
    33.         CGPROGRAM
    34.         // Vertex/fragment program, same as Unlit/Transparent, but with clipping based on low alpha
    35.         ENDCG
    36.     }
    37. }
     
    Last edited: Apr 26, 2015
  2. Zicandar

    Zicandar

    Joined:
    Feb 10, 2014
    Posts:
    388
    Why not use a sub-shader? As the shader replacment used for rendering shadows checks the tags of subshaders. (Make sure the "normal" subshader is first, you probably want to do this anyways unless you want a pass before the normal transparent pass drawing to the z-buffer even when not doing shadows?) (Idk how good unity is at filtering out passes)

    Code (CSharp):
    1.  
    2. SubShader
    3. {
    4.     Tags
    5.     {
    6.         "RenderType" = "Transparent"
    7.         "IgnoreProjector" = "True"
    8.         "Queue" = "Geometry+500"
    9.     }
    10.     Pass
    11.     {
    12.         Name "Draw"
    13.         ZWrite On
    14.         Blend SrcAlpha OneMinusSrcAlpha
    15.         Cull Off
    16.         CGPROGRAM
    17.         // Vertex/fragment program, same as Unlit/Transparent, but with clipping based on low alpha
    18.         ENDCG
    19.     }
    20. }
    21. SubShader
    22. {
    23.     Tags
    24.     {
    25.         "RenderType" = "Opaque"
    26.         "IgnoreProjector" = "True"
    27.         "Queue" = "Geometry"
    28.     }
    29.     Pass
    30.     {
    31.         Name "ShadowCaster"
    32.         Tags
    33.         {
    34.             "LightMode" = "ShadowCaster"
    35.         }
    36.         ZWrite On
    37.         Cull Off
    38.         CGPROGRAM
    39.         // Vertex/fragment program, same as VertexLit's ShadowCaster pass, but with texture read and clipping based on low alpha
    40.         ENDCG
    41.     }
    42. }
    43.  
     
  3. IndreamsStudios

    IndreamsStudios

    Joined:
    Jun 4, 2013
    Posts:
    9
    Hi Zicandar, I tried your suggestion, but I couldn't get it to work (it'd only render or write to the depth texture, not both). From this doc (http://docs.unity3d.com/Manual/SL-CameraDepthTexture.html), it seems like shader replacement is used to render the depth texture (which I'm doing in a later step), but not to populate the depth texture in the first place.
     
  4. Zicandar

    Zicandar

    Joined:
    Feb 10, 2014
    Posts:
    388
    Then to the first subshader leave both passes, and still leave the second subshader. (Or replace the second subshader with a fallback to something like the basic diffuse) ?
     
  5. IndreamsStudios

    IndreamsStudios

    Joined:
    Jun 4, 2013
    Posts:
    9
    Putting both passes in the first subshader and leaving the 2nd subshader didn't seem to help, but looking closer at the frame debugger, it looks like this might be a Unity bug?

    As I have it now, my first subshader only includes the ShadowCaster pass, and has the following tags:
    Code (csharp):
    1. Tags
    2. {
    3.     "RenderType" = "Opaque"
    4.     "IgnoreProjector" = "True"
    5.     "Queue" = "Geometry"
    6. }
    And the second subshader only includes the normal rendering pass, and has the following tags:
    Code (csharp):
    1. Tags
    2. {
    3.     "RenderType" = "Transparent"
    4.     "IgnoreProjector" = "True"
    5.     "Queue" = "Transparent"
    6. }
    In the frame debugger, I see the expected objects being rendered in the UpdateDepthTexture pass. The same objects are then rendered under Render.OpaqueGeometry. If I remove the first subshader containing the ShadowCaster pass, the objects are correctly drawn during Render.TransparentGeometry. Is Unity ignoring tags for the second subshader?
     
  6. Zicandar

    Zicandar

    Joined:
    Feb 10, 2014
    Posts:
    388