OpenHeightmap

A modular, editor-integrated heightmap generation toolkit for Unity 6. Procedural noise, hydraulic erosion, splatmaps, and live preview — all in one window.

Tools > OpenHeightmap  (Ctrl+Alt+H)

Quick Start

  1. Open Unity 6 with URP.
  2. Copy the Assets/OpenHeightmap folder into your project.
  3. Go to Tools > OpenHeightmap (or press Ctrl+Alt+H).
  4. Pick a preset from the Presets tab, or configure parameters manually.
  5. Click Generate. The heightmap appears in the live preview.
  6. Click Export to save it as PNG, RAW16, or EXR, or Apply to Terrain to write it to the active terrain in the scene.

If the scene has no terrain, Apply to Terrain offers to create one. Its size comes from New Terrain in the Noise tab: with Match Size To Resolution on, width and length follow the resolution (1025 → 1024 × 1024); turn it off to set them yourself. Auto Height (on by default) sets the height as a percentage of the width (Height (% of width), 40% unless a preset sets its own) so new terrains have natural proportions; turn it off to type a height. If the scene already has a terrain, Apply to Terrain updates that one and keeps its size; the New Terrain section says so, and warns when heightmap samples would be more than 4 units apart (for example a 513 map stretched over 64,000 units), which makes terrain look soft and flat. Each new terrain gets its own TerrainData asset in Assets/OpenHeightmap Generated. Generated files are kept outside the tool folder, so updating or removing the tool never touches your terrains.

Recommended Workflow

For best results, use RAW16 format throughout the pipeline:

OpenHeightmap (generate) → Export RAW16 → OpenStamper (load .raw) → Apply stamps → Export RAW16 → Unity Terrain (Import Heightmap)

RAW16 and PNG both store 16-bit height precision (65,536 levels); EXR stores full 32-bit floats. RAW16 is the format Unity's terrain Import Raw reads directly.

Features

6 Noise Algorithms

Perlin, Simplex, Voronoi, Worley, Value, Midpoint Displacement. Each with configurable parameters.

Hydraulic + Thermal Erosion

Full particle-based hydraulic simulation with sediment transport. Thermal erosion for slope rounding.

Live Preview

Colored heightmap preview with zoom, click-to-read height, a grayscale toggle (Color), a custom Gradient, and optional GPU rendering. The preview is rendered once per change, so sliders stay responsive. Batch (Noise tab) generates several seeds at once as thumbnails; click one to use it. The current heightmap is rebuilt automatically after a script recompile.

Splatmap Generation

Auto-generate terrain layer weights from height + slope. Configurable biome rules with preview.

10 Terrain Presets

Rolling Hills, Mountain Range, Island, Canyon, Plateau, Desert, Tundra, Volcanic, River Valley, Coastal Cliffs.

PNG Export

Export as 16-bit grayscale PNG (no terracing). The texture importer is set to single-channel (red), linear, uncompressed.

Processing Pipeline

Each generation run executes passes in strict order. Only enabled passes run.

Noise → Domain Warp → Hydraulic Erosion → Thermal Erosion → Gaussian Blur → Laplacian Smooth → Falloff → Normalize → Height Multiplier

Normalization stretches the result to fill [0, 1]. Height Multiplier is applied after it: below 1 lowers the whole terrain, above 1 raises lowlands and slopes with a smooth curve that never flattens the peaks.

Noise is sampled in a fixed reference space (512 units across the map), so the same settings give the same terrain at every resolution — a higher resolution adds detail instead of zooming out. Seed changes the terrain for every noise type.

Noise Algorithms

Noise Perlin Noise

Classic gradient noise. Produces smooth, organic undulations. Good general-purpose noise for rolling terrain. Uses improved Perlin permutation table with fade function 6t^5 - 15t^4 + 10t^3.

Best for: Rolling hills, base terrain layers, large-scale features.
Noise Simplex Noise

