Terrain Generation — Part 1

Terrain generation can be a very difficult area for development — if you make it one. What I mean is: generating the mesh for a terrain can be an incredibly difficult and daunting task. This stems from the fact that there are many different techniques on how you can generate terrain. In its simplest form, to generate a terrain mesh, all you need is a grid of vertices with different heights. But, on the more advanced side, the terrain can be variably tessellated in specific areas to provide extra fidelity while still retaining stellar performance. Today, I will be going over how to start generating terrain, which will provide a launching pad for some of the more difficult topics.

John Kloetzli, Jr — Civilization 5 — GDC 2014

Starting Out

Create a new class, name it ‘TerrainChunk’, or something along those lines. It will hold the data for each chunk, or section of the terrain. This class will have a couple of utility functions that you can use to simplify your game development. These functions will also be utilized in future tutorials, so I would strongly suggest that you add them to your code. This class will also hold a function to generate the Terrain Mesh, and we will run through how you do that.

Building Some Utilities

There are a couple of utilities that we should write before we start getting into generating the terrain mesh. Each function that we need to write will be part of the TerrainChunk class, so include them all in there. All of the code will be shown in C# but can be easily understood by anyone with a basic knowledge of programming. If I were to explain why each of the functions worked in detail, this tutorial would be incredibly long, and no one would want to read it.

getTerrainHeight

This will be a pretty simple function that takes in an x-coordinate and a y-coordinate and will output the height of the terrain at that point. It will automatically interpolate the height of the four points that it lies between by using bilinear interpolation.

getTerrainSlope

This function will tell us what the slope of the terrain is based on two different sets of x-coordinate and y-coordinate inputs. This function will be very helpful if you have an RTS where specific characters cannot move on high slopes, or buildings can only be placed at certain slope inclines. To imagine how the function works, it gets the height at the first point, and then gets the height at the second point, then returns the slope between those two points. The code shown below is not the fastest way to make a slope function, but it is one of the easiest to understand.

setTerrainHeight

This is going to be the opposite of the getTerrainHeight function. This function will take in a height value, x-coordinate, and y — coordinate, and will set the height based on those values. There will not be any interpolation at the moment (it will be covered in a later tutorial), instead, the coordinates will be rounded to their closest neighbor, and that point’s height will be set.

setTerrainHeights

This is the same idea as the setTerrainHeight function. The only difference is that this function will be setting a large chunk of terrain heights at the same time. The input of the function is two integers that specify the x and y offsets of the change, and a 2D array of floating-point numbers representing the heights that need to change.

Getting the Terrain Generated

In the Terrain Chunk class, you will need to create a function that takes in an integer as an input, and a Mesh as the output. This function will be named GenerateTerrainMesh, and the integer will represent the resolution that the grid needs to be. So, as the number is increased, the number of triangles and points in the mesh are decreased. This allows for the generation of lower quality terrain when the camera is further away. This technique is known as Level of Detail, and it can be very helpful to save on resources while still providing good quality terrain. There are a couple of different parts necessary for terrain generation, so I separated them in easy to understand areas below.

Vertex Generation

Create a new array of Vector3 (they are an object that stores x, y, z positioning), name it ‘vertices’, and set the size of the array to ((ChunkWidth + 1) * (ChunkHeight + 1)). To explain this equation, imagine a grid. The length of the grid is ChunkHeight, and the width of it is ChunkWidth. Starting with the first point,(0, 0), all of the points can fit in it, except, for the line of points at the top of the terrain (when looking from the sky downwards), and left of the terrain. We can remedy this by adding 1 to both the ChunkWidth and ChunkHeight, to make sure all the vertex positions are included.

Index Generation

To start the generation of the indices, create an array of integers with their length equal to the equation shown below. To explain this equation, imagine the grid mentioned in the example above, except instead of referencing the points, we are mentioning the squares that four of those points create. In each of these squares, there are two triangles, made up of three points each, and that is where the six comes from. It is really saying, “gridWidth * gridHeight * squarePointCount”.

UV Generation

Finishing Up

To finish up, create a new local variable with Mesh as the type. This is class is specific to unity, but other languages offer very similar systems. Set the vertices array to the vertices that we just created, set the triangles array to the indices we just created, and finally, set the UV array to the UVs that we just created.

You’re Done! (for now)

That’s it. You now have a flexible terrain system that allows you to have high-resolution terrain, low-resolution terrain, and everything in between. But, there is more coming in the future- this is only part 1 of a multipart series. In this series, we will work our way up to terrain generation techniques that can be seen in many AAA games.

A developer, creator, and programmer from Connecticut.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store