Wednesday, November 2, 2016

Procedural terrain in engine

I managed to get some crude procedural terrain generation functioning in the engine test program. The elevation is produced by five octaves of fractional Brownian motion (fBm) with a Perlin noise basis function.  The blend map, which controls which textures appear where, was based upon Perlin noise.  Tree placement was random.
Procedural landscape
Bottom of a hill

It is not without its flaws.  Still, its not too horrible for maybe 90 minutes effort.  The distribution of the noise is a bit of problem.  There's virtually no flat land!  This is a known issue with many fractal algorithms.  I can try out Musgrave's heterogeneous fBm and terrain algorithms or the recent approaches Ian Parberry published in the Journal of Computer Graphics Techniques.

Besides the homogeneity of the terrain (mostly rounded hills and valleys) there are a few other problems.  The blend map generating algorithm is not quite right; only three of the four textures are appearing.  Another problem is with world size and frame rate.  Currently the world is a square measuring 3200 feet on a side, with 10000 trees scattered about.  25000 looks better, but bogs it down.  Some sort of paging may be required, or perhaps instanced drawing.  The last issue is seams at the edges of the sections of terrain.

It "seams" there is a problem.

Seams are a known issue with many terrain partitioning or paging schemes.  It literally presents an edge case at section boundaries.  There are several known solutions: special logic along edges, transitional geometry (shims), etc. that I'll have to dredge back up and look at.

Dynamically generating the terrain on the CPU at startup takes less than ten seconds for about a third of a square mile.  I suspect that can be sped up by moving the terrain generation to GPU, or by generating the sections on an ongoing basis.  In other words, generate only one section at first (where the camera is), then the eight sections around it.  From then on, as the camera moves, only render the camera's section and those in the neighborhood.  Additional sections can be generated asynchronously when it is suspected they're needed, or upon demand, discarding any that are far enough away.  But I also need to do that with the related foliage.  A fascinating challenge for another day.

Good night for now.

No comments:

Post a Comment