GAME DEVELOPMENT

How to Create Your Own Open-World Game Terrain in Unreal Engine

Creating real-life replicas of your favorite terrain, made simple

Ikshura Tachintha
Published in
14 min readFeb 24, 2021

--

Creating an open-world for a game or any other reason should be sounding extremely exhausting or more or less impossible for most of you. But with the rapidly developing community base of popular game engines, this task has become simply achievable with loads of new plugins and asset packages that arrive at the market regularly.

The workaround of this approach will include the use of QGIS, a bit of Photoshop, or any other photo editing software, and mainly the Unreal Engine (4.24 or higher is preferred). Additionally, I have to mention that this workflow is not optimal for creating urban cities with buildings. This workflow concentrates on creating realistic replicas of natural surroundings (areas that mostly consist of mountains, water bodies, vegetation, and so on). But at the end of the article, I will mention a way that you can also add building structures to the terrain after following this approach. That method is not very flexible though, and not really recommended if you are going for a professional-level terrain generation, but I will mention it for the sake of completion.

USGS Earth Explorer. Source: USGS.

1. Gathering the raw data

If you are planning to create a replica from the real world the first step is to find a quality set of GIS data of the area you are planning on creating. For that, it is recommended to use a reliable source to download the data such as USGS-Earth explorer or USGS National map viewer. These two websites contain rich data of USA territories but not for other regions. There are many more sources you can find all over the internet handled by the government institutions of each country. Mainly you have to obtain two data types: the heightmap and the satellite image covering your area of interest, both in GeoTIFF format.

When downloading the required heightmap and satellite images you may notice multiple GeoTIFFs being downloaded. If so, you don’t have to worry since if your area of interest is large, the heightmap and satellite image of that area might come as multiple tiles of heightmap/satellite image which we will combine together later on using QGIS. And also remember, the better the resolution, the better the result! Further, you can download the ESRI shapefiles representing roads, railways, and building footprints data of that area from that same source if you intend on adding roads, rails, and buildings respectively. Also, it is possible to obtain these shapefile data alone from OpenStreetMap as well.

2. Processing the raw data

Next up you have to work with QGIS to process the downloaded raw data. You can simply drag and drop the heightmap and satellite image data into the QGIS workspace area and the data will load and be displayed on the canvas.

I recommend first drag and drop either the heightmap tiles or the satellite image tiles only for further convenience. If you have multiple tiles of data, drag and drop all of them and the tiles will load on the canvas according to their positions.

Now in order to combine the tiles and create a single image/layer, first you should select all the tiles owned by either the heightmap or the satellite image from the layers window on the left bottom of the screen. Now in the main menu, select Raster > Miscellaneous > Build Virtual Raster.

Photo by R. Christian Anderson on Unsplash

In the ‘Build Virtual Raster’ window:

  • Click the ‘…’ button to the right of ‘Input Source’ and select either all of the heightmap tiles or all of the satellite image tiles only as the input tiles to be combined.
  • Set the ‘Resolution’ to ‘Highest’.
  • Make sure ‘Place each input file into a separate band’ is unchecked.
  • Set the ‘Override projection for the output file [optional]’ to your ‘Project CRS’.
  • Leave the ‘Resampling algorithm’ as ‘Nearest Neighbour’ for the heightmap and change it to ‘Bilinear’ when doing this process with the satellite image.
  • Click ‘Run’.

You can repeat this process for both the heightmap data and satellite image data to get the combined images for both of them. After creating the virtual rasters, you can remove the raw data (the tiles) from the QGIS layers by selecting the tiles on the layers window > right-click > remove layer. You only have to keep the two processed Virtual Rasters for each heightmap and the satellite image.

Now if you are planning on using the shapefiles for the roads, rails, and buildings, you can load them as well into QGIS as follows. When you download the ESRI shapefile, you might notice that there are approximately 4 files with the exact same file name but different extensions. These extensions usually are .shp, .shx, .dbf, and .prj. There can be even more different extensions under a single shapefile. And if you want to load the data into QGIS, you have to drag and drop the .shp file only into the workspace. Then you will be able to load the shapefile into the QGIS canvas on top of the already loaded heightmap and satellite image. You can adjust the order of the layers on the layers panel by dragging layers up and down.

