Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Wrong order of ForwardBase and ForwardAdd passes

Discussion in 'Shaders' started by l_skupkov, May 20, 2019.

  1. l_skupkov

    l_skupkov

    Joined:
    Jan 30, 2019
    Posts:
    3
    I'm trying to write a shader that will work like a regular Diffuse, but I can change the transparency from the code in runtime. To solve the problem of the z order I added a pre-pass, as I have been advised everywhere:

    Code (CSharp):
    1. Pass {
    2.     ColorMask 0
    3.     ZWrite On
    4. }
    But I got a problem, the solution of which I can not find: if the object is illuminated with a per-pixel light (Point or Spot light) pass in some cases ForwardAdd pass is called before ForwardBase. Because of this, pixel light is not visible on the object. I see the wrong order of calls in Frame Debugger.
    For some reason, this depends on the position of the camera: when I move the camera, the object is illuminated either correctly or incorrectly.

    Is it possible to solve this problem?
    My shader:

    Code (CSharp):
    1. Shader "Transparent_Diffuse"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Main Color", Color) = (1,1,1,1)
    6.         _MainTex("Base (RGB)", 2D) = "white" {}
    7.     }
    8.  
    9.     SubShader
    10.     {
    11.         Tags {"Queue" = "Transparent" "RenderType" = "Transparent"}
    12.  
    13.         Pass
    14.         {
    15.             ZWrite On
    16.             ColorMask 0
    17.         }
    18.  
    19.         CGPROGRAM
    20.         #pragma surface surf Lambert alpha:fade
    21.  
    22.         sampler2D _MainTex;
    23.  
    24.         fixed4 _Color;
    25.  
    26.         struct Input {
    27.             float2 uv_MainTex;
    28.  
    29.         };
    30.  
    31.         void surf(Input IN, inout SurfaceOutput o) {
    32.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    33.             o.Albedo = c.rgb;
    34.             o.Alpha = _Color.a;
    35.         }
    36.         ENDCG
    37.     }
    38.  
    39.     Fallback "Mobile/VertexLit"
    40. }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    6,977
    That ... should not happen. It's certainly not something I've ever seen occur or am able to reproduce, and I often rely heavily on shader pass execution order being consistent. It sounds like a bug on Unity's side, there's not anything you should be able to do to cause that. I would recommend you report it as a bug from the editor; Help > Report Bug...

    If you remove the extra pass, does it still happen? If not, as a work around you might be able to use two separate materials, one with just the depth write pass, and the other with the surface shader passes.
     
  3. l_skupkov

    l_skupkov

    Joined:
    Jan 30, 2019
    Posts:
    3
    The problem is in the extra path, if I remove it, everything works correctly.
     
  4. l_skupkov

    l_skupkov

    Joined:
    Jan 30, 2019
    Posts:
    3
    Update:
    1) The problem is absent for a single object, this only happens when there are many objects on the scene with this shader and at least 2 light points.
    2) This happens with the usual Legacy Diffuse shader, if you add a pre-pass to it
     
  5. paolo_m_ts

    paolo_m_ts

    Joined:
    Oct 22, 2018
    Posts:
    1
    We have the same problem (reproduced in Unity 2018.3.7f1). Adding a depth pre-pass to a surface shader seems to cause ForwardAdd to be sometimes drawn before ForwardBase, depending on the camera's transform.