This is an old revision of the document!
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 := TGorillaLambertMaterial.Create(FTerrain); FTerrainMaterial.Parent := FTerrain; FTerrainMaterial.Texture.LoadFromFile(LTexturePath + 'terrain-c.jpg'); FTerrain.Mesh.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 := TGorillaLambertMaterial.Create(FTerrain); FTerrainMaterial.Parent := FTerrain; FTerrainMaterial.Texture.LoadFromFile(LTexturePath + 'terrain-c.jpg'); FTerrain.Mesh.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 |
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