Performance issue with lots of dynamic ModelInstance

Anything libgdx related goes here!

Performance issue with lots of dynamic ModelInstance

Postby Estelle » Mon Aug 19, 2019 11:05 pm

Hi,

I'm currently developping a 3D city-builder game with libGDX. So the player can build and destroy roads.

With around 1000 roads, 550 intersections and 1000 vehicles, the game uses 1400MB of memory.
But that is not the main problem. The rendering method for a massive amount of vehicles is the main problem.
I use a ModelCache to render the road network (roads + intersections) and that greatly reduces the CPU usage (but uses more memory).
But I tried to do that as well for the vehicles, and this causes a massive fps drop, because vehicles are moving each frame so I have to recreate the cache on every render call.

So I did the following to render the vehicles :

Code: Select all
batch.render(vehicles, environment);


Where vehicles is an array of ModelInstance.
But with 1000 vehicles, as you can see, one core of the CPU reach around 65% usage, and if I push the vehicles number to 2000, fps will start to drop dramatically because of max usage.
I guess this happens because of too much render call. But is there a way to merge a lot of dynamic modelInstance ?

The vehicle model has a very low level of detail (I made it with Blender) so I don't think that the cpu usage has anything to do with that.



Image

Specs : i7 5820K, 32GB ram, GTX 1080 Ti
Estelle
 
Posts: 8
Joined: Mon Aug 19, 2019 10:20 pm

Re: Performance issue with lots of dynamic ModelInstance

Postby Zappp » Mon Aug 19, 2019 11:26 pm

Rebuilding the cache every render call sound very intensive, I would use one cache for statics models, for the dynamics ones try to lower the level of detail even more at that distance of the camera they can be like 4 polys, then use differents caches, separate them in chunks and always apply frustum culling. As the camera goes closer you can increase level of details of the models because will be a lot less cars in the frustum.

Edit: try asking the libgdx discord 3d section, they maybe can give some betters tips, maybe even achieve some effects of cars at distance with shaders.
Zappp
 
Posts: 81
Joined: Sat Mar 29, 2014 3:34 am

Re: Performance issue with lots of dynamic ModelInstance

Postby tomski » Tue Aug 20, 2019 7:29 am

What amount of geometry are you pushing into the cache each frame? What are your gl stats? How many binds/draw calls are you pushing?
tomski
 
Posts: 909
Joined: Wed Jun 26, 2013 6:06 pm

Re: Performance issue with lots of dynamic ModelInstance

Postby Estelle » Tue Aug 20, 2019 4:57 pm

Zappp wrote:Rebuilding the cache every render call sound very intensive, I would use one cache for statics models, for the dynamics ones try to lower the level of detail even more at that distance of the camera they can be like 4 polys, then use differents caches, separate them in chunks and always apply frustum culling. As the camera goes closer you can increase level of details of the models because will be a lot less cars in the frustum.

Edit: try asking the libgdx discord 3d section, they maybe can give some betters tips, maybe even achieve some effects of cars at distance with shaders.


Right now I use cache only for roads and intersections, and those are static models. I update the cache only when the player creates or removes a road.
I also tried to use a specific cache only for vehicles and to update this one every render call, but then cpu usage is still very high.

I checked in Blender and the vehicle model has 524 polys. So I did the same test with a 12 poly model.
Now with 1000 vehicles to render, the cpu usage does not go above 25% on any core (it was 65% before).
I also tried with a 108 poly model, and the cpu usage is 55% at maximum.

Zappp wrote: then use differents caches, separate them in chunks


I have no idea of how to do that and also why it should improve performance ?

Zappp wrote: and always apply frustum culling


I just did that, but it will not improve the performance if the player wants to view the entire map.

Zappp wrote: As the camera goes closer you can increase level of details of the models because will be a lot less cars in the frustum

I would like to do that, so I guess I need to create different models on Blender. But I saw that the field Model is final in the class ModelInstance, so I need to create a new ModelInstance ?

tomski wrote:What amount of geometry are you pushing into the cache each frame?


