Search Unity

Why does batching not work?

Discussion in 'Editor & General Support' started by LoveToLoose, Mar 26, 2019.

  1. LoveToLoose

    LoveToLoose

    Joined:
    Mar 25, 2019
    Posts:
    8
    Hey, we're currently trying to improve the batch count of our game which shouldn't be too hard as almost every object is using the exact same material.

    However in the frame debugger I can see that almost all of our objects are not batched because "Dynamic batching is turned off in the player settings or is disabled temporarily in the current context to avoid z-fighting."

    Dynamic batching is definitely enabled and the objects don't even overlap so z-fighting shouldn't be an issue either. The meshes are generated at runtime and have a relatively low vertex count. As I've said they are all using the exact same material.

    I feel a little lost with this issue. Do you have any ideas what could be breaking the batches here? Thanks in advance for your input. :)
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,510
    Are they using sem-transparent shaders?
    This often catches people out:

    https://docs.unity3d.com/Manual/DrawCallBatching.html
     
    LoveToLoose likes this.
  3. LoveToLoose

    LoveToLoose

    Joined:
    Mar 25, 2019
    Posts:
    8
    I don't think that is the issue here. Maybe you can have a short look at the shader code and see if you can spot the issue? Thanks. :)

    Code (CSharp):
    1. Shader "Custom/StandardVertexColorWithCustomFog" {
    2.     Properties {
    3.         _FogExponent("Fog Exponent", Range(0,10)) = 3
    4.         _FogMinStrength("Minimum Fog Strength", Range(0,1)) = 0.1
    5.         _FogMaxStrength("Maximum Fog Strength", Range(0,1)) = 1
    6.         _BrightnessThreshold("Brightness Threshold", Range(0,5)) = 1
    7.         _BrightnessInfluence("Brightness Influence", Range(0.0, 1.0)) = 1.0
    8.  
    9.     }
    10.     SubShader {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.  
    14.         CGPROGRAM
    15.         #include "CustomFog.cginc"
    16.         // Physically based Standard lighting model, and enable shadows on all light types
    17.         #pragma surface surf Standard fullforwardshadows finalcolor:customFog nofog vertex:myvert
    18.  
    19.         // Use shader model 3.0 target, to get nicer looking lighting
    20.         #pragma target 3.0
    21.  
    22.         struct Input {
    23.             float fog;
    24.             fixed4 color;
    25.         };
    26.  
    27.         half _Glossiness;
    28.         half _Metallic;
    29.  
    30.         uniform half unity_FogStart;
    31.         uniform half unity_FogEnd;
    32.  
    33.         fixed _FogExponent;
    34.         fixed _FogMinStrength, _FogMaxStrength, _BrightnessThreshold;
    35.         fixed _BrightnessInfluence;
    36.  
    37.         // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    38.         // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    39.         // #pragma instancing_options assumeuniformscaling
    40.         UNITY_INSTANCING_BUFFER_START(Props)
    41.             // put more per-instance properties here
    42.         UNITY_INSTANCING_BUFFER_END(Props)
    43.  
    44.  
    45.         void myvert(inout appdata_full v, out Input o) {
    46.             o.fog = calculateFog(v.vertex, unity_FogStart, unity_FogEnd,
    47.                 _FogExponent, _FogMinStrength, _FogMaxStrength, _BrightnessThreshold, v.color, _BrightnessInfluence);
    48.             o.color = v.color;
    49.         }
    50.  
    51.         void surf (Input IN, inout SurfaceOutputStandard o) {
    52.             o.Albedo = IN.color;
    53.         }
    54.  
    55.         void customFog(Input IN, SurfaceOutputStandard o, inout fixed4 color) {
    56.  
    57.             color = lerp(color, unity_FogColor, IN.fog);
    58.         }
    59.  
    60.  
    61.         ENDCG
    62.     }
    63.     FallBack "Diffuse"
    64. }
    65.  
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,510
    Hey. We are just looking at improving those batching messages, they are not particularly helpful sometimes.

    Are you using Instancing? Batching is done per material and mesh for instancing, so if they all have the same material but a different mesh then it won't help.
    But for drawing many of the same mesh, instancing should be better than dynamic batching anyway
     
    Last edited: Mar 27, 2019
    LoveToLoose likes this.
  5. LoveToLoose

    LoveToLoose

    Joined:
    Mar 25, 2019
    Posts:
    8
    No, GPU instancing is disabled in the material. They are using different meshes, but that shouldn't be an issue with GPU instancing disabled, right?
     
  6. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,510
    Are you able to share an example project that shows the issue you are having?
     
  7. LoveToLoose

    LoveToLoose

    Joined:
    Mar 25, 2019
    Posts:
    8
    I think I found out why batching is not working. We have 2 light sources in the scene and our meshes are probably too big. Yes, they have under 300 verts, but the shader uses vertex color which as far as I understood reduces the amount of verts your meshes are allowed to have for dynamic batching, right?
     
  8. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,638
    Unless you're targeting something without instancing support, why would you use dynamic batching? Have you tested instancing?
     
    karl_jones likes this.
  9. LoveToLoose

    LoveToLoose

    Joined:
    Mar 25, 2019
    Posts:
    8
    Instancing only works when the mesh is exactly the same, though, right? Does it work when the meshes are transformed and does it work with meshes that are generated at runtime? If yes, it might be an option for some objects.
     
  10. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,638
    If using SRP then the SRP batcher will make this a non-issue.

    If "abusing" the dynamic batching to fuse different meshes together, I'm not even sure this is a performance increase. I recommend you try instancing anyway. Even the primitive case of ticking instancing on in the material may yield significant gains.

    The thing with all this is it's a different answer per project and per pipeline. But I don't have any use for dynamic batching in my game which is open world / time of day. The technique has long since outlived it's usefulness for me.

    I don't know your use-case though and suspect Unity just keeps dynamic batching around because it might break projects if suddenly removed and people have shaders that account for the fact that lots of meshes are submitted as one fused mesh.

    How many unique meshes are there? if say, you have 10 unique meshes, that's still only 10 draw calls for instancing. It's nothing.

    Make actions that save several hundred draw calls, not actions that will save less than a hundred, even on mobile.
     
    LoveToLoose likes this.