Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved Optimizing a huge scene with a lot of the same objects and limited amount of materials

Discussion in 'High Definition Render Pipeline' started by GamesbyJP, Aug 6, 2020.

  1. GamesbyJP


    May 20, 2018
    Hello fellow gamedevs!

    I'm stuck with the task of optimizing a big city scene in space, having a whopping 50ms cpu load.
    I've searched the internet for solutions, but to no avail.
    Here are some of the characteristics for the scene:

    1. The city consists of 4 districts.

    2. Each district only differs in scale, they share the exact same buildings otherwise.

    3. Each district has 1200 buildings, and I have 60 building variants as prefabs.

    4. Each building prefab consists of around 8 very basic meshes (< 100 verts each).
    • A quick multiplication of the info above results in 38400 meshes.
    1. There are 16 materials in total for all buildings, all sharing the same shader.

    2. All of those materials have 1 shared normal map and 1 shared texture map for emission.

    3. Normal map and texture are 2048x2048 each.
    1. The whole scene is lighted with a custom skybox and a main directional light.

    2. Every building "emits" light from the material

    3. Shadows are currently not rendering (I know, it's bad)
    1. Built in HDRP, using unity 2019.4f1 LTS
    What I've tried
    1. I figured static batching would help a lot, but there's only a mild difference if I set all objects in the scene to static.

    2. Dynamic batching, but then I'd have worse performance than before as I have to turn off static batching for it to work.

    3. Turning off PP. It helps a little, but since that's clearly not the main issue, I turned it back on.
    What I haven't tried and why
    LODs, because the models are pretty simple already. I don
    1. 't think it's worth it in this case, but correct me if I'm wrong

    2. Decreasing the camera distance. It's currently set to 5000, which renders the whole city. I'd like the whole city to be seen by the player, because it's 1 big structure in space, and it's very noticeable if a part of it is not visible.
    Here's a picture of the scene:

    Edit: And a picture of the profiler: profiler.PNG
    Last edited: Aug 6, 2020
  2. Lesnikus5


    May 20, 2016
    Almost 40000 meshes (or objects) are a lot. Check the profiler to see which methods are taking the most CPU time. What you have shown in the profiler screenshot does not contain information on the CPU. See "Hierarchy" in "CPU Usage".

    Although in general it is clear that the reason for the excessive number of objects. I can make an assumption that:

    - You have not enabled GPU Instancing in the material settings. The fact that you have almost 50000 draw calls bears witness to this and 0 baked draw calls.

    If that doesn't help, then:

    - You will have to use LOD with replacing models with flat sprites (imposters), as in the case of rendering a large forest.

    - Either you have to combine the building models into several larger models using your 3D modeling program or baking plugin asset.
    Last edited: Aug 8, 2020
  3. Lex4art


    Nov 17, 2012
  4. GamesbyJP


    May 20, 2018
    Hi, thanks for the reply.

    I spent a full day of trying to find out why static batching wasn't working.
    Even though the profiler showed 300 baked draw calls after a bit of fiddling around, I didn't notice any performance improvements from setting objects to static to not static.

    I ended up bypassing static batching as it was clearly broken for me somehow, and I combined all meshes which used the same material using a tool called Mesh Combine Wizard (Can really recommend it, it's awesome).

    Frametime went up from 50 - 70ms to 10ms.
    So this is solved.
  5. BattleAngelAlita


    Nov 20, 2016
    Try to use BatchRendererGroup, it provide "true" instancing. Instead of SRB batcher, that not doing instancing at all.