image
Computer graphics
April 12, 2025

The Procedural Generation: From Randomness to Realism


šŸ‘‰ This article is intended for readers of all skill levels, with no prerequisites required to get started.

In this article, we explore what procedural generation is and how it’s applied to create virtual worlds. This is not a step-by-step tutorial but rather an opportunity to demystify the concept and get you wondering about all the things it could be used for.

Procedural generation is a technique used in game development to create content algorithmically instead of manually. It allows developers to produce environments, objects, and experiences that feel organic without designing every element by hand.

Use cases

  • World generation

    image

    image

    The most known use of this process is terrain, biomes, and ecosystems dynamic creation. Minecraft is a good example of that. Each new world is unique, thanks to procedural rules.

  • Dynamic Level Design

    image

    image

    Especially in roguelite games, procedural generation is used to create the dynamic level designs. In The binding of Isaac, for example, rooms are designed by hand, but their layout is dynamically generated, making each run unique.

  • Texture and Asset Creation

    image

    image

    Creating visual details on a massive scale can be overwhelming, but procedural generation makes it manageable. Surfaces, patterns, and objects can be generated dynamically, ensuring that even the smallest details contribute to a world’s uniqueness. This approach adds richness without requiring endless manual work.

  • NPC Behavior and Quests

    image

    image

    NPC's can modulate their dialogues, movements, routines, and behavior towards the player, to make them seem more realistic. Skyrim and Red Dead Redemption 2 are good examples.

as you've seen, procedural generation is involved in almost every aspect of video game creation. However, in this article, we're going to understand how it works through the example of a world creation. So where do we start ?

Step 1 : Random !

The first step is to create randomness, but not just any kind of randomness.

For many applications, pure randomness is too chaotic and disconnected. Take the example below, the chart illustrates pure random values. These values are entirely independent of each other, resulting in abrupt changes.

While this type of randomness can be useful in certain scenarios, it often falls short when it comes to simulating natural or organic patterns. What we often need is randomness with structure, a type of controlled variation that feels smooth and natural :

This chart showcases a more structured approach known as Perlin noise, a technique among others that introduces a sense of continuity.

By ensuring neighboring values are similar, it produces smoother transitions that are ideal for generating lifelike textures, flowing landscapes, and organic forms.

Understand what is a noise

In the context of procedural generation, a noise is a type of mathematical function that generates values distributed across a space, with a certain continuity and coherence. You don’t need to understand how it’s made, just how it works and how it can be applied.

The Perlin noise that we used is one of them. Its ability to produce smooth and continuous variations has made it a solution for many applications, let’s take a closer look at how it works:

On a digital canvas, each pixel is assigned a brightness value between 0 and 100, with 0 representing pure black and 100 pure white. However, as we’ve seen, it’s not just about assigning random values to each pixel. There’s a gradual transition between neighboring values, creating smooth changes across the canvas.

Hover your mouse over the image to zoom in and see its details. You'll notice each pixel's brightness value and the smooth transitions between them :

That is basically the concept of Perlin noise. However, if you’re curious about how it’s made, I recommend reading this articlefrom Raouf Touti.

There are many types of noises, each designed for different purposes. Some examples are:

Fractal noise

Fractal noise

Worley noise

Worley noise

White noise (yes the one from the TVs !)

White noise (yes the one from the TVs !)

Simplex noise

Simplex noise

🌱 The Seed

We won’t dive too deep into the details, but before moving on, I want to introduce an important concept in noise generation: the seed.

You may have noticed the "seed" field with the value 42 in the perlin noise generator component, but what is this ? and why does the noise change when i change the seed value ?

Imagine you open a giant cookbook to page 172. You follow the recipe exactly as it’s written, and you end up with a specific dish, the same every time.

The seed is like the page number. As long as you open the same page, you get the same recipe, and the same result. Change the page number, and it’s a completely different recipe : new ingredients, new instructions, new outcome.

In procedural generation, the seed works the same way : it’s the starting point that determines everything that follows.

You may be familiar with this concept if you ever played Minecraft. Using the same seed as your friend generates identical worlds, allowing you to explore the same terrain.

Step 2 : Turning noise into relief

Remember our Perlin noise grid with values between 0 and 100 ? We can reinterpret these values as elevation levels. For instance, a value of 0 in our noise could correspond to the bottom of a cavern, while a value of 100 might be a mountain peak.

Let's take a sample from the grid :

Represented in 3D, this is what it looks like, with elevation values mapped to height:

