Limitations of Runtime Heightmap Terrain

In previous posts I have discussed the techniques for runtime generation of landscape form from fixed meshes using heighmap textures to generate Y coordinate offsets, this technique is very fast in execution and very frugal in GPU bandwidth. It does have some limitations;

  • The heightmap size itself is limited to a single texture, meaning that its not infinitely extensible.
  • Ultimately the heightmap pixels map to a world voxel coordinate, and can only be interpolated to smaller world coordinates by using terrain-type specific noise (i.e. bumpy ground height noise etc).
  • Continual sampling of the heightmap at different resolutions using floating point can lead to sampling errors, especially near to the edge of the heightmap texture (DirectX no longer supports the margin property of the sampler so we have to include a gutter on the heightmap, further degrading its usable size).
  • Specific landform types cannot be usefully described – river channels, moraines, geological rock outcrops, and more generally any overhang, tunnel or cave.
  • The deformation of the heightmap by features such as rivers, roads, building platforms etc proved to be insurmountable – the heightmap resolution required in the near field of view was excessive, and the progressive halving of the resolution out in the medium and long field of view rendered these landscape features visibly incorrect (rivers got wider and less distinct, roads became impossible to depict).

These limitations can sometimes be overcome.

Heightmap Maximum Size

I generated a set of tessellating heightmaps to create an infinitely extensible heightfield. This approach caused the following issues;

  • In order to reduce to an acceptable limit the number of heightfield textures being submitted to the shader a progression of re-sampled heightmaps, each being the aggregation of four tessellating heightmaps were needed and a selection algorithm used to send the appropriately detailed map to the shader was introduced.
  • Each call to the shader required a minimum of four heightmaps as it was unlikely that the geometry mesh being drawn would match any given heightmap footprint.
  • Sampling errors at the junction between tessellations of different resolutions of heightmap and geometry became quite a problem.

Heightmap Minimum Resolution

As the viewer came closer to the landscape surface the resolution of the heightmap no longer gave a progressively more detailed landscape. Only the introduction of landscape specific noise using perlin textures or other procedural height generation solved this problem.

Next Steps

In order to overcome this problem my next steps will be to “go back to the beginning” and examine the techniques needed to render a large scale landscape without runtime height generation, using tiled meshes unique to each landscape section. This will require a lot more meshes, but its strength is that each landscape tile is a self contained mesh, and meshes are generally cheap. With a mesh you can describe any shape with a known level of resolution (which can vary over the mesh) and accurately describe linear features within the design pipeline rather than at runtime.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s