top of page

Procedural 3D Terrain Generation

5
6
1

 

Project Name: Procedural 3D Terrain Generation using Perlin Noise

 

Technology: Unity Engine, C# Scripting

 

Type: Solo Project

 

Description:

 

In this application, I have procedurally generated a 3D low poly world with two different types of Biomes.

 

  1. A landscape, with a mountain range including moving water, Sand, Greenery, and Ice tops of mountains.

  2. An island, which is covered by water from all sides and has moving water, sand, greenery and ice tops.

 

A screenshot of both biomes is shown above. We can use the flycam(Mouse to look and WASD to move) and fly over the procedurally generated terrain to take a look at the terrain. We can Press “E” and “Q” to switch between terrain biomes.

 

By default, the terrain is generated at compile time but the same algorithm can also work at runtime, however, the algorithm is not optimized to do so.

 

Overview of the procedural generation events (Step by step list of events of how the terrain is generated procedurally):

  1. 2D Noise map is generated using Perlin Noise function.

  2. Octaves are generated on the same 2D noise map.

  3. The 2D Data is mapped to 3D coordinates of a new empty mesh.

  4. The Vertices are corrected according to some of the variables like “Mesh Height Curve”.

  5. Mesh is divided into smaller triangles for LOD and optimization purposes.

  6. Depending on Biome Selected, the mesh is regenerated again.

  7. Colors as textures are applied to the Mesh depending on the color map.

  8. Dynamic Water is applied around the mesh.

 

 

Total algorithms used: 2

 

  • Algorithm 1 (For generating Octaves):

For each Octaves we want to generate, we collect a random number between range -100000 to 100000 and then generate noise from that seed. This random number is generated based on the "System Clock", making it very unpredictable. Additionally, for each octave, a new seed is generated by offsetting the same seed from the previously generated octave. This whole random generation is applied to both X-axis and Y-axis of the current octave. Following is the main part of algorithm where octave calcualtion happens:

 

 

 

        System.Random Rng_No = new System.Random(seed);

        Vector2[] octaveOffsets = new Vector2[Total_Octaves];

 

                     for(int i=0;i<Total_Octaves;i++)

                     {

                              float offset_X = Rng_No.Next(-100000,100000)+ offset.x;

                              float offset_Y = Rng_No.Next(-100000,100000)+ offset.y;

                              octaveOffsets[i] = new Vector2(offset_X, offset_Y);

                     }

 

                     for (int i = 0; i < Total_Octaves; i++)

                     {

                              float sampleX = (x-halfWidth) / scale * frequency + octaveOffsets[i].x;

                              float sampleY = (y-halfHeight) / scale * frequency + octaveOffsets[i].y;

 

                     }

 

 

  • Algorithm 2 (For generating Island Biome):

 

Creating this Biome was interesting. I had a 2D noise map filled with octaves and random noise. I was thinking to make a separate noise function to make noise which will look like an islandic style. However, I found out that masking a 2D gradient map with current noise map can do the trick too. So I wrote a mathematical function to generate a 2D gradient map where all the pixels in the middle were dark(having full opacity) and rest of the pixels had no opacity. Following is the mathematical formula:

Above function gives curve like this:

After implementing the above function in code:

​

​

                                                 Mathf.Pow(value, a) / (Mathf.Pow(value, a) + Mathf.Pow(b - b * value, a));

​

​

Above line of code generated this 2D noise map:

The Black color value in pixel means its opacity. Totally dark pixels are opaque and the pixel shifts towards becoming transparent the more white color it has. In the end, I masked this noise map with original Biome barren terrain, which gave us feel of an island. The white pixels(fully transparent ones) are overlapped by water.

 

 

Where can we use this application:

 

Because of the low poly looks, we can use this terrain in prototypes of many kind of games. Games which need interaction with water are good examples of this. We already have a dynamic water mesh, we just need to add colliders and bam! we have a game where you can sail your own boat to a variety of islands. For a game which needs Jungle style theme, just increase the Mesh Height curve to an extent where water becomes invisible and we have a nice barren environment with different options to generate mountain ranges.

bottom of page