Terrain3DStorage

Inherits: Resource < RefCounted < Object

Description

This resource stores all map data for Terrain3D. Also see Controlmap Format and Storage Format Changelog.

Properties

Array[Image]

color_maps

[]

Array[Image]

control_maps

[]

Array[Image]

height_maps

[]

Vector2

height_range

Vector2(0, 0)

Array[Vector2i]

region_offsets

[]

RegionSize

region_size

1024

bool

save_16_bit

false

float

version

0.8

Methods

Error

add_region(global_position: Vector3, images: Array[Image] = [], update: bool = true)

Error

export_image(file_name: String, map_type: MapType)

void

force_update_maps(map_type: MapType = 3)

Color

get_color(global_position: Vector3)

int

get_control(global_position: Vector3)

float

get_height(global_position: Vector3)

Image

get_map_region(map_type: MapType, region_index: int)

Array[Image]

get_maps(map_type: MapType)

Array[Image]

get_maps_copy(map_type: MapType)

Vector3

get_mesh_vertex(lod: int, filter: HeightFilter, global_position: Vector3)

Vector3

get_normal(global_position: Vector3)

Color

get_pixel(map_type: MapType, global_position: Vector3)

int

get_region_count()

int

get_region_index(global_position: Vector3)

Vector2i

get_region_offset(global_position: Vector3)

float

get_roughness(global_position: Vector3)

Vector3

get_texture_id(global_position: Vector3)

bool

has_region(global_position: Vector3)

void

import_images(images: Array[Image], global_position: Vector3 = Vector3(0, 0, 0), offset: float = 0.0, scale: float = 1.0)

Image

layered_to_image(map_type: MapType)

void

remove_region(global_position: Vector3, update: bool = true)

void

save()

void

set_color(global_position: Vector3, color: Color)

void

set_control(global_position: Vector3, control: int)

void

set_height(global_position: Vector3, height: float)

void

set_map_region(map_type: MapType, region_index: int, image: Image)

void

set_maps(map_type: MapType, maps: Array[Image])

void

set_pixel(map_type: MapType, global_position: Vector3, pixel: Color)

void

set_roughness(global_position: Vector3, roughness: float)

void

update_height_range()


Signals

height_maps_changed()

Emitted when the height maps have changed and been regenerated.


maps_edited(edited_area: AABB)

This signal is emitted whenever the editor is used to:

  • add or remove a region,

  • alter a region map with a brush tool,

  • undo or redo any of the above operations.

The parameter contains the axis-aligned bounding box of the area edited.


region_size_changed()

Emitted when region_size is changed.


regions_changed()

Emitted when any of the maps or regions are modified and regenerated.


Enumerations

enum MapType:

MapType TYPE_HEIGHT = 0

Height map.

MapType TYPE_CONTROL = 1

Control map.

MapType TYPE_COLOR = 2

Color map.

MapType TYPE_MAX = 3

The number of elements in this enum.


enum RegionSize:

RegionSize SIZE_1024 = 1024

Region size is 1024 x 1024 vertices or pixels on maps.


enum HeightFilter:

HeightFilter HEIGHT_FILTER_NEAREST = 0

Samples the height map at the exact coordinates given.

HeightFilter HEIGHT_FILTER_MINIMUM = 1

Samples (1 << lod) * 2 heights around the given coordinates and returns the lowest.


Constants

REGION_MAP_SIZE = 16

Hard coded number of regions on a side. The total number of regions is this squared.


Property Descriptions

Array[Image] color_maps = []

  • void set_color_maps(value: Array[Image])

  • Array[Image] get_color_maps()

The Array of Images containing all the color maps for all regions.

Image format: FORMAT_RGBA8, 32-bits per pixel as four 8-bit components.

RGB is used for color, which is multiplied by albedo in the shader. Multiply is a blend mode that only darkens.

A is used for a roughness modifier. A value of 0.5 means no change to the existing texture roughness. Higher than this value increases roughness, lower decreases it.

The setter calls set_maps.


Array[Image] control_maps = []

  • void set_control_maps(value: Array[Image])

  • Array[Image] get_control_maps()

The Array of Images containing all the control maps for all regions.

Image format: FORMAT_RF, 32-bit per pixel as full-precision floating-point.

However we interpret these images as format: RenderingDevice.DATA_FORMAT_R32_UINT aka OpenGL RG32UI 32-bit per pixel as unsigned integer. See Control map format.

The setter calls set_maps.


Array[Image] height_maps = []

  • void set_height_maps(value: Array[Image])

  • Array[Image] get_height_maps()