I don't update the cache each frame. And the amount of geometry putted in it depends of the number of roads on the map. Roads are very basic because for now they are straigth so only 2 polys. Intersections are made with quadratic Bezier curve and they contain less than 100 polys (I generate meshes in the code).

tomski wrote:What are your gl stats? How many binds/draw calls are you pushing?


I hope this is what you asked. I used glProfiler :

https://i.imgur.com/OIvsaWN.jpg

In this screenshot, all vehicles have 108 polygons and frustrum culling is implemented.
Estelle
 
Posts: 8
Joined: Mon Aug 19, 2019 10:20 pm

Re: Performance issue with lots of dynamic ModelInstance

Postby Estelle » Tue Aug 20, 2019 5:14 pm

I just noticed that for each vehicle visible on the screen , I get 5 more draw call. Isn't that because my vehicle model is composed of 5 nodes (the 4 wheels + the rest) ?
Estelle
 
Posts: 8
Joined: Mon Aug 19, 2019 10:20 pm

Re: Performance issue with lots of dynamic ModelInstance

Postby tomski » Tue Aug 20, 2019 5:19 pm

Yup, that highlights some huge issues. You should be able to draw this whole thing in very few draw calls.
Example, one for ground, one for roads, one for cars. As they are all low poly, this shouldnt be an issue at all. So this is something to exepriement with for sure. Do you have the same material for the car?

Im guessing all your draw calls are coming from the cars?
tomski
 
Posts: 909
Joined: Wed Jun 26, 2013 6:06 pm

Re: Performance issue with lots of dynamic ModelInstance

Postby Estelle » Tue Aug 20, 2019 8:02 pm

tomski wrote:Yup, that highlights some huge issues. You should be able to draw this whole thing in very few draw calls.
Example, one for ground, one for roads, one for cars. As they are all low poly, this shouldnt be an issue at all. So this is something to exepriement with for sure.

Im guessing all your draw calls are coming from the cars?


If we do the math based on the screenshot :

There is 694 visible vehicles.
694*5 = 3470
And there is 3487 draw calls per frame.
So pretty much all draw calls are coming from cars. And I can verify that when I watch an area with no car.

Do you have the same material for the car?


I use a g3df file for the car model :

Code: Select all
"materials": [
      {
         "id": "Red",
         "ambient": [ 0.050876,  0.050876,  0.050876],
         "diffuse": [ 0.216100,  0.022090,  0.024807],
         "emissive": [ 0.216100,  0.022090,  0.024807],
         "opacity":  1.000000,
         "specular": [ 0.216100,  0.022090,  0.024807],
         "shininess":  0.000000
      },
      {
         "id": "Rubber.001",
         "ambient": [ 0.050876,  0.050876,  0.050876],
         "diffuse": [ 0.073236,  0.073236,  0.073236],
         "emissive": [ 0.073236,  0.073236,  0.073236],
         "opacity":  1.000000,
         "specular": [ 0.073236,  0.073236,  0.073236],
         "shininess":  0.000000
      }
   ],
   "nodes": [
      {
         "id": "Cube",
         "rotation": [-0.707107,  0.000000,  0.000000,  0.707107],
         "scale": [ 0.351536,  0.600000,  0.143824],
         "translation": [-0.000102,  0.221711,  0.000000],
         "parts": [
            {
               "meshpartid": "Cube_part1",
               "materialid": "Red",
               "uvMapping": [[]]
            }
         ]
      },
      {
         "id": "Cylinder",
         "rotation": [ 0.500000,  0.500000,  0.500000,  0.500000],
         "scale": [ 0.121903,  0.121903,  0.031135],
         "translation": [ 0.320718,  0.105375, -0.656053],
         "parts": [
            {
               "meshpartid": "Cylinder_part1",
               "materialid": "Rubber.001",
               "uvMapping": [[]]
            }
         ]
      },
      {
         "id": "Cylinder.001",
         "rotation": [ 0.500000,  0.500000,  0.500000,  0.500000],
         "scale": [ 0.121903,  0.121903,  0.031135],
         "translation": [ 0.320718,  0.105375,  0.373861],
         "parts": [
            {
               "meshpartid": "Cylinder.006_part1",
               "materialid": "Rubber.001",
               "uvMapping": [[]]
            }
         ]
      },
      {
         "id": "Cylinder.002",
         "rotation": [ 0.500000,  0.500000,  0.500000,  0.500000],
         "scale": [ 0.121903,  0.121903,  0.031135],
         "translation": [-0.320585,  0.105375, -0.656053],
         "parts": [
            {
               "meshpartid": "Cylinder.007_part1",
               "materialid": "Rubber.001",
               "uvMapping": [[]]
            }
         ]
      },
      {
         "id": "Cylinder.003",
         "rotation": [ 0.500000,  0.500000,  0.500000,  0.500000],
         "scale": [ 0.121903,  0.121903,  0.031135],
         "translation": [-0.320585,  0.105375,  0.373861],
         "parts": [
            {
               "meshpartid": "Cylinder.008_part1",
               "materialid": "Rubber.001",
               "uvMapping": [[]]
            }
         ]
      }
   ],