Each cell in the grid represents an altitude value.
This approach makes it easy to visualize the underlying data and understand how procedural generation affects every point on the surface.

Interpolation & Smoothing

To achieve a more natural appearance, we apply smoothing techniques, such as interpolating the noise continuously or subdividing the mesh. This turns a grid of discrete values into a flowing surface.

This smoothing is often applied automatically by 3D software (like Blender or Unity), which interpolate the vertices and use smoothed normals to render a fluid-looking surface, even if the underlying data remains grid-based.

Here’s how that would look in a more realistic context :

With this step done, we can clearly see our terrain taking shape, but it's not quite there yet.

Adding Granularity with Octaves

Octaves are successive layers of noise, each with its own frequency and amplitude, stacked on top of the base layer that we just created. This process adds granularity and depth to the final result.

šŸ” Frequency is the level of detail
šŸ“¶ Amplitude is the range of values

Let's take 2 more samples with higher frequency and lower aplitude :

Frequency : 20x20, Amplitude : 0.00 to 0.50

Frequency : 20x20, Amplitude : 0.00 to 0.50

Frequency : 40x40, Amplitude : 0.00 to 0.25

Frequency : 40x40, Amplitude : 0.00 to 0.25

By treating the values as elevation levels and stacking the layers

We get a more detailed map :

With interpolation & smoothing :

Step 3: Adding details

At this stage, we have a detailed terrain, but it still looks empty and artificial.

To make it more visually interesting and realistic, we need to add details like environmental variations, textures and biomes.

Environmental Factors

First, we need to determine what kind of environment each region represents.

For now, the only information we have is elevation. But elevation alone isn’t sufficient to determine the type of environment that should emerge.

šŸ‘‰ Two regions at the same altitude can have completely different landscapes. A desert and a jungle, for example, might share similar elevations but have vastly different climates and ecosystems.

To introduce variety and realism, we rely on additional data layers that define key environmental properties:

  • šŸ’§ Humidity
  • šŸŒ”ļø Temperature
  • šŸļø Proximity to Water
  • šŸ“ Slope and Erosion

Just like the elevation map, some of these factors will be generated using separate noise maps with their own scale and frequency. This is the case for the humidity and temperature values. Same process as the octaves, we generate perlin noises :

Humidity noise map

Humidity noise map

Temperature noise map

Temperature noise map

and apply them to the map :

image

image

Other factors, like proximity to water and slope are derived directly from the elevation map. Instead of generating new noise, we analyze the terrain’s shape, calculating distances to water bodies or detecting steep areas, to determine how these factors influence the environment.

The slope is the rate at which elevation changes between neighboring points. Steep areas have large elevation differences, while flat areas show little variation.

In this example, the map is colored according to slope gradient: the more purple the area, the steeper the slope :

It's not easy to see because our terrain is very zoomed out and quite steep, and in some areas, the light reflection actually makes it harder to spot the difference, but if you look closely in some areas, you can spot the difference :

The Water is determined by setting an elevation threshold. Everything below this value is considered underwater.

image

image

From this, we can calculate proximity to water by measuring the distance between each point and the nearest water body.

In this example, proximity to water is represented in orange :

By layering these data maps together, we now have all the environmental information required to define biomes !

Biome Generation

By combining these factors, we categorize the world into recognizable ecosystems like forests, tundras, and savannas. For example:

From there, we can define biomes on our map and assign them the right textures :

Going Further

Now imagine tying this together with climate systems, procedurally generated creatures, villages, quests, and world details, all driven by algorithms !

We won’t go into every possible application of procedural generation in terrain creation, what matters is that you understand the core concept. This article aims to provide a broader understanding rather than focus on concrete implementations.

Conclusion

In this article, we demystified what procedural generation is through the example of one of its applications, but as you'd expect, procedural generation goes far beyond that.

If this introduction has caught your attention, i highly encourage you to dive in and experiment procedural generation for yourself. You'll find a wealth of content online for all levels, interests and applications.

In the meantime, if you'd like to test your knowledge of this article, you can give this quizz a try :

Test your knowledge1 / 8

Which of the following best describes procedural generation ?
Why is pure randomness often unsuitable for natural-looking environments ?
What does a 'seed' influence in procedural generation ?
What happens if you keep the same seed ?
In the context of terrain generation, what can Perlin noise values represent ?
What are 'octaves' in noise-based terrain generation ?
What does frequency control when stacking octaves ?
Which of these is NOT an environmental factor used to generate biomes ?
Your score : 0 / 8Don't worry, you'll do better next time!