The Array of Images containing all the heightmaps for all regions.

Image format: FORMAT_RF, 32-bit per pixel as full-precision floating-point.

Defines the height value of the terrain at a given pixel. This is sent to the vertex shader on the GPU which modifies the mesh in real-time.

Editing is always done in 32-bit. We do provide an option to save as 16-bit, see save_16_bit, which converts to 32-bit on load and back to 16-bit on save.

The setter calls set_maps.


Vector2 height_range = Vector2(0, 0)

  • void set_height_range(value: Vector2)

  • Vector2 get_height_range()

The highest and lowest heights for the sculpted terrain. Any Terrain3DMaterial.world_background used that extends the mesh height outside of this range will not change this variable. Also see Terrain3D.render_cull_margin.


Array[Vector2i] region_offsets = []

  • void set_region_offsets(value: Array[Vector2i])

  • Array[Vector2i] get_region_offsets()

An array of the active regions in region grid coordinates (+/-8, +/-8). e.g. { (0, 0), (-1, 3), (1, 1) }. It is ordered by the sequence in which regions were created, not by location.

Also see get_region_index which returns the index into this array based on position.

And get_region_offset which converts a position in world space to a region space, which is what is stored in this array. Eg. get_region_offset(Vector3(1500, 0, 1500)) would return (1, 1).


RegionSize region_size = 1024

The number of vertices in each sculptable region, and the number of pixels for each layer in the TextureArrays that store the height, control, and color maps. Limited to 1024 for now. This does not factor in Terrain3D.mesh_vertex_spacing.


bool save_16_bit = false

  • void set_save_16_bit(value: bool)

  • bool get_save_16_bit()

Heightmaps are loaded and edited in 32-bit. This option converts the file to 16-bit upon saving to reduce file size. This process is lossy.


float version = 0.8

  • void set_version(value: float)

  • float get_version()

Current version of this storage resource. This is used for upgrading data files and is independent of Terrain3D.version. The file and this variable are updated to the latest version upon saving this resource.


Method Descriptions

Error add_region(global_position: Vector3, images: Array[Image] = [], update: bool = true)

Adds a region for sculpting and painting. This allocates new set of region_size sized image maps in memory and on disk to store sculpting and texture painting data.

If the region already exists and image maps are included, the current maps will be overwritten. This means that if some maps are null, existing maps will be removed.

Parameters:

  • p_global_position - the world position to place the region, which gets rounded down to the nearest region_size multiple. That means adding a region at (1500, 0, 1500) is the same as adding it at (1024, 0, 1024) when region_size is 1024.

  • p_images - Optional array of { Height, Control, Color } with region_sized images. See MapType.

  • p_update - rebuild the maps if true. Set to false if bulk adding many regions, then true on the last one or use force_update_maps.


Error export_image(file_name: String, map_type: MapType)

Exports the specified map type as one of r16/raw, exr, jpg, png, webp, res, tres.

R16 or exr are recommended for roundtrip external editing.

R16 can be edited by Krita, however you must know the dimensions and min/max before reimporting. This information is printed to the console.

Res/tres allow storage in any of Godot’s native Image formats.


void force_update_maps(map_type: MapType = 3)

Regenerates the TextureArrays that house the requested map types. Using the default MapType TYPE_MAX(3) will regenerate all map types.


Color get_color(global_position: Vector3)

Returns the associated pixel on the color map at the requested position. Calls get_pixel.


int get_control(global_position: Vector3)

Returns the associated pixel on the control map at the requested position. Calls get_pixel.


float get_height(global_position: Vector3)

Returns the height at the requested position. If the position is close to a vertex, the pixel height on the heightmap is returned. Otherwise the value is interpolated from the 4 vertices surrounding the position.

Returns NAN if the requested position is a hole or outside of defined regions.

Calls get_pixel.


Image get_map_region(map_type: MapType, region_index: int)

Returns the Image for the specified map type and region. E.g. Returns the region_size height map Image at the first defined region 0.


Array[Image] get_maps(map_type: MapType)

Returns an Array of Images containing all of the regions for the specified map type.


Array[Image] get_maps_copy(map_type: MapType)

Returns a copy of the Array of Images containing all of the regions for the specified map type.


Vector3 get_mesh_vertex(lod: int, filter: HeightFilter, global_position: Vector3)

Returns the position of a terrain vertex at a certain LOD. If there is a hole at the position, it returns NAN in the vector’s Y coordinate.

lod - Determines how many heights around the given global position will be sampled. Range 0 - 8.

