Search Unity

Renderer queue for shadows pass not ordered correctly?

Discussion in 'Shaders' started by jadrefke, Jan 13, 2021.

  1. jadrefke

    jadrefke

    Joined:
    Jun 16, 2019
    Posts:
    2
    Hey guys,

    I made a shader that draws select items on top of other select items, even if it's geometry is further away from the camera by using a combination of render queue ordering and the stencil buffer. It seems to work as expected... except for shadows. It appears that the shadow pass of the shader does not respect render queue ordering, and does not populate shader properties correctly. I'm hoping someone more experienced with shaders may have a hint as to what causes this behavior.


    Here's my setup:

    I have 4 materials:
    MaterialName | RenderQueue | _StencilIndex
    Row0Top | 2001 | 2
    Row0Base | 2002 | 1
    Row1Top | 2003 | 2
    Row1Base | 2004 | 1

    And the stencil shader code I used is pretty straight forward

    Code (CSharp):
    1.  
    2. _StencilIndex("_StencilIndex", Int) = 0
    3.  
    4. HLSLINCLUDE
    5. int _StencilIndex;
    6. ENDHLSL
    7.  
    8.         SubShader
    9.         {
    10.             Tags
    11.             {
    12.                 "RenderPipeline"="UniversalPipeline"
    13.                 "RenderType"="Opaque"
    14.                 "UniversalMaterialType" = "Lit"
    15.                 "Queue"="AlphaTest"
    16.             }
    17.             Pass
    18.             {
    19. ...
    20.         Stencil{
    21.             Ref [_StencilIndex]
    22.             CompFront GEqual
    23.             PassFront Replace
    24.             FailFront Keep
    25.             ZFailFront Keep
    26.  
    27. ...
    28. }
    If an object with a higher priority render queue renders a "top" object, any "base" objects won't draw ontop of it on later queue's even if the base object's geometry is above the top object. This allows me to have an object drawn on top of select other objects, but still respect the depth buffer for the rest of the objects in the scene. This only works if the objects are rendered by the shader in the correct order (hence sperate render queues).

    eg: Row1Top will render ontop of Row1Base regardless of geometry, but will still respect the geometry for anything in Row0Top or Row0Base.

    While this works great if shadows are disabled:
    upload_2021-1-12_21-21-22.png

    It doesn't seem to work for the shadow passes of the shader (even though the same Stencil{} block is the same for both passes).
    upload_2021-1-12_21-21-16.png


    This causes the "top" items, which are actually below the "base" objects in world space to appear as if they have shadows on them even though they should be rendered on top. I noticed that the StencilRef value with either be always 1 or always 2 for every object in the Shadows pass, but never have a mix of both like in the opaques pass.


    When I noticed that the render order and _StencilRef shader property were different for this pass, I realized I might be a little in over my head. Any help or guidance to help me understand why the shader pass behaves differently from the opaques pass is greatly appreciated!


    FWIW i've also tried other RenderQueue ranges (eg 2500+, 3000+), and while they seem to influence the render order, it's still not the order i'd expect and still has the wrong _StencilRef property value.
     

    Attached Files:

  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Unity’s depth render passes ignore the material’s render queue. For the general case this makes sense, but it’s super duper frustrating when using stencils. Some render passes also forcefully override stencil values, either as a bug (like above) or intentionally (like the built in deferred renderer).

    The only solution I’ve come up with is not relying on the built in systems and manually inject objects into the depth render passes with manually sorted command buffers.
     
    jadrefke likes this.
  3. jadrefke

    jadrefke

    Joined:
    Jun 16, 2019
    Posts:
    2
    Thanks for the quick reply!

    That is a bit unfortunate. I'll try to work around it as you suggested, and hopefully it won't cause too much of a mess.