Search Unity

Big amount of meshes render optimization?

Discussion in 'General Graphics' started by oLDo, Feb 21, 2018.

  1. oLDo

    oLDo

    Joined:
    Mar 14, 2017
    Posts:
    55
    Hi.

    I'm writing a library to read CAD data at runtime. Library is working fine, but I have issue with performance when I load big assembly. I can't post specific model, but the model contains 45 280 faces. Every face is converted (triangulated) to mesh. Of course in runtime. That means the result is more then 45k meshes in scene. It's not very big meshes how you can see by amount of vertices in stats screenshot. Also you can see it by profiler rendering screenshot.

    All meshes at this point have same material (standard shader, I tried different shaders but doesn't matter, because the bottleneck is cpu). Thanks to this I think the dynamic batching is working.

    I have turned off shadows, multisampling, vsync, antialiasing and msaa. In the scene is loaded only CAD data, camera and directional light. I had read everything about optimizations in unity documentations.

    stats.PNG

    Here is a screenshot from profiler. There is a big amount of CPU on BatchRenderer.Flush. I didn't find a solution to solve this bottleneck.
    profiler.PNG profiler rendering.PNG

    Also I tried UnityEditor.MeshUtility.Optimize on every mesh after creation and I get 5fps more. But this feature is available only in editor. o_O

    Intel i7-6950x
    4x GPU GTX-1080Ti in SLI
    64GB ram
    Unity 2017.2.0f3 (64bit)
    DirectX 11

    Please, I'll be thankfull for some help.
     
  2. McDev02

    McDev02

    Joined:
    Nov 22, 2010
    Posts:
    664
    Well it seems that you read CAD data and create each patch as a seperate object. That is of course very bad for performance. Did you write the tool by yourself or is it third party? However you have to merge faces in meshes to reduce the amount of draw calls.
    Lets differantiate between Spline Surfaces / Patches (e.g. defined by 4 splines) which you triangulate into faces (triangles).

    Of course the CPU is overloaded by the task to batch all of these objects each frame. This has to be done just once.

    You could try to merge connected surfaces together in one object or write your own batch algorithm that merges as many faces as possible in one mesh depending on which material those have. The latter one would not be ideal for exporting objects but if it is for view only then it is fine.
     
    Last edited: Feb 21, 2018
    theANMATOR2b and mgear like this.
  3. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,983
    Lots of meshes, big meshes, or lots of big meshes?

    If there are many of the same mesh, use a shader with GPU instancing instead of dynamic batching.

    Also use Graphics.DrawMeshInstancedIndirect instead of having them as gameObjects in the scene
     
  4. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    I'm guessing the mesh resolution/data has to be exact - otherwise why use cad.
    With that mentioned - you might consider a in-between software. Most 3D softwares can bring in CAD data (3D Max probably best). The cad data is converted to solid mesh data on import, except for certain spline/line components.
    Then the mesh data can be "crunched" several different ways (scripted or manual input reverse tessellation methods) to make the mesh more manageable. From their bringing into game engine is simple.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    This is the problem. Dynamic batching really wasn't intended to batch 45k meshes. Dynamic batching re-batches every frame, so every frame it's throwing away the last frame's batched meshes and re-merging 45k meshes.

    Try manually merge them into one mesh on import.
    https://docs.unity3d.com/ScriptReference/Mesh.CombineMeshes.html
     
  6. oLDo

    oLDo

    Joined:
    Mar 14, 2017
    Posts:
    55
    Thank you all for support.

    McDev02 you are right about each patch as separated object. It's a way how my colleges are working. Many small patches and faces. This is how they creating big surfaces, primary in Catia and Icem Surf. Each geometry is unique, there is no duplicates.
    bgolus thanks for important explaining how dynamic batching is working.
    The library I'm writing by myself.

    I used CombineMeshes on grouped faces by data file structure and I get 200fps. :)

    If somebody is interested, I also tried to not create gameObjects, just hold mesh array and use Graphics DrawMesh. The result was same, poor performance. After that I tried to create a CommandBuffer with this drawMesh, but the result was same.