After getting all the data loaded into QGIS, you can now decide the extent you are planning on creating the terrain. After deciding you can draw a square/rectangle on top of the data layers which will be used as a reference to cropping the raw data to obtain the final set of data. To create this reference area,

  • Click the ‘New Shapefile Layer…’ icon on the main menu.
  • Give it a useful filename.
  • Select ‘Polygon’ from the ‘Geometry Type’
  • Click ‘OK’.
  • On the main menu, click ‘View’ > ‘Toolbars’
  • Make sure the check-box next to ‘Shape Digitizing Toolbar’ is checked.
Landscape creation example. Source: Unreal Engine Forums.

Now to draw the area,

  • Make sure your new layer is selected in the Layers window.
  • Select the ‘Toggle Editing’ icon on the 2nd row of the main toolbar.
  • Click the small arrow on the ‘Create Rectangle’ icon in the ‘Shape Digitizer Toolbar’ and from the drop-down list.
  • Select ‘Add Rectangle from Extent’.
  • Left-click and release where you want the top left corner of your reference area.
  • Drag the mouse to where you want the bottom-right corner and right-click to stop drawing.
  • A ‘Feature Attributes’ window will appear with an ‘ID’ for the shape.
  • You can enter any integer number you want here, the entered number doesn’t matter.

After creating this reference area, you can save the two Virtual Raster Layers by cropping them during the process. First, let’s save the Virtual Raster Layer of the heightmap. To do this, right-click on the heightmap Virtual Raster Layers > Export > Save As

In the ‘Save Raster Layer As…’ window:

  • Set the ‘Output mode’ to ‘Raw Data’.
  • Make sure ‘Format’ is set to ‘GeoTiff’
  • Use the ‘…’ button to the right of the ‘File name’ field, browse to a folder to save your layer and give it a file name.
  • Make sure the ‘CRS’ field is set to your ‘Project CRS’.
  • To crop the heightmap using our reference area, under ‘Extent’, click ‘Calculate from Layer’ and select the layer with your reference area.
  • Click ‘OK’.

In this same way, you can crop and save your satellite image, but there is one small difference in the saving process.

In the ‘Save Raster Layer as…’ window:

  • ‘Output mode’ should be ‘Rendered Image’ instead of ‘Raw Data’ (because we only want RGB channels).

The next step is to crop the vector layers (roads, rails, and building layers) according to the reference area we previously created. To do that, on the main menu, select Vector > Geoprocessing Tools > Clip.

Example of working with vectors in Unreal Engine 4. Source: YouTube.

In the ‘Clip’ window:

  • Set ‘Input Layer’ to one of your vector layers.
  • Set ‘Overlay Layer’ to the layer containing your reference area.
  • Click ‘Run’.

You can repeat this process for all the vector layers you have (for roads, rails, buildings) and you will get the final vector layers that will be used for the terrain generation. To save the clipped layers, right-click on one of the ‘Clipped’ layers > Export > Save Features As.

In the ‘Save Vector Layer as…’ window:

  • Set ‘Format’ to ‘ESRI Shapefile’.
  • In ‘File name’ navigate to a folder and give your vector a filename.
  • Set ‘CRS’ to ‘Project CRS’.
  • Under ‘Geometry’, change ‘Geometry Type’ to ‘LineString’ for the roads and rails vector files, and change to ‘Polygon’ when saving the building vector file.
  • Click ‘OK’.

Follow the above steps and you will be able to save the processed vector files as well.

3. Creating the masks for vegetation/water bodies/dirt areas

After the raw data are processed through QGIS you have to use photo editing software to make some filtered masks using the finalized satellite image. These masks should be greyscaled images that highlight greenish areas (areas covered with vegetation) to create the vegetation mask, areas covered with water for the waterbody mask, and also areas covered with dirt if any types of those areas are present in your interested areas for the dirt mask. In the greyscaled images, the highlighted portion should be white-ish and the un-highlighted areas should be black-ish. An example of a vegetation mask is shown below.