Gradient noise on a simplex grid instead of a square grid. Fewer directional artifacts than Perlin at high frequencies. Better performance in 2D+.

Best for: Organic terrain, mountain bases, anything Perlin does but with fewer grid-aligned artifacts.
Noise Voronoi (Worley) Noise

Cell-based noise that computes distances to nearest feature points. Produces cell-like patterns.

Return TypeEffect
CellValueRandom value per cell (flat regions)
DistanceDistance to nearest point (bowl shapes)
Distance2Distance difference between 1st and 2nd nearest (ridge lines, crater edges)
Best for: Cratered terrain, cliff formations, volcanic landscapes.
Noise Worley Noise

Variant of Voronoi with hash-based point placement (no floating point artifacts). Returns distance fields.

Return TypeEffect
F1Distance to nearest point
F2Distance to second nearest
F2-F1Ridge/canyon patterns
F1NormalizedInverted distance (peaks at cell centers)
Noise Value Noise

Random value at each grid vertex, interpolated with Hermite smoothing. Produces very smooth, predictable results. No gradient artifacts.

Best for: Smooth plains, gentle undulations, plateau surfaces.
Noise Midpoint Displacement

Fractal subdivision: starts with 4 random corners, recursively subdivides with randomized midpoints. The Roughness parameter controls how much displacement decreases per subdivision level.

Best for: Mountain ridges, jagged fractal terrain, mountain ranges.

Erosion Simulation

Erosion Hydraulic Erosion

Particle-based simulation. Each particle starts at a random position, flows downhill under gravity, picks up sediment (erosion) and deposits it when velocity decreases. Erosion is spread over a small brush so it carves channels rather than pits. This is the single most impactful pass for realism.

ParameterWhat It DoesRecommended Range
IterationsErosion amount, in hundreds of droplets on a 513 map (200 = 20,000). The droplet count scales with map area so results look the same at any resolution.100-500
MaxLifetimeMax steps per particle before it dies20-50
InertiaHow much momentum carries vs. gravity direction. Higher = smoother channels0.01-0.1
GravityAcceleration downhill. Higher = deeper channels2-10
EvaporationRateWater loss per step. Higher = shorter rivers0.01-0.05
DepositionRateHow fast sediment drops when velocity slows0.1-0.5
ErosionRateHow fast terrain is carved under particles0.1-0.5
Erosion Thermal Erosion

Slope-based material displacement. Material slides downhill when the slope exceeds the TalusAngle threshold. Produces natural rounding of peaks and filling of valleys.

ParameterWhat It Does
IterationsNumber of passes (10-30 typical)
TalusAngleSlope threshold before material moves (0.005-0.02). Measured per 513-map pixel, so it behaves the same at every resolution.
CMaterial transfer constant (1.0 = standard)

Filters

Filter Gaussian Blur

Convolution-based blur using a Gaussian kernel. KernelSize must be odd (auto-corrected). Sigma controls blur spread. Multiple passes compound the effect.

Filter Laplacian Smoothing

Each vertex moves toward the average of its 4 neighbors by Strength factor. Good for removing high-frequency noise without losing large-scale shape.

Filter Falloff Mask

Multiplicative mask that darkens edges. Essential for island generation.

TypeShape
CircularRadial falloff from center (standard island)
SquareBox falloff (flat center, sharp edges)
DiamondManhattan distance falloff
GaussianSmooth bell-curve falloff (most natural)

Power — curves the falloff. Higher = steeper drop at edges.
Offset — shifts where the falloff begins. Higher = more flat center area.

Filter Domain Warping

Pushes the terrain around using a second, seeded noise field. Breaks up regularity and produces organic, non-repeating geological formations. Applied before erosion. Strength is the maximum shift as a fraction of the map width (0.02 ≈ 2%); Frequency uses the same units as the noise Scale.

Splatmaps