Estelle
 
Posts: 8
Joined: Mon Aug 19, 2019 10:20 pm

Re: Performance issue with lots of dynamic ModelInstance

Postby Zappp » Wed Aug 21, 2019 6:24 am

Estelle wrote:
Zappp wrote: then use differents caches, separate them in chunks


I have no idea of how to do that and also why it should improve performance ?


Not all your scene is at the same distance of the camera, so with chunks you can manage them individually with differents LOD, culling or building model cache, and other stuff. Is often used in voxel engines.
Zappp
 
Posts: 81
Joined: Sat Mar 29, 2014 3:34 am

Re: Performance issue with lots of dynamic ModelInstance

Postby Estelle » Wed Aug 21, 2019 2:24 pm

Zappp wrote:
Estelle wrote:
Zappp wrote: then use differents caches, separate them in chunks


I have no idea of how to do that and also why it should improve performance ?


Not all your scene is at the same distance of the camera, so with chunks you can manage them individually with differents LOD, culling or building model cache, and other stuff. Is often used in voxel engines.


Alright I see. I guess this is usefull because then frustum culling is more efficient. Also when the player wants to modify the terrain, then I will need to only update the modified chunk and not all the map.

I tried to run the simulation with this car : https://free3d.com/3d-model/low-poly-car-40967.html

And now I have 8 more draw call per car. In the g3dj file, I can read the following :

Code: Select all
"nodes": [
      {
         "id": "Car",
         "rotation": [-0.707107,  0.000000,  0.000000,  0.707107],
         "scale": [ 4.000000,  4.000000,  4.000000],
         "parts": [
            {
               "meshpartid": "Cube_part8",
               "materialid": "Body"
            },
            {
               "meshpartid": "Cube_part7",
               "materialid": "Black"
            },
            {
               "meshpartid": "Cube_part6",
               "materialid": "Window"
            },
            {
               "meshpartid": "Cube_part5",
               "materialid": "Bumpers"
            },
            {
               "meshpartid": "Cube_part4",
               "materialid": "Lights"
            },
            {
               "meshpartid": "Cube_part3",
               "materialid": "Bottom"
            },
            {
               "meshpartid": "Cube_part2",
               "materialid": "Tires"
            },
            {
               "meshpartid": "Cube_part1",
               "materialid": "Wheels"
            }
         ]
      }
   ],


So apparently there is 1 draw call for each node part (each part has its own material). Is this something normal ?

Image

Also it seems like ModelCache is not using vram but ram.
Estelle
 
Posts: 8
Joined: Mon Aug 19, 2019 10:20 pm

Re: Performance issue with lots of dynamic ModelInstance

Postby tomski » Wed Aug 21, 2019 7:06 pm

Your model cache is basically doing nothing in relation to the cars. Are you using skinning?
tomski
 
Posts: 909
Joined: Wed Jun 26, 2013 6:06 pm

Next

Return to Libgdx

Who is online

Users browsing this forum: MSN [Bot] and 1 guest