Repository navigation
How to import into Blender
This workflow should work for any location, output zoom, width, or height generated with:
https://manticorp.github.io/unrealheightmap/
The important things to keep separate are:
- Heightmap resolution — the PNG width/height in pixels
- Horizontal scale — determined by latitude and output zoom
- Vertical scale — determined by the heightmap's normalisation mode
The easiest workflow is to export a 16-bit PNG with Normalisation set to None.
In Manticorp, choose whatever:
- Latitude / longitude
- Output Zoom
- Width
- Height
you require.
For Blender, use:
-
Output Format:
PNG 16 bit -
Normalisation:
None
With None, the stored 16-bit pixel value corresponds directly to elevation in metres:
pixel value 0 = 0 m elevation
pixel value 500 = 500 m elevation
pixel value 8849 = 8849 m elevation
Negative elevations are clipped to zero.
Manticorp uses Web Mercator map zoom levels.
At latitude L and output zoom Z, calculate the approximate metres per pixel as:
metres_per_pixel = 156543.03392 × cos(latitude) / 2^zoom
latitude should be converted to radians when using most programming/calculator cos() functions.
For example:
latitude = 46°
zoom = 12
gives approximately:
26.54 metres/pixel
Then calculate the physical size of the terrain:
terrain_width = (image_width - 1) × metres_per_pixel
terrain_height = (image_height - 1) × metres_per_pixel
Using width - 1 and height - 1 gives the distance between the centres of the first and last elevation samples.
For rough visual work, simply using:
image_width × metres_per_pixel
image_height × metres_per_pixel
is also usually close enough.
Go to:
Scene Properties → Units
Set:
Unit System: Metric
Unit Scale: 1.0
This makes:
1 Blender unit = 1 metre
If your heightmap is:
W × H pixels
ideally create a grid containing:
W vertices across X
H vertices across Y
For example:
| Heightmap | Grid |
|---|---|
| 505 × 505 | 505 × 505 vertices |
| 1001 × 1001 | 1001 × 1001 vertices |
| 2017 × 1009 | 2017 × 1009 vertices |
In Blender:
Shift+A → Mesh → Grid
Set:
X Subdivisions = image width
Y Subdivisions = image height
Then set the object's dimensions to the values calculated above:
X = terrain_width
Y = terrain_height
Then apply the scale:
Ctrl+A → Scale
The object's scale should now be:
1, 1, 1
You do not necessarily need one vertex per heightmap pixel.
For very large images, using the full raster resolution can create an unnecessarily huge mesh.
For example:
8129 × 8129 ≈ 66 million vertices
Instead, use a lower-resolution grid with subdivision, adaptive subdivision, Geometry Nodes, or tiled terrain.
Add a:
Displace Modifier
Create a new texture and load the Manticorp PNG.
Set the image's:
Color Space: Non-Color
This is important because the image contains numerical height data rather than colour information.
In the Displace modifier use:
Coordinates: UV
Direction: Z
Midlevel: 0
For a 16-bit PNG exported with Normalisation = None, use:
Strength: 65535
Midlevel: 0
This works because Blender internally reads the 16-bit image approximately as values between 0 and 1.
For example, an elevation of 1500 m is stored as:
1500
Blender reads that as approximately:
1500 / 65535
and the Displace modifier calculates:
(1500 / 65535) × 65535 = 1500
Therefore:
1500 m terrain elevation = Z 1500 in Blender
So the generic settings are:
| Setting | Value |
|---|---|
| Manticorp normalisation | None |
| Image format | PNG 16 bit |
| Blender colour space | Non-Color |
| Displace direction | Z |
| Midlevel | 0 |
| Strength | 65535 |
This works regardless of whether the terrain is Everest, a coastal area, hills, mountains, etc.
With the method above, Blender contains the absolute altitude.
For example, terrain ranging from:
720 m → 1940 m
will appear between:
Z = 720
Z = 1940
That is technically correct, but may be inconvenient for modelling.
The simplest solution is to move the completed terrain down by its minimum elevation.
For example:
minimum elevation = 720 m
Move the terrain:
Z = -720
The resulting mesh then ranges from:
0 → 1220 m
while preserving the correct vertical relief.
The vertical scaling is different if the heightmap has been normalised.
Suppose Manticorp reports:
minimum elevation = A
maximum elevation = B
Use:
Strength = B - A
Midlevel = 0
For example:
minimum = 420 m
maximum = 2170 m
then:
Strength = 2170 - 420
= 1750
The generated mesh will range from:
Z = 0
to:
Z = 1750
If you want absolute altitude again, move the entire terrain up by:
420 m
so it ranges from:
420 → 2170 m
For Blender, using Normalisation = None is generally simpler because the PNG values retain their direct meaning in metres.
Compare a recognisable terrain feature with the original map.
A useful convention is:
+X = East
+Y = North
+Z = Up
If north/south is reversed, flip the UV map vertically or rotate/flip the terrain as necessary.
This does not affect the elevation data.
Given:
L = centre latitude
Z = Manticorp output zoom
W = image width
H = image height
calculate:
R = 156543.03392 × cos(L) / 2^Z
where R is metres per pixel.
Then:
X = (W - 1) × R
Y = (H - 1) × R
Create a Blender grid:
W × H vertices
with dimensions:
X metres × Y metres
Then use:
Image Color Space: Non-Color
Displace:
Coordinates: UV
Direction: Z
Midlevel: 0
Strength: 65535
provided the Manticorp export is:
PNG 16 bit
Normalisation: None
That gives an approximately 1:1 horizontally and vertically scaled terrain mesh in metres, regardless of the selected location, output zoom, or image dimensions.