Mesh rendering performance optimisation

Anything libgdx related goes here!

Mesh rendering performance optimisation

Postby adunato » Thu Feb 14, 2019 11:29 am

I'm working on a libgdx implementation of mesh terrain and running into some performance issues.

The terrain is represented by a number of mesh tiles, each mesh is made of vertices laid onto a 2D plane.

The implementation of the meshes is done via libgdx Mesh, each of which is cached after its initial generation. I use GL3.0 and therefore the vertices are handled via `VertexBufferObjectWithVAO` which as I understand it should allow GPU caching. Meshes are indexed.

Aiming to optimise performance, I have tried to increase the number of vertices in each mesh (while keeping the same overall amount of vertices) but weirdly the performance gets worse rather than improving.

Question 1: any possible reasons why given the same total number of vertices the scenario with lower amount of meshes (#3 below) is slower than the scenarios with higher number of meshes?

Question 2: based on the OPENGL pipeline summarised below is it correct to assume that VBOs are being transferred to the GPU once and then drawn via GPU memory reference?

Performance comparison

1. 1,600 meshes * 3,042 vert (4.8M vertices) -> 131 FPS

2. 625 meshes * 11,250 vert (4.5M vertices) -> 132 FPS

3. 100 meshes * 45,000 vert (4.5M vertices) -> 113 FPS

Hardware Details

GTX660 2GB
Memory Utilisation during test 70% in all scenarios. Vertex allocation memory impact seems to be negligible compared to textures.

OPENGL pipeline

From API TRACE, this is the frame life-cycle in summary

mesh generation (one off)

glGenBuffers()
glGenVertexArrays()

render (every frame)

glClear(GL_COLOR_BUFFER_BIT)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glUseProgram(...)
glUniformMatrix4fv(...)
glUniform1f(...)
glActiveTexture(...)
glBindTexture(...)
...
glBindVertexArray(...)
glBindBuffer(...)
glDrawElements(...)
[for each mesh]



*edited to clarify that I have tried to group the vertices into less amount of meshes to reduce number of draw calls

**edited to provide more data and streamline questions.
Last edited by adunato on Fri Feb 15, 2019 12:24 pm, edited 1 time in total.
adunato
 
Posts: 14
Joined: Sat Nov 07, 2015 6:14 pm

Re: Mesh rendering performance optimisation

Postby slebed » Fri Feb 15, 2019 2:26 am

That seems like a lot of verts to process to me. What are you getting in terms of frames per second? What platform are you running this on. Graphic card?
slebed
 
Posts: 222
Joined: Fri Dec 28, 2012 3:29 am

Re: Mesh rendering performance optimisation

Postby adunato » Fri Feb 15, 2019 12:26 pm

Edited to provide more details and clearer questions.

To clarify, this is a stress test to optimise performance, the conclusion may be that given this set up this is as fast as it's going to get however I'm still unclear as to why the scenario with less meshes and same amount of vertices is slower.

If I don't spot obvious performance bottlenecks my next steps will be to investigate VBO instancing, which is not straightforward given that I'm passing per-vertex custom attributes.
adunato
 
Posts: 14
Joined: Sat Nov 07, 2015 6:14 pm

Re: Mesh rendering performance optimisation

Postby shatterblast » Fri Feb 15, 2019 5:37 pm

You might consider sharing some of your test code. I am not sure if you are using ModelInstance objects, but according to the post in the link below, LibGDX can be sensitive to them:

http://www.java-gaming.org/topics/libgdx-3d-optimize/36209/msg/343122/view.html#msg343122

https://libgdx.badlogicgames.com/ci/nightlies/docs/api/com/badlogic/gdx/graphics/g3d/ModelInstance.html


Unfortunately, I am not experienced with 3D in OpenGL yet, but apparently, Renderable exists as another option instead of ModelInstance. However, each Renderable seems to own a draw call, and since minimizing draw calls boosts efficiency, I assume lots of those would cause some slow down.

https://libgdx.badlogicgames.com/ci/nightlies/docs/api/com/badlogic/gdx/graphics/g3d/Renderable.html


Apart from that, you can also cull both "frustum" and "occlusion" when in a readily developed game.
shatterblast
 
Posts: 180
Joined: Sun Jul 06, 2014 1:14 pm

Re: Mesh rendering performance optimisation

Postby adunato » Sat Feb 16, 2019 9:04 am

The code for this is pretty simple, I instance a Mesh (https://libgdx.badlogicgames.com/ci/nightlies/docs/api/com/badlogic/gdx/graphics/Mesh.html) for each map sector when passing the culling test and then I render them using Mesh.render(). Basically the OpenGL functions you see in my post are the result of these calls.

I have considered using ModelInstance and other complex objects but they are too bloated for what I need to do. Having spent some time testing my code I'm starting to think that there is nothing wrong with it, just a lot of vertices due to the fact that these meshes are the result of hexagonal cells split into triangles. Still would like to know why increasing the amount of vertices in each mesh while decreasing the number of meshes worsens performance.

Next I'm planning to use mesh instancing as all map sectors have the same structure, it will need some customisation to pass a vertex array to the vertex shader to provide information about type of material so that the appropriate texture can be applied by the fragment shader.
adunato
 
Posts: 14
Joined: Sat Nov 07, 2015 6:14 pm


Return to Libgdx

Who is online

Users browsing this forum: Bing [Bot], shatterblast and 1 guest