Instanced Static Mesh Performance

My game uses an Instanced Static Mesh to create the Floor and Background shown here:

Each Hexagon is a Static Mesh with 36 Vertices and 20 triangles. There are 2 materials applied to the mesh. For the record changing the materials make no difference neither does changing the mesh for a lower polygon one.

On average each level uses a 72x72 grid of these (5184 instances). None of them have collision or cast shadows. They are not being changed in real time.

This single component accounts for ~10ms out of every frame on my PC (GTX 560Ti, 16GB of Ram, Intel 3.5Ghz i7 2700k) and causes my graphics card to sound like a vacuum cleaner.

Is there any way I could get the performance of this any faster? It’s a big problem for those people playing on Laptops (even gaming laptops) but for what I have planned for the game the dynamic background is actually incredibly important.

Would it be any faster to use say 4 of these components with less instances on each one?

EDIT: I’ve tried doing the same job with regular static mesh components and the Instanced Version is about 7ms faster.

Performance is almost certainly going to be affected by the number of instances rather than the complexity of each instance… you really need to get that number down by merging meshes - or by changing the way that the background is built up entirely.

Can I ask how each of the meshes changes during play…? Do the materials or material parameters change per instance? Do they move? (if so, do they move in just one or in all axes?)

The reason I ask is that, if the answers to the above go a certain way, you could probably have the entire background made using a single mesh instead of over 5000 - using some clever shaders, material and texture methods.

The material parameters change during play to respond to gameplay (There is a specular effect on the floor which needs to know the players world position for example). The only movement they do is being handled via WorldOffset in their material though as they bounce on the Z axis. The only time I change the data on the component is when the Arena is generated.

Currently the maximum size of an arena is being limited by the number of instances as well, I’d prefer to be able to generate larger arenas but right now they have to fit into the space available.

I was considering the possibility of generating a procedural mesh component for the background in a similar way to the walls but wasn’t sure if that would be much faster, it would probably increase the generation time which is currently instant.

It seems to be somehow related to overdraw. This is the arena with no postprocessing and most of the scaling options set to 0.

The Mesh being instanced is in this picture 2000 units tall and being offset vertically to create the arena.

Here I’ve replaced the mesh with a 6 vertex perfectly flat version. Same material (although I messed up the UV mapping). Massive drop in Draw time.

Now on a hung that it wasn’t actually the number of verts causing the problem I tried reducing the size of the original mesh to 100 units. This is the result.

Very similar frame times to the perfectly flat mesh with 6 times as many vertices. I should be able to work with this so that only those meshes whose sides will not be visible get scaled so they are very thin. Hopefully that will solve my problem.

Mesh resized and now getting scaled so there are no gaps. I also deleted some triangles on the bottom of the mesh which would never be seen. Back to being GPU limited rather than Draw Limited. Just the way it should be.

You’ll get a performance boost if you use LoD’s.