Loading terrain

Gorilla3D provides a simple terrain component for generation from height-map image. Besides the default usage, different procedural builders are available: diamond square, mandelbrot, perlin-noise (linear, cosine and cubic), plateau algorithms. The resolution / number of vertices is configurable.

For detailed information about the component and its methods, check out: Gorilla.Terrain

Creating a terrain at runtime from heightmap

Form1.pas
uses
  Gorilla.Terrain,
  Gorilla.Material.Lambert;
 
procedure TForm1.FormCreate(Sender: TObject);
var LTexturePath : String;
begin
  LTexturePath := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
 
  FTerrain := TGorillaTerrain.Create(fGorilla);
  FTerrain.Parent := FGorillaViewport;
 
  // set resolution of terrain to 256 x 256 sections
  // this generates 65.536 cells with 131.072 triangles and 393.216 vertices.
  FTerrain.ResolutionX := 256;
  FTerrain.ResolutionY := 256;
 
  // here we load the height map image
  FTerrain.HeightMap.LoadFromFile(LTexturePath + 'terrain-h.jpg');
 
  // adjust terrain size and scaling
  FTerrain.HeightScale := 10;
  FTerrain.Scale.X := 100;
  FTerrain.Scale.Y := 10;
  FTerrain.Scale.Z := 100;
 
  // build terrain mesh from previously loaded heightmap
  // 1st param: static buffering for large number of vertices.
  // 2nd param: decimation disabled
  FTerrain.RebuildTerrain(true, false);
 
  // apply a material as texture to it
  FTerrainMaterial := TGorillaLambertMaterialSource.Create(FTerrain);
  FTerrainMaterial.Parent := FTerrain;
  FTerrainMaterial.Texture.LoadFromFile(LTexturePath + 'terrain-c.jpg');
  FTerrain.MaterialSource := FTerrainMaterial;
end;

Creating a terrain at runtime by procedural method

Form1.pas
uses
  Gorilla.Terrain,
  Gorilla.Material.Lambert;
 
procedure TForm1.FormCreate(Sender: TObject);
var LTexturePath : String;
begin
  LTexturePath := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
 
  FTerrain := TGorillaTerrain.Create(fGorilla);
  FTerrain.Parent := FGorillaViewport;
 
  // set resolution of terrain to 256 x 256 sections
  // this generates 65.536 cells with 131.072 triangles and 393.216 vertices.
  FTerrain.ResolutionX := 256;
  FTerrain.ResolutionY := 256;
 
  // adjust terrain size and scaling
  FTerrain.HeightScale := 10;
  FTerrain.Scale.X := 100;
  FTerrain.Scale.Y := 10;
  FTerrain.Scale.Z := 100;
 
  // build a random terrain by a predefined procedural algorithm
  FTerrain.RandomTerrain(TRandomTerrainAlgorithmType.DiamondSquare);
 
  // apply a material as texture to it
  FTerrainMaterial := TGorillaLambertMaterialSource.Create(FTerrain);
  FTerrainMaterial.Parent := FTerrain;
  FTerrainMaterial.Texture.LoadFromFile(LTexturePath + 'terrain-c.jpg');
  FTerrain.MaterialSource := FTerrainMaterial;
end;

NOTICE: Once you build a random terrain, you are able to store the heightmap bitmap and reload later.

Implemented terrain algorithms

Algorithm Notice
Hill A basic procedural hill algorithm. The algorithm will produce smooth hills by radius settings and a given count.
DiamondSquare A very popular algorithm to build random terrain. The algorithm creates randomly lows and highs for a realisic terrain.
Mandelbrot Creates the typical mandelbrot pattern: https://en.wikipedia.org/wiki/Mandelbrot_set This is a fixed result, but you could use this as basis for further computation.
PerlinNoise Perlin noise terrains are a good choice for random terrain. The component provides different mathmatical interpolation methods (linear, cosine, cubic).
Plateau A plateau terrain is described by a specific number of high and flat areas, while the rest is much lower. The algorithm extends the TDiamondSquareTerrain.
Brownian Brownian terrains or brownian surface is based on the diamond square based terrain algorithm: https://en.wikipedia.org/wiki/Brownian_surface The component computes peaks by a specific number of random particles. Afterwards the complete terrain will be smooth to create a realistic landscape.

Creating an individual procedural terrain algorithm

You can also develop your own procedural algorithm by extending TRandomTerrainAlgorithm or any descendant. In the example below, we generate a random terrain:

MyTerrainAlg.pas
type
  TMyTerrainAlgorithm = class(TRandomTerrainAlgorithm)
    protected
      procedure Generate();
    public
      function GetHeightMap() : TBitmap; override;    
  end;  
 
{ TMyTerrainAlgorithm }
 
 
procedure TMyTerrainAlgorithm.Generate();
var x, z: Integer;
       i : Integer;
begin
  System.SetLength(FData, 256);
  for i := 0 to High(FData) do
    System.SetLength(FData[i], 256);
 
  for x := 0 to 255 do
    for z := 0 to 255 do
    begin
      FData[x, z] := Random(100) / 100;
    end;
end;
 
function TMyTerrainAlgorithm.GetHeightMap() : TBitmap;
begin
  Generate();
 
  result := inherited;
end;
 
LMyTerrainAlgorithm := TMyTerrainAlgorithm.Create();
try
  FTerrain.RandomTerrain(LMyTerrainAlgorithm);
finally
  FreeAndNil(LMyTerrainAlgorithm);
end;

Resolution

It is recommend to use 2 ^ X resolution sizes for your terrain. Set resolution by the published properties “ResolutionX” and “ResolutionY”.

The table below lists common terrain sizes and their resulting vertices.

Size Vertex-Count Index-Count Triangles Memory-Size
16 x 16 289 1536 512 26.952 Bytes
32 x 32 1089 6144 2048 102.984 Bytes
64 x 64 4225 24.576 8192 402.504 Bytes
128 x 128 16.641 98.304 32.768 1.591.368 Bytes
256 x 256 66.049 393.216 131.072 6.328.392 Bytes
512 x 512 263.169 1.572.864 524.288 25.239.624 Bytes
1024 x 1024 1.050.625 6.291.456 2.097.152 100.810.824 Bytes
2048 x 2048 4.198.401 25.165.824 8.388.608 402.948.168 Bytes

Notice: When using terrain on Android, remember the 16-Bit vertex and index limitation. You are allowed to use at max 65536 indices per mesh on Android systems.

Smoothing

In case you are using a height-map smaller than your terrain-resolution, the resulting terrain could show some unlovely steps. Therefore the component provides the published “Smoothing” property. Set a value between 1 and 20 to apply smoothing algorithm onto your heightmap. A value of zero means that smoothing is deactivated.

Decimation

Due to optimization reasons the component provides an experimental decimation algorithm.

// 1st parameter - static buffering of vertex data
// 2nd parameter - decimation algorithm execution
FTerrain.RebuildTerrain(true, >>>true<<<);

Generating a procedural terrain by algorithm, activate decimation like this:

// 1st parameter - type of terrain algorithm
// 2nd parameter - static buffering of vertex data
// 3rd parameter - decimation algorithm execution
FTerrain.RandomTerrain(TRandomTerrainAlgorithmType.DiamondSquare, true, >>>true<<<);

Next step: Skybox