Original satellite image

As shown below, you can create several masks for vegetation areas, areas with water bodies, and areas with dirt. After these steps are done you can jump on to start the creation of the terrain.

The mask created to highlight vegetation areas

4. Creating the final terrain

Here I have been using a plugin named TerraForm Pro. This plugin allows you to import heightmaps of GeoTIFF format and transform them into landscapes and also allows you to import line shapefiles as splines to represent roads and railways. I have found this plugin comes in handy when creating professional-level natural terrains. To add the plugin to Unreal Engine, paste the plugin content folder into the plugins folder under Unreal Engine installation. (Usually, it’s located at C: > Program File > Epic Games > UE_4.25 > Engine > Plugins)

Also, I have been using Procedural Landscape Ecosystem (PLE) asset package which in turn has helped me to ease out many time-consuming tasks that have to be done manually such as creating landscape layers and creating realistic landscape materials. Also, this asset package includes two finely crafted tree meshes (pine tree models and birch tree models) and also a smooth road material that will be useful further on.

For the final steps, you have to open Unreal Engine and you will get a popup mentioning ‘New Plugins are Available’, under that click ‘Manage Plugins’. Then the plugins window will popup and you have to tick the ‘Enable’ option under the details of the TerraForm plugin. Then it will require to restart Unreal Engine to enable the plugin.

After enabling the TerraForm Pro plugin, Select the TerraForm mode from the ‘Modes’ Panel. Click the ‘Activate TerraForm’ button. You have to provide a reference name and the Activation key in order to activate the plugin. Upon activation, there will be 3 options appearing under TerraForm menu. Click on the first option named ‘Import DTM as Landscape’. Then you have to browse and select the final heightmap image that we saved after the process inside QGIS. There are no key import options to be adjusted when importing the image for now. The plugin will take some time and will load the heightmap as a perfect landscape where your character will be able to freely roam if you are using the Third Person project template. After importing you can apply a landscape material which either you manually create or are available in the PLE asset package if you are using it.

Then you can assign the masks you have created for each relevant landscape layers that have been already created inside the PLE package which make things much more convenient. To assign the masks, first go to ‘Landscape’ mode, then select ‘Paint’. Under ‘Target Layers’, you’ll find the ‘Procedural Landscape Ecosystem’ layer list if you are using PLE. Else you have to make them manually which can be quite time-consuming. If you have PLE. initially, each ‘Layer’ will be set to ‘None’. Click the drop-down arrow in the field under the ‘Grass_plane’ layer name and select ‘Grass_plane_Layerinfo’. Repeat this for the other layers in the Procedural Landscape Ecosystem.

To assign the masks, select the relevant layer (for example if you are going to assign the vegetation mask, either select the ‘Pine_forest_a’ layer or the ‘Birch_forest_a’ layer from the ‘Layers’ list under ‘Target Layers’.) Right-click on the layer and select ‘Import from File’. In the browser window that appears, select the relevant .png mask according to the selected layer and click ‘Open’.

Example of terrain created in TerraForm Pro. Source: TerraForm Pro.

Next up, either you can spawn the trees on the areas covered by the vegetation mask or jump on to the step of adding roads and rails through the shapefiles. I recommend going for adding roads step before spawning trees since if trees are spawned first and the roads are added afterwards, there will be instances where some trees will be spawned on the roads which can be fixed by resimulating the tree spawner tool which is technically known as the procedural foliage spawner. But this ‘Resimulate’ option is done by a single button click even though it may take some time to process depending on the extent of your terrain. Therefore it’s fine even if you chose to spawn trees first before adding roads.

So to add the roads, click on the second option in the TerraForm menu, ‘Import Lines as Landscape Splines’. (The TerraForm menu can be opened by clicking ‘TerraForm Ed Mode’ in the modes panel) Now you will get a file browser window where you have to browse to the cropped road shapefile that we saved in the second step. And make sure to select only the .shp file. In the ‘Vector Line Import Options’ for the landscape spline to be created:

  • Set the ‘Spline Width’ to ‘500 Centimetres’. (This will be the approximate width of the resulting road, so you can enter any width you prefer)
  • Set the ‘Side Falloff’ and ‘End Falloff’ values to ‘200 Centimetres’.
  • ‘Layer’ should be ‘Global_ground_a’. (Hit the ENTER key after typing the layer name to ensure it’s applied.)
  • Make sure ‘Raise Terrain’ and ’Lower Terrain’ are both checked.
  • ‘SM_roads_a’ is the mesh we applied to the segments. (This is coming from the PLE package)