Auto-generate terrain layer weights from height and slope. Each biome rule defines a height range and a maximum slope in real degrees (worked out from the terrain's height-to-width ratio: the active terrain's, or the New Terrain size). Weights are smooth-stepped for natural blending. Where a spot is too steep for every rule at its height, the height match is kept rather than falling back to the first layer.

Height Weight sets how sharply height bands separate (0 = height ignored). Slope Weight sets how strictly Max Slope is enforced (0 = slope ignored, 1 = a layer fades out over 10° past its Max Slope).

LayerDefault HeightMax SlopeColor
Water0 – 15%90°█ Blue
Sand15 – 25%20°█ Tan
Grass25 – 55%30°█ Green
Rock55 – 80%60°█ Brown
Snow80 – 100%90°█ White

Click Generate Splatmap in the Splatmap tab to see a color-coded preview (toggle Splat in the toolbar to switch back to the heightmap). Generating a new heightmap clears the splatmap. Apply to Terrain writes it too: it is resampled to a power-of-two alphamap (513 → 512), each splat rule gets a solid-colour TerrainLayer asset in Assets/OpenHeightmap Generated/TerrainLayers (reused on later applies). Applying again, for example after switching presets, swaps those generated layers for the current rules' colours. A layer you assigned yourself (such as a real texture) keeps its slot and is never replaced.

Presets

Each preset keeps your current Resolution and Seed, and sets the New Terrain Height (% of width) to a value that suits it, so gentle presets don't come out mountainous. You can change that slider afterwards. Presets also set the Splatmap rules: Canyon, Plateau, Desert Dunes, Tundra and Volcanic bring their own layers and colors (red rock, sand, moss, ash and so on), and the rest use the default water, sand, grass, rock and snow layers. Edit the rules freely afterwards; Reset to Defaults in the Splatmap tab goes back to the default layers.

Rolling Hills
Perlin, 4 octaves, light thermal erosion and smoothing. Broad, gentle hills. Suggested height: 8% of width.
Mountain Range
Simplex, 8 octaves, hydraulic + thermal erosion, warped ridgelines. Large eroded mountain masses. Suggested height: 30% of width.
Island
Perlin + circular falloff, hydraulic + thermal erosion. A single island with beaches and a mountainous centre. Suggested height: 15% of width.
Canyon
Voronoi cell edges as gorges, high Height Multiplier for flat mesa tops, strong warping and erosion. Mesas cut by winding gorges. Splatmap: gorge sand, red rock, sandstone tops. Suggested height: 12% of width.
Plateau
Value noise, raised with Height Multiplier, heavy blur and smoothing. A flat tableland with escarpments. Splatmap: lowland grass, rock escarpments, upland grass. Suggested height: 12% of width.
Desert Dunes
Simplex, few octaves, warped and heavily blurred. Low, smooth, wind-shaped undulations. Splatmap: three shades of sand. Suggested height: 5% of width.
Tundra
Perlin, low height, thermal erosion and blur. Flat cold lowland with shallow lakes. Splatmap: water, gravel, tundra moss, snow. Suggested height: 6% of width.
Volcanic
Worley F1Normalized at a low scale, erosion and slight warping. A few large volcanic cones. Splatmap: water, ash, scrub, basalt, snow. Suggested height: 25% of width.
River Valley
Voronoi cell edges as valley floors, warped to meander, heavy erosion and blur. Rounded hills between winding river valleys. Suggested height: 12% of width.
Coastal Cliffs
Simplex + strong offset circular falloff, erosion. A landmass that drops steeply into the sea. Suggested height: 12% of width.

API Reference

INoiseProvider
public interface INoiseProvider
{
    string Name { get; }
    float Sample(float x, float y, int seed = 0);
}

All noise algorithms implement this interface. Returns value in [-1, 1] range (except MidpointDisplacement which returns [0, 1]).

HeightmapGenerator
var generator = new HeightmapGenerator();
var parameters = new HeightmapGeneratorParameters { ... };
HeightmapData result = generator.Generate(parameters);

