Search Unity

Efficient rendering of duplicate objects

Discussion in 'General Graphics' started by SoftwareGeezers, Jan 7, 2021.

  1. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    Just experimenting, this approach to a voxel-like terrain generates crazy numbers of draw calls:

    upload_2021-1-7_20-3-55.png

    It's one textured cube with randomised rotation and noise-based vertical offset.

    Is it possible to optimise this to get those drawcalls down to a handful?

    Edit: Found that myself with dynamic batching in Project Settings. Gets calls down to 15. Dunno why that's not on by default!
     
  2. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
  3. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    GPU instancing doesn't appear to do anything, other than break dynamic batching!

    I'm using the default Standard shader. Enabling GPU instancing results in no change in draw calls. If I enable dynamic batching, with GPU instancing enabled it has no benefit. Even tried disabling the texture - GPU instancing doesn't appear to do anything (2019.2.21).

    Not that it'd help anyway as I'm investigating mobile.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Dynamic batching has some CPU overhead. With a lot of objects and a low performance CPU (like on mobile), the cost of batching them can sometimes exceed the cost of just rendering them individually. Having 5000 cubes is an excellent use case for instancing, even on mobile.

    However the "best" performance would likely be to bake it down to a single mesh manually from script, assuming you don't need these to update every frame.
    https://docs.unity3d.com/ScriptReference/Mesh.CombineMeshes.html
    https://medium.com/acrossthegalaxy/...for-performance-and-organization-c3515c844fdb

    This is basically the same thing as what dynamic batching does, but Unity will do that every single frame, and has a limit to the number of objects that can be batched at one time (hence why you still have 15 batches). Doing combine mesh manually in chunks as you spawn stuff means it doesn't have to update every frame. Again, assuming you don't have to animate the relative positions of the individual blocks.
     
    Findeh and SoftwareGeezers like this.
  5. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    Cool! Basic implementation would be perhaps a tile-based scrolling, populating a new lines of tiles as the level scrolls. I imagine one could just combine the mesh to the old one. Oh, no, you'd have to lop off the old tiles from the bottom. If vertices aren't optimised, that should just be a case of deleting a set number of verts from the beginning of the mesh data?

    Imagining a game where the terrain can be manipulated, every update is going to need a new mesh construct. I guess here you'd subdivide, trading clusters of tiles for more overall draw calls per frame but lower update overhead when they need to change.