Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Vert/frag shader ignores render queue in SubShader?

Discussion in 'Shaders' started by pea, Dec 22, 2015.

  1. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
    Hmm. Stumped! This shader here seems to just render in "Geometry". I can adjust the queue, check the Frame Debugger and everything still renders in the same order as before.

    I've even tried "Queue" = "Background" and that doesn't change anything. This used to work when I was using Surface shaders.

    Anyone see something obvious I'm doing wrong? Unity 5.2.3f1. Thanks!

    Code (CSharp):
    1. Shader "Vcol + rim"
    2. {
    3.     Properties
    4.     {
    5.         _rim_color("_rim_color", Color) = (1,1,1,1)
    6.     }
    7.  
    8.     SubShader
    9.     {
    10.         Tags
    11.         {
    12.             "Queue"="Geometry-10"
    13.             "IgnoreProjector"="True"
    14.             "RenderType"="Opaque"
    15.         }
    16.  
    17.         Cull Back
    18.         ZWrite On
    19.         ZTest LEqual
    20.         Fog{}
    21.  
    22.         CGPROGRAM
    23.         #pragma surface surf BlinnPhongEditor exclude_path:prepass vertex:vert interpolateview nolightmap noshadow novertexlights noforwardadd nometa noambient
    24.         #pragma target 2.0
    25.  
    26.         #include "vcolor_rim.cginc"
    27.  
    28.         ENDCG
    29.     }
    30.     //FallBack "VertexLit"
    31. }
     
  2. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
    Setting the renderQueue on the material does work, for some reason.

    Code (CSharp):
    1. this.myMaterial.renderQueue = 1900; // Before Geometry, which is 2000
     
  3. Trigve

    Trigve

    Joined:
    Mar 17, 2013
    Posts:
    136
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,248
    That's probably a different issue than the one you're experiencing (see my comment in the bug filed in the issue tracker). The fact you're changing the renderQueue in script and it's still not working means it's something different. I have seen a lot of people complaining about the "background" queue simply not working anymore with anything <2000 seems to get sorted with queue 2000 geometry anyway when using deferred but it working properly in forward.

    However your situation is different. Your shader is writing to the z buffer (ZWrite On) which means subsequent queues are going to correctly test against said z depth and reject pixels that are "behind" it. There's nothing special about the queue order being <2000 concerning z depth testing. You can try turning off zwrite on your shader, but it might cause funky sorting issues on your geometry depending on what it is.

    A trick you can use is to use a second camera to render the "background" with a lower camera depth than your main camera. Set your main camera to clear depth only and the background will be the view of this alternate camera. You'll want to mess with layer masks too so only stuff you want in the background gets rendered by this camera and doesn't get rendered by the main camera and it's not free.
     
  5. Trigve

    Trigve

    Joined:
    Mar 17, 2013
    Posts:
    136
    Maybe I'm missing somethng, but I cannot find the part when he is writing that it doesn't work.

    I think it is same issue. Also I think that ZWrite is irrelevant here, because we just want the right order. And you can find the order easily with frame debugger.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,248
    Post #2 is a bit of C# for setting the render queue on a material. That should be the same thing as setting the custom render queue in the debug inspector.

    Also zwrite is never irrelevant. If you use z write and z test with opaque geometry it doesn't matter what order objects renders in, the end results will always be the same ... that's the purpose of the z buffer.
     
  7. Trigve

    Trigve

    Joined:
    Mar 17, 2013
    Posts:
    136
    But I don't see the part, where he write that changing the shader doesn't solve the issue (I don't think that he even tried it).

    Yes, but the problematic part is the render order, which is broken (that it will draw correctly because of Z testing is another thing).

    Anyway, if it isn't the same bug as we've encountered, it is still bug :)
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,248
    Blargle, read #2 wrong. *facepalm*

    Misread that as "doesn't"!
     
    swansonator likes this.
  9. pea

    pea

    Joined:
    Oct 29, 2013
    Posts:
    98
    Yes, thanks for the in-depth post @bgolus

    Seems like a workaround for the bug is setting the renderQueue value on the material. For now. Dirty!
     
  10. Flailer

    Flailer

    Joined:
    Apr 1, 2014
    Posts:
    66
    Are you using Unity 5? + Because if so I've noticed a nasty little thing where the material has a renderqueue other than -1 set to it at times seemingly in the background, which makes any shader queue stuff null and void. Switch to debug mode on the inspector - set the material queue to -1 and voila, should work and take from what you set in the shader again.
     
    Spacejunkk likes this.
  11. Spacejunkk

    Spacejunkk

    Joined:
    Sep 8, 2012
    Posts:
    7
    Thanks Flailer, solved my issue. I haven't been able to work out why the custom render queue is getting set, but that would be why the workaround, um, works.
     
  12. jistyles

    jistyles

    Joined:
    Nov 6, 2013
    Posts:
    34
    Apologies for echoing this in the various threads on this topic, I just wanted to note I've found where this common bug is originating from. Here's a copy of my post from another thread:

    So I've done a triage pass and found where this bug is coming from.

    It's caused by the Standard Shader material interface which you can find the source in the built-in shader package under \Editor\StandardShaderGUI.cs

    The Standard Shader supports a variety of "render modes". These change things like blend op's, zwrite, set keywords, etc... but it also explicitly sets the Material.renderQueue
    If you ever have a material reference the Standard Shader, then it will stomp the -1 default with whatever is relevant for its "Render Mode", but it won't clean itself up if you then change the shader to something else.
     
  13. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,248
    Yes and no. You're right in that this is likely where the issue comes from but not in the way you think. The actual behavior is if you change the shader of a material it'll set the renderQueue to match that shader's queue at that time regardless of if it is the standard material or not. Switch between an unlit and an additive particle shader and it'll switch between 2000 and 3000.

    My theory is that someone flagged it as a bug that the renderQueue was staying set after changing the material from the standard shader to another shader and whomever fixed that bug did so by naively setting the renderQueue to the new shader's render queue instead of the default -1 perhaps unaware of that magic number.
     
  14. Trigve

    Trigve

    Joined:
    Mar 17, 2013
    Posts:
    136
    It's shame that this bug haven't been touched upon. Have someone tested if it is still the case in the latest beta?