Skip to content

Terrain Graph

The Terrain Graph is the core of Metaplanets Creator: a visual, graph-based workflow for defining terrain, biomes, and planetary features — similar to Unreal's Blueprints, but for planets.

How it works

  • Nodes are generation stages — noise fields, height shaping, biome masks, surface detail, and more.
  • Connections flow the planet's parameters from one stage to the next.
  • Real time — tweak values and watch the planet update live in the editor.
  • Fast — the graph compiles to bytecode and then to native SIMD code, and planets are generated tile by tile at runtime, only where the camera needs detail.

The editor

The Terrain Graph editor with the Wildlands graph and the 3D Preview

Tab What it does
Graph The node canvas. Right-click for nodes; drag from a pin to filter.
3D Preview A lit globe of your planet (about 97,000 samples), coloured by height from deep sea through lowland, highland and rock to snow. It is evaluated in the background, so it doesn't block the editor.
Preview A flat Heightmap Preview (the whole planet unwrapped) or a Line Preview (a 1D slice), with min / mean / max.
Details Asset settings, including Caching → Disable Noise Prebake and Allow GPU Computation.
Compile Log Validation errors and compile messages.

3D Preview controls:

  • Relief: height exaggeration. At 1, the planet's full relief spans 6% of its radius so you can read it at globe scale.
  • Sea level: flattens everything below 0 m into water tinted by depth.
  • Low / Medium / High: preview resolution.
  • Live update: recompiles and refreshes 0.35 s after each edit.

The stats line shows the height range in km, the sample count and how long the evaluation took, which is a quick way to spot an expensive node.

3D Preview controls: Relief, Sea level, Low / Medium / High

The Compile button has a dropdown with Clear Cache & Compile. Use it after changing a cached node (Planet Simulation V2, Continents) so every planet using the graph rebuilds from scratch.

Building a terrain graph

A minimal rocky-planet graph, step by step.

1. Create the generator asset

Create a Terrain Height Generator asset from the Content Browser (Metaplanets → Terrain Height Generator). It lives alongside your level.

Create → Metaplanets → Terrain Height Generator

The generator asset in the Content Browser

2. Add a noise source

Open the asset. The editor shows the graph canvas, a live Preview, and a compile log. Add an FBM noise node and an Output node.

FBM noise and Output nodes in the Terrain Graph

3. Wire it up and compile

Connect the noise's Out to the Output node's Value, then Compile. The heightmap preview updates with live min / mean / max stats.

FBM noise wired to Output with the heightmap preview

4. Place the planet actor

Place a Metaplanet Actor in your level, then point its Generation settings at your generator asset and pick a Terrain Mode and Planet Kind.

Placing a Metaplanet Actor into the level

Generation settings on the Metaplanet Actor

Create and assign a material to your planet to add visual detail:

Selecting the planet material in the Content Browser

5. Tune the surface

Raise the noise Amplitude for stronger relief, and wire bump and normal maps into the planet's surface material for detail.

Increasing the FBM Amplitude

Wiring bump and normal maps into the surface material

6. Add a biome mask

Normalize the height into a 0–1 biome mask (Add → Divide → Saturate) and drive a Biome Output channel — this is what the foliage system scatters against.

Normalizing height into a biome mask

7. Baked noise

Metaplanets can bake noise into textures. Here the same noise shown raw (quad) versus wrapped and lit on the planet:

Baked noise: raw texture vs on the planet

Outputs

A terrain graph can drive more than height. Every output is optional except Output.

Output node Pins What it drives
Output Value Terrain height in metres above the planet radius (sea level is 0).
Biome Output X, Y, Z, W Four 0–1 channels you define, for example cold, moisture, bare rock and slope. Surfaces colour the ground from them, and spawners place plants by them.
Water Output Level, Kind, Flow Lakes, rivers and wetlands at their own height. Level in m (unset = no water); Kind: -1 auto, 0 dry, 1 ocean, 2 river, 3 lake, 4 wetland; Flow: current in m/s.

Decide what each biome channel means and keep it the same in your surface and your spawner. The shipped examples use x = cold, y = moisture, z = bare rock and w = slope.

Node reference

Heights are in metres; crater sizes are in kilometres. Noise Scale is a frequency, so higher values give smaller features. On an Earth-sized planet, Scale 400 on Simplex Noise gives features about 100 km across.

