Procedural Mesh for terrain - Tiled approach bad for performance

I am looking into ways to implement simplistic terrain surface which would allow for deformation in realtime. Procedural meshes seem to be the answer.

Recently I have put together the following setup:

1.png

This is a procedural mesh component defined by 4 (relative) points.

P1 = 0x, 0y, 0z
P2 = 0x, 200y, 0z
P3 = 200x, 0y, 0z
P4 = 200x, 200y, 0z

In my event graph, I create a mesh section, feeding in the 4 points as vertices. When I start it up, the mesh is generated as a 200x200 tile. Great!

I then used a nested loop to create a 10x10 grid of these meshes, essentially creating 100 tiles in a square to be used as a terrain surface. Now it takes a couple seconds for the game to start but it’s not really an issue. The problem is the continued low performance when moving around. Turns out having 100 procedural mesh actors on the screen at the same time takes its toll on the performance. My camera is top-down so I can limit the number of actors on screen by lowering the camera or increasing the size of the actors but this seems like a poor solution.

So I guess it would make sense to use a single 2000x2000 mesh rather than 100 200x200 meshes. But this introduces a problem - I don’t know how to do that. I would need to have vertices every 200 (or less) units, effectively ending up with a mesh like this:

2.png

I need all these vertices because I will be manipulating them in real time to deform the terrain. The value I pass to the Vertices would need to be an array vector containing all these points. I suppose I could run another nested do loop, adding vertices to an array until it encompasses the grid, but what about the triangles? Honestly, I don’t know how to tackle this.

Is this even how it is normally done? I feel like people have to have come across this issue and dealt with it so I’m looking for other solutions here.

Currently procmesh is rendered as a dynamic object. As of 4.13 you can merge procmesh to a regular static mesh. You just need to have created the component using the components dropdown in the BP as opposed to an “add proc mesh” node.

I have tested this and was able to make and merge a 512x512 grid. I did have to go into project settings and increase the max loop iterations by x10 to allow it to finish though. But then you select the proc mesh component in the details panel in the world and a ‘create static mesh’ button should appear in the details panel below a bit.

He needs deformation on runtime, and he would lose that feature if he would convert the mesh to a static mesh.

@Chumble Take a look at the Runtime Mesh Component (RMC), it has improved performance over the PMC:

Runtime Mesh Component - Marketplace - Epic Developer Community Forums!

Sounds great but unfortunately I’m having a tough time getting the plugin installed. I created a plugins folder and extracted the file from here so it currently is

C:\Users<user>\Documents\Unreal Projects<project>\Plugins\RuntimeMeshComponent_v1.2\

At this location, there exists a RuntimeMeshComponent.uplugin so I believe it is in the right path. When I try to launch my project though, I get

1.png

If I press no (because I don’t want to disable it), I get

1.png

1.png

The documentation indicates simply putting it in that location should be enough.

What engine version are you using? You could also try to just install it from the UE4 Marketplace, that should be easier.

4.13.1 - installing it from the marketplace seemed to work. Giving it a test now

Holy cow - Yeah the performance is MUCH better. I experienced absolutely no performance issues with the same setup I had with the procedural mesh.

So I guess there’s no real need to replace this grid of meshes with a single grid. Still, I wonder if it’s the smart thing to do… using a single mesh over a ton of small ones.

A little late, but…

There are tradeoffs to one larger, vs multiple smaller meshes especially with terrain. First up, one large mesh means that the whole thing draws if the bounding box overlaps the view frustum. Since terrain, especially procedural, can be large and high poly, this probably isn’t going to be a great idea. It also means that updating small areas require copying much larger pieces of data around. Multiple smaller meshes allow the culling to draw much less, but at the cost of higher draw call counts. There’s kind of a balance between the two and there’s no exact number as it depends on your project.

Glad to hear the RMC helped!

I’ve decided to go with the smaller meshes (specifically, 200x200) over the larger ones. So far, my biggest headache is finding a good way to keep them linked.

What I mean by this is when I modify the vertex on one mesh, the corresponding vertex needs to be modified on the 3 connected/surrounding meshes.

Untitled.png

Take this scenario with a 3x3 grid of meshes. There are four major vertex intersections, labeled as A B C and D. If I wanted to raise the vertex of mesh 1 at A (bottom right corner), I need to raise the bottom left corner of 2, the top right corner of 4 and the top left corner of 5.

My first method of dealing with this was by creating collision spheres at each corner.

Untitled.png

(in this picture I only drew them at the important intersections though they exist at all corners).

Now when I want to raise one corner, I can also look to see what other meshes exist and collide with the sphere. But this introduces a new problem. If I get all overlapping actors for that mesh, I get three meshes and no way to identify which one is which. I need to know which one is which because I need to know which corner to raise since it is different for each one. So then I added additional collision spheres.

Untitled.png

These spheres allowed me to identify that 4 was below 1, so I need to raise the top right corner. 2 is to the right of 1 so I need to raise the bottom left corner. Then, by using the corner overlap, I got all actors and made sure they were not 4 or 2. The remaining one has to be 5, so I raised the top left corner.

Overall, I hate this method. It’s incredibly messy in every way. The only advantage I see to this is it’s dynamic, allowing me to add additional meshes to either side and it will be able to adjust properly. But I can’t help but feel like there has to be a better way to handle this… it seems like such an easy problem that I’m having such a hard time with.

While typing this, I did just think of one other thing… using boxes instead of spheres for collision.

Untitled.png

I only drew the ones for mesh 1 but the idea is that each box collides with 1 and only 1 mesh. This eliminates the problem of having multiple colliding meshes for one collision.

But it’s still messy.

Anyone have any better more clever solutions for this?

Have a look at what we have been working on. May be what you are looking for.
https://forums.unrealengine.com/showthread.php?88558-Skunkwerks-Game-Tools-Dynamic-Terrain-Deformation-Plugin&p=638174#post638174

Dave

I had to deal with the exact same problem.
To know the position of the vertex inside the chunk(TopBorder, bottomBorder, TopLeftEdge, etc.) you can use a little math.

let’s say you have ChunkSize = 200.
Now you want to know the position of the vertex with the **LocalChunkCoordinates **(199, 0).

This gives you the result (x=1, y=0). Which is the top border.

**Text Example
**[spoiler]
**LocalChunkCoordinates **(0, 0)…result(0, 0)…EdgeBottomLeft.
**LocalChunkCoordinates **(199, 0)…result(1, 0)…EdgeTopLeft.
**LocalChunkCoordinates **(0, 199)…result(0, 1)…EdgeBottomRight.
**LocalChunkCoordinates **(199, 199)…result(1, 1)…EdgeTopRight.

**LocalChunkCoordinates **(0, 56)…result(0, 0.28)…BottomBorder.
**LocalChunkCoordinates **(199, 87)…result(0, 0.44)…TopBorder.
**LocalChunkCoordinates **(65, 0)…result(0.33, 0)…RightBorder.
**LocalChunkCoordinates **(98, 199)…result(0.49, 0)…LeftBorder.

**LocalChunkCoordinates **(98, 65)…result(0.49, 0.33)…NotOnBorder.[/spoiler]

BP mockup example:


you can either execute this each time you update a vertex, or store the position as an enum and use a switch (better for performance)