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¶
| 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.
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.
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.
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.
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.
Create and assign a material to your planet to add visual detail:
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.
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.
7. Baked noise¶
Metaplanets can bake noise into textures. Here the same noise shown raw (quad) versus wrapped and lit 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.