Inputs

Node Use
Position The sample's position on the sphere, plus LatitudeDeg, LongitudeDeg and their sine and cosine. Feed WorldPosition into noise; use latitude for polar caps and climate bands.
LOD Level The tile's detail level. Use it to fade out features thinner than a tile's vertex spacing so distant views don't speckle.
Constant A fixed number.

Noise

Node Use
Simplex Noise Smooth, even noise. The best choice for large region masks.
Perlin Noise, Noise Classic gradient noise.
FBM Noise Fractal noise with Octaves (4), Lacunarity (2.0) and Gain (0.5). The workhorse for detail. At very large scales its low octaves can look grid-aligned; use Simplex there.
Cellular Effector (Voronoi) Distance to the nearest cell centre. Use it for cells, one feature per cell, karst towers, volcanic paterae and cracked ice. Scale 20 gives cells about 320 km apart on Earth.
Cellular Edge A mask along cell borders (EdgeWidth) for cracks, plates and polygonal ground.
Domain Warp Noise distorted by itself, for swirled, flowing terrain.
Erosion Landforms (V2) The main realism node: erosion-carved ranges, plateaus and valleys with branching gullies that follow the slope. Seamless down to metre-scale detail. See below.
Erosion Noise A cheaper gully filter. For large planets prefer Erosion Landforms (V2).
Mesa Noise Terraced plateaus and buttes in the style of Monument Valley. Outputs Height and CliffMask.
Metaplanets Natural Noise v1 / v2 Ready-mixed natural terrain: ridged FBM, cells and erosion (v1), or a baked hydraulic-erosion tile (v2).

Erosion Landforms (V2) pins:

Pin Meaning
Scale Landform size in metres. 6000 suits mountain ranges, 1500 hills.
Amplitude Relief in metres.
Strength, GullyWeight Gully depth. GullyWeight 0 = crests only, 1 = full gullies.
Octaves Detail levels. The smallest gully is about Scale × 0.1 / 2^Octaves.
Ridged 0 = rounded hills, 1 = sharp alpine ranges.
Plateau, TerraceStep Flat-topped mesas and terraces.
Sediment Flat, filled valley floors.
Mask 0–1: where the landform applies, for example a mountain mask.

Outputs: Height, Ridge, Erosion, Sediment and Slope. All of them work as masks for surfaces and foliage.

Planet-scale terrain

Node Use
Planet Simulation V2 A whole planet in one node: continents from a pseudo-tectonic simulation, mountain belts, continental shelves, and river networks with carved channels, lakes and deltas. Key pins: Continents (8), LandmassCoverage (0.42), LandmassHeightMeters, OceanDepthMeters, MountainHeightMeters, ErosionIntensity, Age, WaterwayIntensity, RiverWidth, MeanderStrength, Seed, CacheResolution. Outputs Height plus masks: ContinentMask, OceanMask, MountainMask, FaultMask, ShelfMask, CoastMask, IslandMask, HillMask, BasinMask, TablelandMask, RiverMask, CoastDistance and RiverDepth.
Climate Map Physical climate from latitude, height and terrain: sunlight, prevailing winds, moisture carried inland, rain shadows behind mountains and cooling with altitude. Outputs BiomeMask (snow, vegetation, forest density), ErosionMask (bare rock), MountainRangeMask and DryMask (steppe to desert).
Water Field Reads the simulation's rivers and lakes: WaterLevel, WaterType, WaterDepth and RiverFlow. Wire it into Water Output.
Continents A simpler polygon-continent field with MacroHeight, ContinentMask, CoastMask and MountainMask.
Planet Aged Adds coasts, islands, old worn mountains and cliffs to an existing height.
Ridge Mountains Ridged multifractal mountains (default 8,000 m).
Crater Field Impact craters with rims: Density (per million km²), Min/MaxRadius, Depth, RimHeight and RimWidth (km). Outputs height and RimMask.
Crater Pit, Crater Cone Dense micro-craters for close-up detail.

Heightmaps and real data

Node Use
Planet DEM Real global elevation data (Mars MOLA, Earth ETOPO and others). See Real elevation data.
Stochastic Heightmap Scatters a heightmap texture as randomly rotated stamps, with no visible tiling.

Math and logic

