Search Unity

DepthPass.Job and GPU Instancing

Discussion in 'Shaders' started by Brad-Newman, Jun 2, 2022.

  1. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    185
    I have GPU Instancing enabled in my material and in the Frame Debugger when observing the DepthPass.Jobs I see different results for different Unity shaders:

    1. With the Unity > Mobile > Diffuse shader I see an event for each mesh, and no DrawInstanced calls.

    2. However, when I switch to the Unity Standard shader I see those events combined as DrawInstanced calls.

    I'm wondering what is unique about the Standard shader? My goal is to hopefully do the same thing in my custom shader to enable DrawInstanced calls in the Depth Pass.
     
  2. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    731
  3. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    185
    Sorry, I wasn't clear. I'm creating a surface shader. My understanding was that GPU instancing works with surface shaders by default, no? I get an instanced draw call in my surface shader, I just don't get the DepthPass.Job DrawInstanced.
     
  4. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    731
    It's still not default no. You still have to add the appropriate code for it to work correctly.
     
  5. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    185
    hmmm. When I test this shader with GPU instancing checked DepthPass.Job goes away completely, and the Drawing is GPU Instanced without further modification:

    Code (CSharp):
    1. Shader "Custom/NewSurfaceShader"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    7.     }
    8.  
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.  
    14.         CGPROGRAM
    15.         #pragma surface surf Lambert noforwardadd
    16.         #pragma target 3.0
    17.  
    18.         sampler2D _MainTex;
    19.  
    20.         struct Input
    21.         {
    22.             float2 uv_MainTex;
    23.         };
    24.  
    25.         fixed4 _Color;
    26.  
    27.         void surf (Input IN, inout SurfaceOutput o)
    28.         {
    29.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    30.             o.Albedo = c.rgb;
    31.             o.Alpha = c.a;
    32.         }
    33.         ENDCG
    34.     }
    35. }
    If I add a Fallback shader DepthPass.Job returns with a bunch of calls, but the drawing remains GPU Instanced.


    Code (CSharp):
    1. Shader "Custom/NewSurfaceShader"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    7.     }
    8.  
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.  
    14.         CGPROGRAM
    15.         #pragma surface surf Lambert noforwardadd
    16.         #pragma target 3.0
    17.  
    18.         sampler2D _MainTex;
    19.  
    20.         struct Input
    21.         {
    22.             float2 uv_MainTex;
    23.         };
    24.  
    25.         fixed4 _Color;
    26.  
    27.         void surf (Input IN, inout SurfaceOutput o)
    28.         {
    29.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    30.             o.Albedo = c.rgb;
    31.             o.Alpha = c.a;
    32.         }
    33.         ENDCG
    34.     }
    35.  
    36.     Fallback "Mobile/Diffuse"
    37. }
    Should I worry about perf with all these DepthPass.Job calls?
     
  6. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    185
    Based on stress test profiling, it seems the answer is yes. With 5620 low poly trees I see the following median Player Loops:

    Without Fallback Shader: 6.62 ms
    With Fallback Shader: 10.56 ms

    Why would a Fallback Shader that's not being used affect perf?
     
  7. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    185
    Think I figured it out. So based on these docs: https://docs.unity3d.com/Manual/SL-SurfaceShaders.html , if you don't have a shadow directive like addshadow i.e. #pragma surface surf Lambert noforwardadd addshadow then the Fallback shader's shadow directive is used. "Mobile/Diffuse" doesn't have a directive, so it goes to it's Fallback shader "Mobile/VertexLit" which is a fragment shader with shadow handling that is different than whatever addshadow compiles into.

    When I use #pragma surface surf Lambert noforwardadd addshadow I no longer see all the DepthPass.Job calls.
     
    tmonestudio likes this.