Search Unity

DrawMeshInstanced freezes on WebGL platform

Discussion in 'General Graphics' started by gregume, Oct 4, 2018.

  1. gregume

    gregume

    Joined:
    Mar 3, 2018
    Posts:
    6
    I am using DrawMeshInstanced to render many objects without the overhead of using individual GameObjects. This works great, except on one platform - WebGL.
    The first time DrawMeshInstanced is called, there is a severe hitch and it freezes for several seconds.
    I assume there is some CPU work being done internally when it goes to render instanced meshes, perhaps sorting and culling. I don't know why this would be an issue for the WebGL platform and no other platform.

    This issue is preventing me from using GPU instancing. Does anyone have any insight into this or how to prevent it?

    I have attached a simple project with a scene that demonstrates the problem. Thanks for any help!
     

    Attached Files:

    SunnyChow, mowax74 and cloutiertyler like this.
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Same as your other post - report a bug using the bug reporter :)
     
  3. jRocket

    jRocket

    Joined:
    Jul 12, 2012
    Posts:
    700
    Are you using WebAssembly? In my experience, those hitches will happen with the non-WebAssembly JIT compiler when it first encounters code. Chrome is especially bad with that.
     
  4. gregume

    gregume

    Joined:
    Mar 3, 2018
    Posts:
    6
    Thanks for the suggestion. I just tried it out, and unfortunately the issue happens both with WebAssembly and asm.js.
    Also with Chrome and Firefox. It's a 6 second hang in every case.

    What I'm trying to achieve is efficiently rendering thousands of identical objects in separate locations in my WebGL app. I have tried many options, and I can't get any to work very well.
     
    mowax74 likes this.
  5. JeanSimonet

    JeanSimonet

    Joined:
    Nov 23, 2012
    Posts:
    31
    Did you ever sort this out? I think I'm having the same problem... instancing works fine in emulation in editor but not in the actual webGL build.
     
    mowax74 and cloutiertyler like this.
  6. gregume

    gregume

    Joined:
    Mar 3, 2018
    Posts:
    6
    Let me see if I can remember ... I never got it to work perfect, but I found a workaround that I'm okay with. I reported a bug for this, so it may get fixed eventually.

    What seems to be happening is that on WebGL, DrawMeshInstanced has a really high overhead the first time it's called with, say, 1000 instances. Every subsequent call is fine. The overhead is proportional to the number of instances. 500 takes half the time.

    My workaround was to split it into 20 smaller batches of 50. This was the sweet spot for me between a hitch at the beginning, and too many draw calls. All other options I tried to efficiently batch objects had performance issues, including dynamic batching. Good luck!
     
    ThomasAstrom likes this.
  7. JeanSimonet

    JeanSimonet

    Joined:
    Nov 23, 2012
    Posts:
    31
  8. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    Where is the bug report for this? Has this been fixed in Unity 2019?
     
  9. Crozzroads

    Crozzroads

    Joined:
    Sep 8, 2014
    Posts:
    3
    No. I had the same issues in 2019.2. One "fix' is to just turn off GPU instancing on each material, which defeats the entire point of GPU instancing of course. But at least your application won't hang for 6 seconds every few frames!
     
  10. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    I notice that my game freezes when new areas of GPU-instanced objects are discovered, but after that, the performance is good. I use 48 instances per batch. It would be really good if the game didn't freeze, though. Maybe it is related to upwarming of the shaders?
     
    mowax74 likes this.
  11. Crozzroads

    Crozzroads

    Joined:
    Sep 8, 2014
    Posts:
    3
    I've literally tried for everything with GPU-instancing on web without the freezes; it just doesn't work. Even after "discovering" the objects like you say, it isn't reliable and will still freeze intermittently, even on the already "discovered" objects.

    If anyone has any findings or solutions, please share them here so people googling might find it.
     
    Twyker likes this.
  12. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    I have still not tried these:
    https://docs.unity3d.com/ScriptReference/Shader.WarmupAllShaders.html
    https://docs.unity3d.com/ScriptReference/ShaderVariantCollection.WarmUp.html
     
  13. Crozzroads

    Crozzroads

    Joined:
    Sep 8, 2014
    Posts:
    3
    I have not tried these either, but I have tried including the shaders used by the objects I wanted instanced in Unity's "always included shaders" section, under the Graphics settings. Was under the impression these would also then never be unloaded, but in hindsight I'm probably wrong about that.

    Edit*
    Do let me know if this works for you?
     
    Twyker likes this.
  14. fciornei

    fciornei

    Joined:
    Mar 6, 2016
    Posts:
    3
    Using Shader.WarmupVariantCollection or adding the variant collection to preload shaders helps indeed to solve the problem, the game will load very slowly. Did this happen in your cases?
     
    Nyanpas likes this.
  15. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    Which version of uwunity are you on?
     
  16. cloutiertyler

    cloutiertyler

    Joined:
    May 12, 2018
    Posts:
    5
    mowax74, Twyker, GuitarBro and 2 others like this.
  17. netkill

    netkill

    Joined:
    Feb 12, 2020
    Posts:
    3
    Same issues on Web GL !
     
    mowax74, Twyker and Nyanpas like this.
  18. Twyker

    Twyker

    Joined:
    Nov 10, 2016
    Posts:
    12
    +1 for this issue
     
    mowax74 and Nyanpas like this.
  19. mowax74

    mowax74

    Joined:
    Mar 3, 2015
    Posts:
    97
    Same issue here. I have a room with same furniture in there. The furnitures shaders are gpu instanced. When i move/rotate the camera and new furniture comes into sight, there are really large unacceptable lags for nearly seconds, depending an the number of objects (lets say 50-100). When every object is "established", the scene runs smooth.
    This only happens on WebGL, not on standalone, and also the profiler in the editor did not even show some spikes in the same situation.

    Edit: Unity 2020.1.17f1 here
     
    Nyanpas likes this.
  20. SunnyChow

    SunnyChow

    Joined:
    Jun 6, 2013
    Posts:
    360
  21. Stormer2020

    Stormer2020

    Joined:
    Sep 14, 2020
    Posts:
    92
  22. kkrupovich

    kkrupovich

    Joined:
    Jun 21, 2022
    Posts:
    1
  23. MSQTobi

    MSQTobi

    Joined:
    Feb 12, 2018
    Posts:
    8
  24. mowax74

    mowax74

    Joined:
    Mar 3, 2015
    Posts:
    97
    Unity, why you don't call WebGL plattform support deprecated? Since such elementary functionality like shader warmup never gets fixed over the years, practically, it's not possible to create a professional WebGL project with Unity.

    It's not acceptable that the browser freezes for seconds just to warm up a handful of shader(variant)s.

    Communicating this clearly would prevent new developers put a lot of time in creating their webgl projects with unity just to realize later that there are that massive issues with no chance of any kind of a workaround.
     
  25. Zarod

    Zarod

    Joined:
    Jan 20, 2016
    Posts:
    60
    "gpu instancing being called elementary"

    every single poor developer that has to write it from scratch and can't make a phone call to his collegues or steal a repo to ctrl+c ctrl+v :
    :(:(:(:(:(