This repository contains an application for procedural generation of heightmaps of terrains containing rivers.
The algorithm evolves through a series of steps, combining multiple techniques together.
At first, the plane is sampled randomly, and two extra vertices are added outside the
relevant region at north and south (namely, Ps and Pe). The
Delaunay graph of the
samples is computed, and the shortest path from Ps to Pe is found. Using the samples
in the plane, a spline is computed
and drawn with a certain thickness. The resulting image is blurred, and this process
concludes the generation of the river's bed.
On top of this, a pass of Perlin and Voronoi noise are added to introduce variety in the scene, generating a natural landscape.
Finally, a smooth offset is applied to the plane, so to give an inclination to the river.
The building process is entirely handled with CMake, and the required libraries are included as external submodules. Despite being a command line application, SFML relies on the system's ability to create GUI windows, so your system must be able to create a window. If you are working on WSL, please be sure to update to WSL2.
First, clone the repository and update the submodules.
git clone https://github.com/filthynobleman/river-generator.git --recursive
cd river-generator
git submodule update --init --recursiveBefore building the application, you need to build the included SFML library.
mkdir sfml-build
cd sfml-build
cmake ../ext/sfml/ -DSFML_WARNINGS_AS_ERRORS=FALSE -DCMAKE_INSTALL_PREFIX=./install
cmake --build . --config release --parallel
cmake --install .At this point, you can build the actual application
cd ..
mkdir build
cd build
cmake ..
cmake --build . --config release --parallelThe building process should produce a single executable named RiverGen.
The application RiverGen only accepts a single argument, which is a configuration file
in JSON format. The configuration file must specify the following attributes:
sizecan be a single integer or an array of two integers that specifies the dimensions of the heightmap.width/heightcan be used alternatively tosize.output_filespecifies the path to the output heightmap. The application also uses this path to save the ouput map as a mesh in OBJ format.perlinis a JSON object structured as follows:weightspecifies the coefficient of the Perlin noise component.scalespecifies the scale of the domain (i.e., the noise's frequency).octavesspecifies the number of octaves for the noise.
voronoiis a JSON object structured as follows:weightspecifies the coefficient of the Voronoi noise component.scalespecified the scale of the domain.
riveris a JSON object structured as follows:nodesspecifies the number of nodes in the Delaunay triangulation.samplesspecifies the number of samples for drawing the river's spline.thicknessspecifies the thickness in pixels of the river.seedspecifies the seed used to sample the plane.
gaussis a JSON object structured as follows:ksxspecifies the size of the horizontal blur.ksyspecifies the size of te vertical blur.sigmaspecifies the standard deviation of the kernel.
planeis a JSON object structured as follows:deltaspecifies the difference in height between the beginning and end of the river.widthspecifies the horizontal resolution of the output mesh.heightspecifies the vertical resolution of the input mesh.
An example of configuration file can be found in the configs folder.
Currently, the river's height is set to one and cannot be changed, so the other settings must be specified accordingly.
At the moment, there is no way to specify the river's thickness proportionally, so when the resolution of the image is changed, the thickness must be updated manually.
The attributes in the configuration file must be all set, and no default value are provided.
The path to the output mesh cannot be specified independently.
Currently, the app has been tested only in a Linux environment.
The app relies on SFML's RenderTexture objects to draw the river. These objects need GUIs to perform their tasks, so an environment with the ability to open windows is needed.

