Procedurally generate random terrain with Perlin Noise.
GitHub repository : https://github.com/B10732009/procedural-terrain-generation
Procedural Generation is a method of creating data algorithmically as opposed to manually, typically through a combination of human-generated assets and algorithms coupled with computer-generated randomness and processing power.
In video games, Procedural Terrain Generation is very useful where you want to generate natural terrain (caves, hills, rivers, etc.) that has a smooth feel, but is still random.
Perlin Noise is a very popular algorithm for procedural generation developed by Ken Perlin in 1983. It can be used for any kind of wave-like, undulating material, texture, or terrain.
Compared with just some random values, Perlin Noise can generate values very smoothly and continuously, which looks more realistic in terrain generation.
The graph below shows the difference between normal random values and perlin noise.
In this project, I am going to implement a set of API (for C++ and Python) of the Perlin Noise algorithm in 1D, 2D, and 3D (if time is enough), and use these API to render some terrain with Ursina (a game engine in Python).
Anyone who wants to simulate random terrain or uses Perlin Noise for application.
- Use
C++
to implement the algorithm. - Use
Pybind11
to wrap C++ functions for Python. - Use
Python
to render the terrain with these APIs (with Ursina).
API functions :
- Create class object
- Create class object with detail options (scale, octaves, lacunarity, persistance)
- Get noise value at specific position
- Get noise value list
- Get single parameter value (seed, xsz, ysz, zsz, scale, octaves, lacunarity, persistance)
The API will have both C++
and Python
version.
For Python
users :
import noise
# create class object
n = noise.Noise1D(seed, x_size)
n = noise.Noise2D(seed, x_size, y_size)
n = noise.Noise3D(seed, x_size, y_size, z_size)
# create class object with optional parameters
n = Noise1D(seed, x_size, scale, octaves, lacunarity, persistance)
n = Noise2D(seed, x_size, y_size, scale, octaves, lacunarity, persistance)
n = Noise2D(seed, x_size, y_size, z_size, scale, octaves, lacunarity, persistance)
# get noise at specific position
n[i] # 1D
n[i, j] # 2D
n[i, j, k] # 3D
# get other attributes
n.seed
n.xsz
n.ysz # (only for 2D & 3D)
n.zsz # (only for 3D)
n.scale
n.octaves
n.lacunarity
n.persistance
n.data # get noise list
For C++
users :
#include "noise1d.hpp"
#include "noise2d.hpp"
#include "noise3d.hpp"
// create class object
Noise1D n(std::size_t _seed, std::size_t _xsz);
Noise2D n(std::size_t _seed, std::size_t _xsz, std::size_t _ysz);
Noise3D n(std::size_t _seed, std::size_t _xsz, std::size_t _ysz, std::size_t _zsz);
// create class object with optional parameters
Noise1D n(std::size_t _seed, std::size_t _xsz,
std::size_t _scale, std::size_t _octaves, double _lacunarity, double _persistance);
Noise2D n(std::size_t _seed, std::size_t _xsz, std::size_t _ysz,
std::size_t _scale, std::size_t _octaves, double _lacunarity, double _persistance);
Noise3D n(std::size_t _seed, std::size_t _xsz, std::size_t _ysz, std::size_t _zsz,
std::size_t _scale, std::size_t _octaves, double _lacunarity, double _persistance);
// get noise at specific position
n(std::size_t idx1); // 1D
n(std::size_t idx1, std::size_t idx2); // 2D
n(std::size_t idx1, std::size_t idx2, std::size_t idx3); // 3D
// get other attributes
std::size_t n.seed();
std::size_t n.xsz();
std::size_t n.ysz(); // (only for 2D & 3D)
std::size_t n.zsz(); // (only for 3D)
std::size_t n.scale();
std::size_t n.octaves();
double n.lacunarity();
double n.persistance();
std::vector<double> n.data(); // get noise list
This system is built by makefile
.
Makefile targets :
Target | Description |
---|---|
(all) | compile a noise.so in noise/ folder. |
test | use pytest to test python API. |
graph1 | display 1D noise testing graph. |
graph2 | display 2D noise testing graph. |
graph3 | display 3D noise testing graph and generate a noise3d.gif file in test/ folder. |
render | take parameters in render.conf , generate heightmap.png and colormap.png , and render terrain by Ursina . |
clean | remove all generated files (*.so, __pycache__/, etc). |
- Before rendering terrain, remember to put the parameters in
render.conf
.
- Automatic build system :
GNU Make
- Version control :
git
- Testing framework :
pytest
- Documentation :
README.md
in the github repository
Rendered Terrain | |
---|---|