filter - Specifies how samples are filtered. See HeightFilter.

global_position - X and Z coordinates of the vertex. Heights will be sampled around these coordinates.


Vector3 get_normal(global_position: Vector3)

Returns the terrain normal at the specified position. This function uses get_height.

Returns Vector3(NAN, NAN, NAN) if the requested position is a hole or outside of defined regions.


Color get_pixel(map_type: MapType, global_position: Vector3)

Returns the pixel for the map type associated with the specified position.

Returns Color(NAN, NAN, NAN, NAN) if the position is outside of defined regions.


int get_region_count()

Returns the number of allocated regions.


int get_region_index(global_position: Vector3)

Returns the index into the region_offsets array for the region associated with the specified position.


Vector2i get_region_offset(global_position: Vector3)

Converts a world space position to region space. For a region_size of 1024 this basically means global_position/1024.0. Also see region_offsets.


float get_roughness(global_position: Vector3)

Returns the roughness modifier (wetness) on the color map alpha channel associated with the specified position. Calls set_pixel.


Vector3 get_texture_id(global_position: Vector3)

Returns Vector3(base texture id, overlay id, blend value).

Returns Vector3(NAN, NAN, NAN) if the requested area is not in a region.

This is often used for playing footstep sounds. It’s up to the gamedev to determine which is visually apparent based on shader settings.

Due to blending, it won’t be pixel perfect. Try having your player controller print this value while walking around to see how the blending values look. Perhaps you’ll find that the overlay texture is visible starting at a blend value of .3 to .5, otherwise the base is visible. You can also observe the control blend debug view with Terrain3DMaterial.show_control_blend.

Observing how this is done in The Witcher 3, there are only about 6 sounds used (snow, foliage, dirt, gravel, rock, wood), and except for wood, they are not pixel perfect. Wood is easy to do by detecting if the player is walking on wood meshes. The other 5 sounds are played when the player is in an area where the textures are blending. So it might play rock while over a dirt area. This shows pixel perfect accuracy is not important. It will still provide a seamless audio visual experience.


bool has_region(global_position: Vector3)

Returns true if the specified position has a region allocated.


void import_images(images: Array[Image], global_position: Vector3 = Vector3(0, 0, 0), offset: float = 0.0, scale: float = 1.0)

Imports an Image set (Height, Control, Color) into this resource. It does NOT normalize values to 0-1. You must do that using get_min_max() and adjusting scale and offset.

images - MapType.TYPE_MAX sized array of Images for Height, Control, Color. Images can be blank or null.

global_position - X,0,Z position on the region map. Valid range is Terrain3D.mesh_vertex_spacing * (+/-8192, +/-8192).

offset - Add this factor to all height values, can be negative.

scale - Scale all height values by this factor (applied after offset).


Image layered_to_image(map_type: MapType)

Returns an Image of the given map type that contains all regions in one large image. If the world has multiple islands, this function will return an image large enough to encompass all used regions, with black areas in between the islands.


void remove_region(global_position: Vector3, update: bool = true)

Removes the region at the specified position from the region_offsets and the height, control, and color map arrays.


void save()

Saves this storage resource to disk, if saved as an external .res file, which is the recommended practice.


void set_color(global_position: Vector3, color: Color)

Sets the color on the color map pixel associated with the specified position. Calls set_pixel.


void set_control(global_position: Vector3, control: int)

Sets the value on the control map pixel associated with the specified position. Calls set_pixel.


void set_height(global_position: Vector3, height: float)

Sets the height value on the heightmap pixel associated with the specified position. Calls set_pixel.

Unlike get_height, which interpolates between vertices, this function does not and will set the pixel at floored coordinates.


void set_map_region(map_type: MapType, region_index: int, image: Image)

Sets the Image for the specified map type and region. This method calls force_update_maps.


void set_maps(map_type: MapType, maps: Array[Image])

Sets the Array of Images for the specified map type. This method calls force_update_maps.


void set_pixel(map_type: MapType, global_position: Vector3, pixel: Color)

Sets the pixel for the map type associated with the specified position. This method is fine for setting a few pixels, but if you wish to modify thousands of pixels quickly, you should use get_maps or get_map_region and edit the images directly.

After setting pixels you need to call force_update_maps. You may also need to regenerate collision if you don’t have dynamic collision enabled.


void set_roughness(global_position: Vector3, roughness: float)

Sets the roughness modifier (wetness) on the color map alpha channel associated with the specified position. Calls set_pixel.


void update_height_range()

Evaluates every height map pixel for every region and updates height_range.