Creating and Using Custom Heightmaps and Layers

Landscape_Example_Image.png

Sometimes your Landscape will require that you use external programs to create both the height map and layers that are needed. UE4 does accommodate this style of workflow and everything that you need to be aware of when using a workflow like this is in this guide. If this is your first time using the Landscape tools, you might want to check out the Landscape Overview first as what is going to be covered here may be too advanced for new users.

Layers

Landscape Layers are special textures that help to break up the look and feel of the Landscape.

Layer Formats

  • Landscape layers can be imported from external programs via implementation of the ILandscapeHeightmapFileFormat and ILandscapeWeightmapFileFormat interfaces. The editor's existing support for image-based importing has been converted to use this interface and is still fully supported. Images for the built-in formats are still required to be grayscale, 8 bits per pixel, single channel files in either .PNG or .RAW format. If you are creating layers in Photoshop, you should use the following settings when creating a new document:

    Photoshop_Layer_Example.png

Layer Import

Importing Layers that were made in an external application is a simple process but you first need to make sure that you have a few things set up in order to get everything to work smoothly.

  1. You first need to make sure that you have a Landscape to work with. If you do not have one now, please create one.

  2. Once your Landscape has been created, you need to make a new material for it. For this example, we will be making a very simple Material but this Material could easily be expanded upon if needed. The Material that you need to setup should look something like this.

    Landscape_Simple_Shader.png

  3. Once the material is created, apply it to the Landscape Actor so that you have something that looks like this.

    Landscape_Applied_Material.png

  4. Now with the material applied, it is now time to add some Layer Info to our Landscape Actor. Add a Layer Info object for each layer you are going to have. For this example, we are going to have three. To read more about Layer Info objects, check out the Layer Info Objects section of the Paint Mode document.

    Landscape_Create_Layer.png

  5. When completed, your Target Layers section should look like this.

    Landscape_Target_Layers.png

  6. Now it is time to import our layer. To do this, all you need to do is Right-Click on the Target Layer you want to import a layer for and then select the layer that you want to import from the dialogue box that pops up.

    Landscape_Import_Layer_Option.png

  7. If your layers are not output at the correct size, you will receive the following warning.

    Landscape_Layer_Import_Error.png

    To fix this issue, you need to determine how big the Landscape layer you are trying to import over is supposed to be. To find this out, you can export any layer by Right-Clicking on the Target Layer you want to look at then select Export from the dialogue box that pops up. Once you do that, you will be asked to save the layer file somewhere on your PC. After the file has been saved, you can then open it up to determine what size your layers should be.

Height Maps

Using external tools to create a base heightmap to work off of inside Unreal can be a good way of speeding up the Landscape creation process. The base heightmap can then be imported, cleaned up, or modified using the editing tools inside Unreal Editor to customize the Landscape and make it better fit into the world and desired game play.

Height Map Formats

When exporting heightmaps from external programs, only the following formats are usable inside UE4.

  • 16-bit, grayscale PNG file.

  • 16-bit, grayscale .RAW file in little-endian byte order.

If you are using Photoshop to export your heightmap from make sure that you set up your new images like the following. Photoshop_HeighMap_Example.png

When making a heightmap in an external application, a value of White (255 in all channels) will represent the highest point on your height map and a value off Black (0 in all channels) will represent the lowest point on your heightmap.

Importing Custom Heightmaps

Importing custom Heightmap is quite simple. The process is initiated from the New Landscape section of the Landscape Modes panel. To active it, select the radio box labeled Import from File to expose the ability to import a heightmap from a file.

Landscape_Import_Section.png

To select a Heightmap to import, press the button next the box that says "Please specify a heightmap" and then select your Heightmap using the file browser.

Landscape_Import_Section_Button.png

Now let's try importing a custom height map. For this example, we will be using the image below so make sure that you do load it.

Make sure you right-click Save as on the image to download it to your PC.

Landscape_Test_HM.png

Once you have the heightmap saved to your PC, it is now time to use it in the Landscape tools.

  1. Open up the Landscape tool and go into Manage Mode.

    Landscape_Open_Manage_Mode.png

  2. Selected the option to Import from File.

    Landscape_Import_Section.png

  3. Select the Heightmap you want to import from the Heightmap File section.

    Landscape_Import_Section_Button.png

  4. When the above has been completed, press the Import button to create a new Landscape based off of your heightmap.

    Landscape_Press_Import.png

Before pressing the Import Button: Landscape_Import_Heightmap_Setup.png

After pressing the Import Button: Landscape_Import_Heightmap_Finsh.png

Now you have a new Landscape to work with that is based off the Heightmap that you just imported.

Writing A Custom Importer

  • In order to create new importers, your plugin should create instances of objects implementing ILandscapeHeightmapFileFormat and ILandscapeWeightmapFileFormat, and register those objects with ILandscapeEditorModulemodule::RegisterHeightmapFileFormat and ILandscapeEditorModulemodule::RegisterWeightmapFileFormat, respectively.

  • Implementing the ILandscapeHeightmapFileFormat interface in a plugin requires overriding the following functions:

    1. const FLandscapeFileTypeInfo& GetInfo() const: Returns type information indicating which file types this class handles, and whether or not exporting is supported.

    2. FLandscapeHeightmapInfo Validate(const TCHAR* HeightmapFilename) const - Validates the named file, or rejects it and returns an error code and message.

    3. FLandscapeHeightmapImportData Import(const TCHAR* HeightmapFilename, FLandscapeFileResolution ExpectedResolution) const - Actually imports the file.

    4. void Export(const TCHAR* HeightmapFilename, TArrayView Data, FLandscapeFileResolution DataResolution, FVector Scale) const - Exports the file, if this format supports exporting (see the return value from GetInfo). This is the only function that doesn't need to be overridden in order to compile. However, if it is called without being overridden, it will call check.

    5. (Destructor) - Classes that implement this interface should use a virtual destructor, as they will be deleted via a pointer to the interface class.

  • Implementing the ILandscapeHeightmapFileFormat interface is nearly identical, with only minor differences in some return types:

    1. const FLandscapeFileTypeInfo& GetInfo() const - Returns type information indicating which file types this class handles, and whether or not exporting is supported.

    2. FLandscapeWeightmapInfo Validate(const TCHAR* WeightmapFilename) const - Validates the named file, or rejects it and returns an error code and message.

    3. FLandscapeWeightmapImportData Import(const TCHAR* WeightmapFilename, FLandscapeFileResolution ExpectedResolution) const - Actually imports the file.

    4. void Export(const TCHAR* WeightmapFilename, TArrayView Data, FLandscapeFileResolution DataResolution, FVector Scale) const - Exports the file, if this format supports exporting (see the return value from GetInfo). This is the only function that doesn't need to be overridden in order to compile. However, if it is called without being overridden, it will call check.

    5. (Destructor) - Classes that implement this interface should use a virtual destructor, as they will be deleted via a pointer to the interface class.

  • For further information and examples, you can see the interfaces in LandscapeFileFormatInterfaces.h, the .PNG implementations in LandscapeFileFormatPng.cpp1 and LandscapeFileFormatPng.h , and the .RAW implementations in LandscapeFileFormatRaw.cpp and LandscapeFileFormatRaw.h. All of this code is in the LandscapeEditor module in the engine.