Search Unity

Question Optimize Runtime-generated mesh that shouldn't be this slow ?

Discussion in 'General Graphics' started by Wonsder, Jun 29, 2021.

  1. Wonsder

    Wonsder

    Joined:
    Jan 24, 2020
    Posts:
    37
    Hello,
    First of all I don't really know if this is the right place to ask, please redirect me if needed.

    So, I'm doing procedural generated dungeons, and I generate the mesh at runtime. generation works fine (takes 1-2 secs for the hole thing) But my game is really laggy, and I can't explain why.

    My entire dungeon is splitted up into 8 gameobjects, one for each material. Then each GameObject have one mesh, That represent all the dungeons triangles on that material.

    Most of my meshes are indeed exceeding the 65k vertex limit, so I put my meshes in the 32-bit mode. But my hole dungeon doesn't exceed a million or so vertex.

    However, Looking in the profiler, I get to something like 10-15 fps, most of the use being in rendering, And I can go up to 30-40 fps when I delete Most of the dungeons meshes objects (so, 7 out of 8 of them)

    I've seen people run smoothly into much more complicated scenes than I have, with lots more materials and vertex, So I don't really understand why it is so laggy.

    Maybe some more details :
    My machine is middle range, but should be able to run my game at 100-200 fps without a problem. My project also have multiplayer with the MLAPI lib, and when it's lagging on rendering multiplayer is really chunky. When i set the dungeon to be smaller (10-100 times less vertex) it run smoothly (60 fps), and multiplayer is also fine.

    I don't know what else I can tell for more detail, I can provide screenshots of the profilre or answer any questions. Thanks for taking time to read !
     
  2. BrandyStarbrite

    BrandyStarbrite

    Joined:
    Aug 4, 2013
    Posts:
    2,076
    I have never used procedural generated stuff before, but I think if your procedural generated mesh is complex, it'll use up more cpu and gpu resources. That might be part of what is causing the slowdown.

    What is made up of 65k? The characters or the dungeon areas?

    Alot of times, it's because they use normal maps, together with enviroments and objects made up of low or semi high polygon counts, to fake the look of a high poly complicated detailed scene.

    Interesting.
     
    Last edited: Jul 3, 2021
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    There’s also questions like how many real time lights you have, or if you’re using real time shadows, and if combining meshes into a “single mesh” is helping or hurting.

    There’s a common myth that “less draw calls the better”, and while it’s true you can sometimes get significant performance improvements by reducing the number of draws, it’s almost never a good idea to combine all meshes manually. If you have several thousand set pass calls on desktop or console, maybe look at optimizing. If you have several hundred on mobile, maybe look at optimizing. Otherwise you’re probably doing more harm than good.

    This is because then culling doesn’t work if you merge too much together.

    If you can’t see an entire mesh at once, all of it still being rendered, or more specifically all of the vertices of that mesh are still calculated. If you have a real time point light, the entire mesh gets re-rendered even if the light only touches a small part of it. If your point light has real time shadows, it renders the entire mesh 6 more times as the shadow map for a point light is a cubemap with 6 “views” that have to render individually. Same with spot lights, or even directional lights which usually use shadow cascades that only need to draw part of the scene at one time.

    If the entire dungeon is “one mesh”, or in your case a small handful of large meshes meshes, each of those cases above are going to have to draw the entire dungeon no matter how small a part of it the camera or light can “see”. Leaving the parts separate, only those meshes that are visible will be drawn which can drastically reduce the number of vertices the GPU has to redundantly process, even if it’s “more draw calls”. I suspect if you just stop combining the meshes the frame rate will drastically improve.

    If you want to optimize the draw calls still, what you want to do is not combine everything into one big mesh, but instead combine groups of meshes that are close together. If your mesh pivots are nicely centered on the mesh and the dungeon layouts are roughly on a grid, you may want to use that grid to do the combining. Only combine meshes within a box of the grid at a time.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    You might also be thinking “but what about Static Batching …”. Yes, Unity’s Static Batching combines many meshes into a single mesh per material. But a Static Batching has a trick… it still renders each object individually. In the Game view Stats and in the Frame Debugger it’ll show as a single set pass call event, because it is, it sets the mesh and material once and then issues a draw call with a range of vertices for each individual game object that’s part of the static batch. But the draw calls aren’t actually the thing that are expensive, it’s the changing of the mesh, shader, render state, and material properties that’s the expensive part. This means it can cull game objects that can’t be seen, or that are have been toggled off, etc. Unfortunately there’s no way to do this with meshes generated at runtime.
     
  5. Wonsder

    Wonsder

    Joined:
    Jan 24, 2020
    Posts:
    37
    I think this is the biggest improvment i could do, and it's why it is so slow. I'll try to combine them, I can't let all the cells uncombined (as this let to something like 25k cells, so 25k gameobjects and THAT is laggy)