Now click import and you will be able to see the road network blended with your landscape properly. Now repeat this same step to import the rails. But remember to change the ‘Spline Width’ to a lesser value since railways aren’t wide as roads and create of find a suitable material to be applied to mesh segments instead of the ‘SM_roads_a’ which is the material for roads. (Here make sure to first import roads and then the rails since naturally, the rails overlap the roads at the intersections and not vice versa.

Finally, in order to spawn the trees, you can use the procedural foliage tool inside Unreal Engine to create custom procedural spawners and assign the tree models that you want to be spawned. If you are using the PLE package, there are built-in spawners for the Pine and Birch trees. If not, it’s not that difficult or complex to create a custom procedural foliage spawner by yourself.

Example of terrain created with PLE. Source: GFXDomain Forums.

If you are using the PLE package, in the content browser, browse to where the procedural foliage spawners are, and when choosing which spawner to use, you have to take into account the layer to which you assigned your vegetation mask previously. (If you assigned the vegetation mask to ‘Pine_forest_a’ layer, chose a Pine forest spawner and if you assigned the vegetation mask to ‘Birch_forest_a’, use a Birch forest spawner since a spawner will follow the relevant area covered by its relevant landscape layer). As you might have noticed the function done by assigning the mask to a landscape layer is to highlight which areas are under that specific landscape layer. And we will be spawning the trees on the area which is covered by the layer to which the vegetation mask was assigned.

After figuring out which procedural foliage spawner to use, drag and drop that foliage spawner from the content browser onto the viewport (on to the map). You will notice the spawner is a cube. Now you have to adjust the position and the scale of the cube so that this cube covers the whole map. After it’s done, scroll down the ‘Details’ panel to the ‘Procedural Foliage’ section and de-select ‘Allow Static Mesh’ and click ‘Resimulate’ button to run the spawner. After a little while, you will be able to see the trees being spawned on the areas which were highlighted through your vegetation mask. You can adjust the tree heights, tree densities, and much more settings by double-clicking on the procedural spawner and tweaking its properties.

This concludes the basic steps of the Open-World Terrain generation process inside Unreal Engine. But earlier I mentioned that this method doesn’t support adding buildings and such structures from GIS data and also I mentioned that I will mention an alternate way I found out after trying out many optional approaches.

If you plan on adding buildings, I have found a method which you can use Blender-GIS plugin for Blender which can be used to load the same heightmap into Blender and create a 3D terrain similar to the initial terrain in Unreal Engine. Then the plugin also has an option to load building footprint shapefile to create 3D buildings with the help of building height data encoded inside the shapefile. And these buildings can be placed on top of the Blender terrain which we created previously so all the buildings will be well blended into the landscape. Then you can texture-out the buildings inside Blender and you can export the buildings layer as a .fbx into Unreal Engine.

The downside of this approach is that the whole building layer will be in a single static mesh and hence not flexible to deal with when considering customizing individual buildings inside the Unreal Engine. And also there can be mild alignment issues of the buildings with the Unreal Engine terrain since although we are using the same heightmap to create the terrains, the two platforms (Unreal Engine and Blender) may process the data slightly differently.

Source: unrealengine.com.

Most of you who are not experts in these fields might have found this article a bit difficult to understand. But this is a perfect pipeline I have been using and found it easy to work with. If you get used to working with Unreal Engine I believe this article would have been an easy follow-up tutorial. This is an image of a terrain I made using this approach.

Any questions, clarifications, or feedback is highly appreciated and I thank you for the time spent reading this article. Be safe and have a good day!

--

--

Ikshura Tachintha
SUPERJUMP

Undergrad @ University of Moratuwa, Faculty of IT — A gaming enthusiast ❤