Search Unity

Why isn't GPU Instancing enabled by default on materials?

Discussion in 'General Graphics' started by dgoyette, Nov 5, 2018.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I figure there's something I'm missing about GPU Instancing on materials, but to me it seems like it should be enabled by default, on my assumption that it leads to better performance. What's the reason it's disabled by default?
     
  2. LennartJohansen

    LennartJohansen

    Joined:
    Dec 1, 2014
    Posts:
    2,394
    When enabled it disables dynamic batching and if it was enabled by default it would change behaviour of old projects.
     
    jegrad likes this.
  3. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Ah, that's very helpful. I've been enabling GPU instancing for materials I only put on moving objects, but it sounds like I'm doing it wrong. For moving objects, I should leave GPU Instancing disabled, and let Dynamic Batching do the work?
     
  4. LennartJohansen

    LennartJohansen

    Joined:
    Dec 1, 2014
    Posts:
    2,394
    Dynamic batching only works on small meshes, for larger stuff instancing is better.
     
    BrandyStarbrite and xVergilx like this.
  5. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I guess I'm still a little confused. I quickly tested out disabling GPU Instancing on some materials that are used only on moving objects. Here's the before stats, with GPU instancing enabled on the materials:

    upload_2018-11-5_10-54-27.png

    and here's the after, turning off GPU instancing:

    upload_2018-11-5_10-54-53.png

    It seems like the first version, with GPU instancing enabled on my dynamic objects, results in many fewer batches. So maybe I still don't understand GPU instancing.
     
  6. LennartJohansen

    LennartJohansen

    Joined:
    Dec 1, 2014
    Posts:
    2,394
  7. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Thanks.
     
  8. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Note that on platforms that do not support GPU instancing (e.g. <OpenGLES 3.0), dynamic batching will still work just fine if built with enabled GPU instancing.

    So, it's always nice to have it enabled. I haven't seen a case when it wasn't worth enabling it.

    Also, keep in mind that dynamic batching will break batches, if even one property of the material is different.
     
  9. friuns3

    friuns3

    Joined:
    Oct 30, 2009
    Posts:
    307
    Because in most cases
    it is slower when material GPU Instancing is enabled, even on your screenshot it give you less FPS as you see.

    Better not touch it or implement your own gpu instancing
     
  10. stevesan

    stevesan

    Joined:
    Aug 14, 2011
    Posts:
    65
    i've just observed HUGE slow down when enabling instancing, but instancing isn't actually possible. so there seems to be a good amount of overhead when Unity even TRIES to instance.
     
  11. Darkgaze

    Darkgaze

    Joined:
    Apr 3, 2017
    Posts:
    397
    GPU instancing should be used exclusively when objects are the same mesh (obviously), are dynamic and there are a lot of them in the same render. Otherwise, disable it!
     
  12. nico_st_29

    nico_st_29

    Joined:
    Mar 14, 2020
    Posts:
    69
    Hi Lidia, I'm going to test it in my project however I am not sure how much it can help: my project is an RTS where most unit models are used less than 50x times across the entire map and less than 15x times on the average screen.

    When I add units to the game the rendering work on the CPU shoots up - I've noticed that it is not the case when I switch to using Entities with the Hybrid Renderer v2 and as I understand this is mainly because the Hybrid Renderer v2 has an advanced GPU rendering module
     
  13. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,756
    Using unity terrain with standard Tree Creator. In built in render pipeline. I enable GPU instancing on the material of the trees... no instancing whatsoever going on. Literally drawing the barks and leafs one by one. I searched the forum and it's known issue and broken since 2017 at least. I mean, the main usage of GPU instancing would be on terrain trees. So... what gives?
     
  14. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Yeah, don't use it. If you're using built-in - SpeedTree is decent.
    As well as Mtree could be worth investigating (has same in Unity Editor features, and instancing / indirect instancing support).
     
    Last edited: Apr 3, 2021
  15. Arycama

    Arycama

    Joined:
    May 25, 2014
    Posts:
    185
    Yeah, this should really be a configurable option, per project, and enabled by default for new projects. (Eg "Project Settings/Editor/Enable GPU instancing on new Materials" or something)

    In the majority of recent projects I've worked on, (Mostly mobile, across a wide range of target devices), disabling GPU instancing in favour of dynamic batching is the exception, not the norm.

    GPU instancing can replace dynamic batching in pretty much any situation.

    Objects will only dynamic batch if they share the same material, and are under the 900 vertex attribute limit. It also does not allow for per-object data, and also is incompatible with several shader techniques.

    Using Instancing instead of Dynamic Batching means objects that share the same material, but not the same mesh will increase draw calls, but your SetPass calls should stay the same, and SetPass calls impact performance a lot more than draw calls. This frees the CPU from having to manually transform all of your dynamic-batched vertex attributes from object to world space every frame.

    Perhaps the only situation in which dynamic batch still wins, is with very small meshes. (I'd say less than 32 vertices)
    As the GPU dispatches workloads in 32-64 threads, and there is one thread per vertex. So if there's only 4 vertices, eg a single quad, you're wasting 28 or more threads.
     
    Last edited: Apr 3, 2021
    Novack likes this.
  16. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,756
    I´ve tried SpreedTree on mobile and the performance is horrible. x2 to x3 slower than the unity creator trees.
     
  17. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
    Hi Guys,
    I want to ask for a help. I am testing dynamic objects which use same materials which has GPU instancing enabled on 3 different phone. Interesting that on 2 of them performance decreases when I enable gpu instancing... On other phone(galaxy s7) performance increase.. So, what should I do now?
    Performance decreasing phones they both have PowerVR Rogue GE8320 gpus. Is it related gpu?
     
  18. Darkgaze

    Darkgaze

    Joined:
    Apr 3, 2017
    Posts:
    397
    Correct me if I'm wrong, but GPU Instancing only works for the same object with the same material. It's just meant to be used to copy the same item hundreds of times. And it has to be a dynamic object. That's the only point of GPU Instancing.
    Were you referring to GPU Instancing in that phrase?
     
  19. Arycama

    Arycama

    Joined:
    May 25, 2014
    Posts:
    185
    Yeah, my point is even though GPU instancing causes more draw calls than dynamic batching, the amount of setpass calls doesn't necessarily increase. It's possible to draw several different meshes with the same material, without additional setpass calls. Setpass calls are generally what slows down rendering, not draw calls.
     
    Novack likes this.
  20. Arycama

    Arycama

    Joined:
    May 25, 2014
    Posts:
    185
    GPU instancing doesn't affect the GPU in a noticeable way, it only affects the CPU. You may be CPU or GPU bound on any of those devices, and it could be any number of things, such as scripting, culling, setpass calls, vertex count, tri count, shader complexity, screen resolution/overdraw, etc.

    Some of those devices may be CPU bound, and enabling instancing improves CPU performance. The other ones may be GPU bound, so GPU instancing does not help. They may be bottlenecked by something else such as vert count, overdraw or shader complexity, however.

    You need to find where your bottlenecks are and optimise them.
     
  21. BrandyStarbrite

    BrandyStarbrite

    Joined:
    Aug 4, 2013
    Posts:
    2,076
    Interesting.
     
    Zamaroht likes this.
  22. hasnain7734

    hasnain7734

    Joined:
    Jan 17, 2022
    Posts:
    2
    I once had a scenario where I had like hundreds of objects together with same mesh and same material (texture was in atlas) and the material had GPU Instancing Enabled. I had very bad experience with that my game was literally stuck at a point on some devices that I had to restart the game or wait for few seconds to respond it. So I disabled GPU instancing and enable static batching which solve the issue for me/ so ig GPU Instancing Enabled is not ideal all the time. I have attached the picture of my scene where I was having issue.
     

    Attached Files:

  23. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    731
    How Unity combines "batches" for instancing is the slow part really. The raw graphics API drawing is pretty fast. You will get closer to the raw API performance by calling CommandBuffer.DrawMeshInstanced(Indirect even better) yourself.