Procedural Terrain Generation
Generate realistic, infinite terrain using noise functions, erosion simulation, and biome systems that create believable natural landscapes.
Heightmap-Based Terrain
The most common approach to terrain generation uses a heightmap — a 2D grid where each cell stores an elevation value. Multiple layers of noise at different frequencies (octaves) are combined to create natural-looking terrain.
Noise Layering
| Layer | Frequency | Amplitude | Creates |
|---|---|---|---|
| Continental | Very low | Very high | Major landmasses and ocean basins |
| Mountain | Low | High | Mountain ranges and valleys |
| Hill | Medium | Medium | Rolling hills and ridges |
| Detail | High | Low | Small bumps and surface variation |
Erosion Simulation
Raw noise terrain looks alien and unrealistic. Erosion simulation transforms it into natural-looking landscapes by simulating water and thermal processes.
- Hydraulic erosion: Simulate water droplets flowing downhill, picking up sediment and depositing it. Creates river valleys, deltas, and realistic drainage patterns.
- Thermal erosion: Material falls from steep slopes to shallow ones, creating talus slopes and softening sharp features.
- Wind erosion: Simulate wind carrying particles, creating dunes and wearing down exposed surfaces.
def erode(heightmap, iterations=50000): for _ in range(iterations): # Random droplet starting position x = random.uniform(0, heightmap.shape[1] - 1) y = random.uniform(0, heightmap.shape[0] - 1) sediment = 0.0 speed = 1.0 water = 1.0 for step in range(64): # Calculate gradient at current position gx, gy = compute_gradient(heightmap, x, y) # Move droplet downhill x -= gx y -= gy if out_of_bounds(heightmap, x, y): break # Calculate height difference h_new = sample(heightmap, x, y) h_diff = h_new - h_old # Deposit or erode if h_diff > 0: # Going uphill deposit(heightmap, x, y, sediment) else: # Going downhill erode_point(heightmap, x, y, -h_diff) water *= 0.99 # Evaporation return heightmap
Biome Distribution
Biomes are assigned based on elevation and moisture. Use a Whittaker diagram to map temperature/moisture combinations to biome types:
- Low elevation + high moisture = Tropical rainforest
- Low elevation + low moisture = Desert
- High elevation + high moisture = Taiga/Snow
- Medium elevation + medium moisture = Temperate forest
Infinite Terrain (Chunked Generation)
For open-world games, terrain is generated in chunks around the player. Since noise functions are deterministic and position-based, each chunk generates identically regardless of when it is created.
- Load ring: Generate chunks within a radius around the player.
- LOD levels: Nearby chunks get full resolution; distant chunks use lower resolution meshes.
- Seamless borders: Because noise is continuous, chunk borders are automatically seamless.
- Async generation: Generate chunks on background threads to avoid frame stutters.
Lilly Tech Systems