Main entry point. Orchestrates the full pipeline from noise to normalized output. Set generator.Progress = (stage, progress) => { ... } to receive progress updates.

HeightmapData
HeightmapData hm = new HeightmapData(513);
float h = hm.GetHeight(x, y);
float hBilinear = hm.GetHeightBilinear(u, v); // 0-1 UV coordinates
float[] flat = hm.ToFlatArray();
HeightmapData clone = hm.Clone();

Core data wrapper. Use GetHeightBilinear for smooth UV-based sampling.

HeightmapExporter
HeightmapExporter.Export(heightmap, "/path/to/output.png", ExportFormat.PNG);
HeightmapExporter.Export(heightmap, "/path/to/output.raw", ExportFormat.RAW16);

Writes PNG (16-bit grayscale), RAW16 or EXR. Paths normally come from a save dialog, which already asks before overwriting; pass confirmOverwrite: true to ask again. Auto-configures the texture importer when saving inside the project.

TerrainApplier
string status = TerrainApplier.Apply(heightmap, new NewTerrainSettings(), "Assets/MyTerrains", "My Terrain");

Writes a heightmap (and optional splatmap) to the active terrain, or creates a new one. Used by both OpenHeightmap and OpenStamper. Call it outside OnGUI (for example from EditorApplication.delayCall) because it can show dialogs.

File Structure

Assets/OpenHeightmap/
├── Documentation/
│   └── Index.html              ← this file
├── Editor/
│   ├── OpenHeightmapWindow.cs  Main EditorWindow (6 tabs + preview)
│   ├── PreviewRenderer.cs      CPU / GPU preview (rendered once per change)
│   ├── HeightmapExporter.cs    PNG / RAW16 / EXR export
│   ├── TerrainApplier.cs       Apply to Terrain (shared with OpenStamper)
│   ├── OpenHeightmap.Editor.asmdef
│   └── Presets/
│       └── TerrainPresets.cs   10 terrain presets
├── Runtime/
│   ├── HeightmapData.cs        Core float[,] wrapper
│   ├── HeightmapGenerator.cs   Pipeline orchestrator
│   ├── OpenHeightmap.Runtime.asmdef
│   ├── Noise/
│   │   ├── INoiseProvider.cs   Interface
│   │   ├── PerlinNoise.cs
│   │   ├── SimplexNoise.cs
│   │   ├── VoronoiNoise.cs
│   │   ├── WorleyNoise.cs
│   │   ├── ValueNoise.cs
│   │   └── MidpointDisplacement.cs
│   ├── Erosion/
│   │   ├── HydraulicErosion.cs
│   │   └── ThermalErosion.cs
│   ├── Filters/
│   │   ├── GaussianBlur.cs
│   │   ├── LaplacianSmooth.cs
│   │   ├── FalloffGenerator.cs
│   │   └── DomainWarping.cs
│   ├── Sampling/
│   │   ├── PoissonDiskSampler.cs
│   │   └── CellularAutomata.cs
│   └── Splat/
│       └── SplatmapGenerator.cs
└── Shaders/
    ├── PreviewCompute.compute  GPU heightmap-to-color
    └── PreviewShader.shader    URP preview material

Companion Tool: OpenStamper

OpenHeightmap has a companion tool called OpenStamper for stamp-based terrain compositing. OpenStamper lets you layer procedural features (craters, mountains, ridges, rivers, etc.) onto existing heightmaps using 8 blend modes.

OpenStamper depends on OpenHeightmap — it uses HeightmapData, HeightmapExporter, and ExportFormat at both runtime and editor level. Install this asset first before adding OpenStamper.

Recommended pipeline: Generate in OpenHeightmap → Export RAW16 → Load into OpenStamper → Stamp → Export RAW16 → Import to Unity Terrain.

Open via Tools > OpenStamper (Ctrl+Alt+S).