Download

[WIP] Procedural Terrain generation (smooth heightmap based)

Not sure if this is the correct forum but, I am currently working on a method to dynamically generate a heightmap based terrain in C++ (as opposed to voxel based).

Many thanks to the contributors in this thread, particularly dmacesic and FireOnHigh (for his UV mapping modification)

Also thanks to the FPS tutorail here on which the code is still based (eventually I hope to be able to have 3 types of camera

I am using 4 tris per tile, which smoothly connect to adjacent tiles.

The basic algorithm works, however I can really only generate a map of about 512x512 (100 cm tile size) before the performance really drags down. I believe this mostly due to the collision calculation. I think I need to break up the at the mesh or possibly Actor level to get the collision performance . Perhaps even I need to roll my own collision calculation code.

Here is a screenshot.

Amazing!!! Are you spawning a stadard procedural mesh, or a landscape?

Its just a static mesh based off the GeneratedMeshComponent class (which is itself mostly taken from CustomMeshComponent). That part is really nothing fancy, although it did take some work to figure out how the triangles should connect together in smooth way and figuring out UV mapping (thanks to dmas.

The algorithm for generating the heightmap is one I just I rolled myself - it starts with a flat map, then generates number of hills and vallleys by picking a random tile then doing random walk bumping up the terrain by a given constant amount until the desired number of tiles are visited (keeping track of which tiles have already been visited). Next the entire map is smoothed out with a 2D convolution (basically averaging around each tile, the kernel is really basic as its weights all surrouding tiles equally). It repeats this number of times to “spread” the hills and valleys out on the map. This sort of simulates an “eroson” effect … Lastly I just add some random noise and smooth it out again with a smaller kernel and less iterations to given it bit of a “bumpy” appearance. Most parameters are user settable through Blueprint now.

Unfortunately UE4 landscapes can’t be generated or changed at runtime, at least last I checked. A big reason is I think is because they take advantage of some type of prebaked lighting and some advanced shader techniques which can make them look really cool. Especially as you start to add different materials to the landscape, compiling all the shaders can take a while. I think last time i tired 4 different materials in a UE4 landscape, the shader compilation took something like 30 minutes …

What needs to be done:

  • Optmize the collision logic somehow to allow larger maps (either by breaking up the meshes/actors, or rolling own routine)
  • Set materials on a per tile basis, also if possibly do a smooth transition somehow (not really sure how that part works, I think the UE4 landscape uses some custom shader routines which weights the materials somehow, which is why the shader compilaiton takes so long…)
  • Be able to change the height dynamically in an efficient manner (i.e, not regenerating the whole mesh…)

Actually, about the collision, I think you can go for two ways:

  1. Just make a optimized collision mesh.
  2. Use the algorithm you use for generating the mesh, to figure out, i nthe pawn, the height of it at the position where the pawn is, and this way tell him where he would collide. It may be better than a full collision mesh.

Ok, breaking up the landscape into “super tiles” at the Actor level seems to help a ton … now I can do 1024x1024 world and its pretty seemless (though height map generator is taking a while now, thats a seperate issue) … still have a bug where its not doing the seams between the super tiles correctly, but should be easy to fix

This in deed is amazing. Any progress-update or were you just finished with that? Actually this is quite similar to what I am currently working on. (I am loading hights from a mysql-database and updating a Procedural Mesh Component to the position of my character.)

So here some questions that might help me with my project:
How did you turn a GenerateMeshComponent into a static mesh? Do you think Procedural Mesh Component could do the same? From Blueprint?
How did you make the mesh so smooth? Is it just so far tesselated or is normal-calculation involved?

Sorry to live-up such an old threat. I just had to ask,
regards! =)

Not my thread, but I did something similar recently too, code’s on github so feel free to poke around