Skip to content

Commit 56ac63d

Browse files
author
Roberto De Ioris
authored
Create Landscape_API.md
1 parent 9ad931f commit 56ac63d

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

docs/Landscape_API.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# The Landscape/Terrain API
2+
3+
Terrains in UE4 are special actors built over the 'heightmap' concept.
4+
5+
Each Terrain is a grid of components (ULandscapeComponent). Each component is mapped to a texture holding heights data.
6+
7+
The landscape component concept is really important as it impacts performance and quality of the result. A component is the minimal render unit of a terrain
8+
(so it is the minimal geometry that can be culled both from the rendering and collisions point of view).
9+
10+
A brief explanaton on landscape components is available here: https://docs.unrealengine.com/latest/INT/Engine/Landscape/TechnicalGuide/#componentsections
11+
12+
To build a new terrain (or Landscape in UE4), you need to get a heightmap. From this heightmap, the UE4 api will generate
13+
the textures mapped to components.
14+
15+
Heightmaps are simple arrays of unsigned 16bit values (0 to 65535 with 32768 value considered the 'sea level').
16+
17+
In Python (for performance reason, and to simplify integration with numpy) heightsmap are represented as bytearray's (so you eventually need to recast them).
18+
19+
# Creating a new Landscape
20+
21+
We start by creating a heightmap with random values:
22+
23+
```python
24+
import unreal_engine as ue
25+
import struct
26+
import random
27+
28+
width = 1024
29+
height = 1024
30+
heightmap = []
31+
32+
# fill the heightmap with random values
33+
for y in range(0, height):
34+
for x in range(0, width):
35+
heightmap.append(random.randint(0, 65535))
36+
37+
data = struct.pack('{0}H'.format(width * height), *heightmap)
38+
```
39+
40+
Now 'data' is something we can use for the landscape api
41+
42+
Before filling up a landscape, we need to spawn it:
43+
44+
```python
45+
from unreal_engine.classes import Landscape
46+
47+
new_landscape = ue.get_editor_world().actor_spawn(Landscape)
48+
```
49+
50+
Note: do not run the previous script, as the editor does not like uninitialized terrains. (read: it will brutally crash)
51+
52+
Now it is time to fill the terrain with the heightmap data we created before. We need to choose how many components we need (the grid resolution)and how many quads are required for each component
53+
(each component geometry is formed by simple quads primitives).
54+
55+
Once we know how big the terrain will be, we can expand/adapt the heightmap accordingly using a special UE4 api function:
56+
57+
```
58+
unreal_engine.heightmap_expand(data, original_width, original_height, terrain_width, terrain_height)
59+
```
60+
61+
This function will generate a new heightmap with the optimal dimension for the landscape.
62+
63+
64+
```python
65+
import unreal_engine as ue
66+
import struct
67+
import random
68+
from unreal_engine.classes import Landscape
69+
70+
width = 1024
71+
height = 1024
72+
heightmap = []
73+
74+
for y in range(0, height):
75+
for x in range(0, width):
76+
heightmap.append(random.randint(0, 65535))
77+
78+
data = struct.pack('{0}H'.format(width * height), *heightmap)
79+
80+
quads_per_section = 63
81+
number_of_sections = 1
82+
components_x = 8
83+
components_y = 8
84+
85+
fixed_data = ue.heightmap_expand(data, width, height, quads_per_section * number_of_sections * components_x + 1, quads_per_section * number_of_sections * components_y + 1)
86+
87+
landscape = ue.get_editor_world().actor_spawn(Landscape)
88+
landscape.landscape_import(quads_per_section, number_of_sections, components_x, components_y, fixed_data)
89+
landscape.set_actor_scale(1,1,1)
90+
```
91+
92+
You should have noted that instead specifying the quads per component we are using the 'section' concept.
93+
94+
The truth is that UE4 allows another level of subdivision for giving better control over optimizations (LOD, mipmapping...). More details here:
95+
96+
https://docs.unrealengine.com/latest/INT/Engine/Landscape/TechnicalGuide/#componentsections
97+
98+
You can have 1 section (1x1 quad) or 2 (2x2 quads). Other values are not supported.
99+
100+
Even the number of quads is related to textures size, so valid values are: 7x7, 15x15, 31x31, 63x63, 127x127, 255x255 (note the off-by-one weirdness, as all of the terrain tools works with max value on not the size)
101+
102+
Note that you need to carefully choose the size of the terrain as well as the heightmap:
103+
104+
https://docs.unrealengine.com/latest/INT/Engine/Landscape/TechnicalGuide/index.html#calculatingheightmapdimensions
105+
106+

0 commit comments

Comments
 (0)