Rail3dWiki — Terrain


Terrain modelling is a hugely important part of a railway simulation of this sort - it is also a fairly complicated issue. Because there is so much terrain in any but the most trivial layouts, the rendering speed and quality are critical to the overall simulation.


In divising a terrain modelling system, our requirements include:

  • Efficient, fast rendering
  • Ability to cope with large variations (mountains) and small detail (eg earthworks)
  • Ability to model different surface types
  • Simple, intuitive editing interface

These are probably in the above priority order.


The most obvious way to implement a terrain surface is to define a grid and store the surface height at each point in the grid. However this approach has some disadvantages - primarily the problem of grid resolution. If the grid resolution is small then any significant area will require a huge number of points to be stored. Conversely, if a smaller number of points are stored then the resolution is reduced and it becomes harder to represent small terrain and earthwork detail well.

Rail3D tackles this problem by storing terrain as an arbitrary array of points. This allows points to be placed at a closer resolution where the detail is required, and at lower resolution where less detail in the surface is required, however in return it introduces more complex problems with the surface generation and rendering.

Rail3D terrain works by “triangulating” the arbitrary array of points to produce a mesh of triangles. This is a complex mathematical process and is implemented using a third-party triangulation algorithm: there is a bug in this algorithm that sometimes produces the rifts and holes in the terrain mesh, but the maths is too complex for me to understand it and find the bug.

Embankments and Cuttings

One of Rail3D’s strengths (in my opinion) is the quality of the cuttings and embankments.

The terrain generation process produces these as follows:

  1. Generate a triangle mesh from the array of terrain points: this defines the general surface of the terrain, ignoring the tracks in the layout. This may be referred to as the primary mesh.
  2. Examine all the resultant triangles in the primary mesh and compare with the track links to see where tracks cross terrain triangles. For each track link that is above or below the suface of the primary mesh, add additional terrain points (auto-cutting points) to form the required embankment or cutting.
  3. Triangulate the resulting set of points to produce the final detail mesh.


Rendering the terrain is problematic - it happens often (10 or more times a second) and involves a lot of 3d surface traingles to be calculated and drawn on the display. To do this as efficiently and speedily as possible, we need to consider:

  • Points that are not in view should not be rendered as this can slow down the system considerably. For example points that are behind the camera can be dropped from the rendering fairly easily.
  • Points that are in view, but hidden by other objects need not be rendered. This is more complex, for example if there is terrain behind a nearer mountain the mountain may hide it from view - however this is a complex calculation and has not been attempted.
  • Changing textures, eg for different surfaces, will slow the generation as the terrain textures need to be swapped in memory.