threejs-biomes: Whole worlds from one seed.
Climate, continents, mountain ranges, rivers and volcanoes, sorted into 20 blended biomes on an infinite plane or a whole planet. Streaming terrain takes you from orbit down to the ground an ant walks on.
A planet in a few lines.
Make a World from a seed, hand it to WorldTerrain, and steer with SurfaceControls. Chunks build in workers if you give it one, and every setting can change while it runs.
import { World, WorldTerrain, SurfaceControls } from 'threejs-biomes'
const world = new World({ seed: 'pangaea', surface: 'sphere', radius: 60_000 })
const controls = new SurfaceControls(camera, renderer.domElement, world) // 1 cm … orbit
const terrain = await WorldTerrain.create({ world, camera, scene })
renderer.setAnimationLoop(() => {
controls.update()
terrain.setOrigin(controls.origin) // floating origin
renderer.render(scene, camera)
})
world.biomeAt(120, -40).name // 'Temperate deciduous forest'
world.set({ mountains: { height: 1600 } }) // live: chunks rebuild
import { useWorld, WorldTerrain } from 'threejs-biomes/react'
function Scene() {
const world = useWorld({
seed: 'pangaea',
mountains: { height: 1200 },
rivers: { enabled: true },
})
return (
<WorldTerrain
world={world}
lodFactor={2.5}
material={{ debug: 'biomes' }}
/>
)
}
Everything a world needs.
Climate first, then height, then biomes, then ground. Every step is a deterministic function of the seed and a position, so worlds never end and never change behind your back.
Twenty biomes
Blended, never cut.
Each biome has a centre in climate space, and every point blends its nearest few, so forests thin into grassland instead of stopping at a line. The table is plain JSON in BIOMES: edit it or replace it.
- Deep ocean
- Beach and coast
- Temperate grassland
- Deciduous forest
- Temperate rainforest
- Boreal forest (taiga)
- Tundra
- Glacier and ice sheet
- Alpine meadow
- Mountain peaks
- Hot desert (erg)
- Badlands (mesa)
- Savanna
- Tropical rainforest
- Tropical dry forest
- Mediterranean shrubland
- Cold steppe
- Wetland
- Mangrove
- Volcanic
debug: 'biomes'Climate drives it
Temperature, moisture, wind.
Continentalness, erosion, temperature and moisture fields come first. Temperature falls 6.5 °C per kilometre of height and mountains cast rain shadows, so peaks are cold and their lee sides dry. renderWorldMap draws any field as a top-down map.
map overlayFlat worlds and planets
One switch: surface.
An infinite plane for games that think in x and z, or a whole sphere with a real horizon. On a planet, LocalFrame gives any spot a flat (x, z) => y view, so height-function packages work unchanged.
surface: 'plane'
surface: 'sphere'From orbit to an ant
One camera, every scale.
SurfaceControls zooms from 1 cm to orbit with automatic near and far planes. A floating origin keeps the camera near render-space zero, so the ground stays precise at planet scale.

Streaming LOD terrain
A quadtree that follows the camera.
A flat grid or a cube-sphere quadtree splits where you look and merges behind you. Skirts hide the seams, noise octaves below a chunk's resolution are skipped, and chunks build in Web Workers under a per-frame time budget.
debug: 'lod'Shaped by the land
Ranges, rivers, volcanoes.
Ridged mountain ranges, eroded hills, rivers carved toward the sea and rare volcanoes with craters. Biomes shape their own ground too: desert dunes, mesa terraces, tundra hummocks, flat wetlands and glacier crevasses.
mountains.height: 1800Plain data, all live
Save it, share it, send it to a worker.
Every option is JSON. world.set() rebuilds the terrain progressively, and height, biomeAt and sampleAt answer gameplay questions. Data-only modifiers flatten circles and paths, which is how towns level their roads and lots.

Real erosion
For bounded maps.
GPU hydraulic erosion baked into a tile and cached, for maps with edges. Infinite worlds keep the cheap eroded noise they use today.
Go make a world.
Fly from orbit to the ground in the live demo, or go straight to the API reference.