Add, Subtract, Multiply, Divide, Pow, Sine, Abs, Min, Max, Clamp, Saturate, Floor, Ceil, Frac, Lerp, SmoothStep, Make/Break Vector, vector math (Length, Normalize, Dot, Cross, Distance and more), Slope Gradient, and comparisons with Select (if/else).

SmoothStep and Saturate are how you build masks. For example, SmoothStep(1500, 2500, height) is 0 below 1,500 m and 1 above 2,500 m.

PlanetScript

Every terrain graph can also be written as text in PlanetScript (.ps), which compiles to exactly the same graph. Function names are node names, and .OutputName picks an output. Scripts are easy to diff, review and generate, and every example planet ships as one.

planet Earthlike {
    let pos = Position();
    let sim = PlanetSimulationV2(Position: pos, Continents: 6.0, LandmassCoverage: 0.32,
        LandmassHeightMeters: 850.0, OceanDepthMeters: 5200.0, MountainHeightMeters: 5200.0,
        ErosionIntensity: 0.5, Age: 1.0, Seed: 2718.0, WaterwayIntensity: 1.2,
        RiverWidth: 1.0, CacheResolution: 1024.0, MeanderStrength: 0.8);
    let clim = ClimateMap(Position: pos, BaseHeight: sim.Height,
        ContinentMask: sim.ContinentMask, OceanMask: sim.OceanMask,
        RidgeMask: sim.MountainMask, Seed: 2718.0);
    height = clim.FinalHeight;
    let b = BreakVector(clim.BiomeMask);
    biome.x = b.X; biome.y = b.Y; biome.z = clim.DryMask; biome.w = clim.ErosionMask;
}
Statement Meaning
height = ...; Required. Terrain height in metres.
biome.x = ...; (to .w) Biome channels.
water.level, water.kind, water.flow Inland water.
spawn.<Key> = ...; Foliage density, in spawner scripts (see Foliage).
let name = ...; A named value.
fn Name(a, b) = expr; A reusable macro.
kernel Name(...) { for i in 0 .. 8 { ... } return ...; } Loops, unrolled at compile time (constant bounds).
surface Name { layer ... } The planet's surface, in the same file.

Build an asset from a script with the commandlet:

UnrealEditor-Cmd MyProject.uproject -run=MetaplanetCreateExamples -scripts=C:/Planets -names=Earthlike -dest=/Game/Planets
Scout on the built asset

Every noise node gets a random orientation based on its position in the compiled graph. Building an asset can order nodes differently from compiling the script directly, so mountains may land elsewhere. Pick camera locations on the built asset. Changing values (not the structure) keeps the layout.

Planet actor settings

Setting Where Notes
Sphere Radius Meters Metaplanet → Shape 6,371,000 is Earth. Mars is 3,390 km, the Moon 1,737 km.
Terrain Generator Asset Metaplanet → Generation Your graph.
Terrain Mode Metaplanet → Generation Heightfield.
Planet Kind Metaplanet → Generation Rocky, or Gas Giant (Shader Sphere) for a gas giant.
Max Level Quadtree LOD 16 by default (about 5 m vertex spacing on Earth). It is a cap, not a cost: tiles only refine where the camera needs them.
Min Level Quadtree LOD Coarsest level. Keep it at 2–4.
Detail Scale Quadtree LOD 1 by default; 2 is sharper (about 4× the tiles), 4 suits cinematics, 0.5 background planets.

The console variable metaplanets.Lod.ScreenSpaceErrorPx (default 16) sets how many pixels a tile's vertex spacing may cover before it splits. Lower values add detail everywhere, at about 4× the tiles per halving. See Performance.

What you can build

From stylized low-poly worlds to cinematic-quality planets, the same graph workflow scales to your vision. Realistic planets has recipes for Earth-like worlds with rivers and climate, moons, Mars from real elevation data, volcanic worlds, jungle karst and gas giants.

Tips

  • Build in layers: continents first, then mountains, then hills, then metre-scale detail, then biomes.
  • Mask every layer. A mountain node applied everywhere looks artificial; masked by the simulation's MountainMask it reads as a range.
  • Watch the min / mean / max in the preview while tuning amplitude.
  • Keep biome masks 0–1 and saturated so downstream scattering stays stable.
  • Put small detail (under 2 m) into the height, not only the material, so collision, foliage and shadows agree with what you see.