This project was about creating a new method of procedural generating terrain for the use in games. This was for my final year dissertation. Standalone player and source code available below at GitHub.
The end product is a product that demonstrates being able to build terrain by customizing methods and features used. Methods can be added and removed in a modular way. This means that you can easily choose features to have on the terrain, customise them and even add new features easily without needing to write more than needed. The usable methods produce and add one clear feature such caves to the terrain.
The generated terrain supports 3D features such as caves unlike most height map approaches.
The project has 2 major components, the Generator system and the Generator UI. Both will be covered in detail below.
The generator system contains a main managing system to manage the generation process. It takes a list of provided generation methods in a list. These have their custom properties applied from the UI which is covered later. The generation process then occurs by producing an empty volumetric container and passing it through each method. Each method modifies this data.
The implemented methods are:
- Perlin Noise
- Cave Generator
Perlin noise generates a 2D Perlin noise data set and converts it into a 3D representation.
The Cave generator generates a basic cave structure utilizing a meta ball that is sweeps through the volumetric data and subtracts. This is very inefficient and could be greatly improved.
The result is then converted using the chosen conversion method to a visible mesh. The conversion method used in the project is an implementation of Marching Cubes by Scrawk. This is modified to be multi threaded for faster conversion.
The generator UI operates by creating a new instance of the method specified when selected by the user. This is added to the generator system list. Then reflection is performed on the instance to locate properties that can be customised by them having a specific attribute. These are displayed in the UI.
A similar process is performed when generation is triggered, the entered values are then applied back to the instance.