Terrain3D

Inherits: Node3D < Node < Object

Description

Terrain3D is a high performance, editable terrain system for Godot 4. It provides a clipmap based terrain that supports up to 16k terrains with multiple LODs, 32 textures, and editor tools for importing or creating terrains.

This class handles mesh and collision generation, and management of the whole system. See System Architecture for design details.

Properties

bool

collision_enabled

true

int

collision_layer

1

int

collision_mask

1

float

collision_priority

1.0

int

debug_level

0

bool

debug_show_collision

false

Terrain3DMaterial

material

int

mesh_lods

7

int

mesh_size

48

float

mesh_vertex_spacing

1.0

ShadowCastingSetting

render_cast_shadows

1

float

render_cull_margin

0.0

int

render_layers

2147483649

int

render_mouse_layer

32

Terrain3DStorage

storage

Terrain3DTextureList

texture_list

String

version

"0.9.2-dev"

Methods

Mesh

bake_mesh(lod: int, filter: HeightFilter)

PackedVector3Array

generate_nav_mesh_source_geometry(global_aabb: AABB, require_nav: bool = true)

Camera3D

get_camera()

Vector3

get_intersection(src_pos: Vector3, direction: Vector3)

EditorPlugin

get_plugin()

void

set_camera(camera: Camera3D)

void

set_plugin(plugin: EditorPlugin)


Signals

material_changed()

Emitted when material is changed.


storage_changed()

Emitted when storage is changed.


texture_list_changed()

Emitted when texture_list is changed.


Property Descriptions

bool collision_enabled = true

  • void set_collision_enabled(value: bool)

  • bool get_collision_enabled()

If enabled, collision is generated according to the mode selected. By default collision is generated for all regions at run time only using the physics server. Also see debug_show_collision.


int collision_layer = 1

  • void set_collision_layer(value: int)

  • int get_collision_layer()

The physics layers the terrain lives in. Also see collision_mask.


int collision_mask = 1

  • void set_collision_mask(value: int)

  • int get_collision_mask()

The physics layers the terrain scans for colliding objects. Also see collision_layer.


float collision_priority = 1.0

  • void set_collision_priority(value: float)

  • float get_collision_priority()

The priority used to solve collisions. The higher priority, the lower the penetration of a colliding object.


int debug_level = 0

  • void set_debug_level(value: int)

  • int get_debug_level()

The verbosity of debug messages printed to the console. Errors and warnings are always printed. This can also be set via command line using --terrain3d-debug=LEVEL where LEVEL is one of ERROR, INFO, DEBUG, DEBUG_CONT. The last is for continuously recurring messages like position updates for the mesh as the camera moves around.


bool debug_show_collision = false

  • void set_show_debug_collision(value: bool)

  • bool get_show_debug_collision()

If collision is enabled, this generates collision in the editor and in game. It can be visible in the editor by enabling View Gizmos in the viewport menu.


Terrain3DMaterial material

A custom material for Terrain3D. You can optionally save this as an external .tres text file if you wish to share it with instances of Terrain3D in other scenes. See Terrain3DMaterial.


int mesh_lods = 7

  • void set_mesh_lods(value: int)

  • int get_mesh_lods()

The number of lods generated in the mesh. Enable wireframe mode in the viewport to see them.


int mesh_size = 48

  • void set_mesh_size(value: int)

  • int get_mesh_size()

The correlated size of the terrain meshes. Lod0 has 4*mesh_size + 2 quads per side. E.g. when mesh_size=8, lod0 has 34 quads to a side, including 2 quads for seams.


float mesh_vertex_spacing = 1.0

  • void set_mesh_vertex_spacing(value: float)

  • float get_mesh_vertex_spacing()

The distance between vertices. Godot units are typically considered to be meters. This scales the terrain on X and Z axes.

This variable changes the global position of landscape features. A mountain peak might be at (512, 512), but with a vertex spacing of 2.0 it is now located at (1024, 1024).

All Terrain3D functions with a global_position expect an absolute global value. If you would normally use Terrain3DStorage.import_images to import an image in the region at (-1024, -1024), with a mesh_vertex_spacing of 2, you’ll need to import that image at (-2048, -2048) to place it in the same region.

To scale heights, export the height map and reimport it with a new height scale.


ShadowCastingSetting render_cast_shadows = 1

  • void set_cast_shadows(value: ShadowCastingSetting)

  • ShadowCastingSetting get_cast_shadows()

Tells the renderer how to cast shadows from the terrain onto other objects. This sets GeometryInstance3D.ShadowCastingSetting in the engine.


float render_cull_margin = 0.0

  • void set_cull_margin(value: float)

  • float get_cull_margin()

This margin is added to the terrain bounding box (AABB). The terrain already sets its AABB, so this setting only needs to be used if the shader has expanded the terrain beyond the AABB and the terrain meshes are being culled, as might happen from using Terrain3DMaterial.world_background with NOISE and a large height value. This sets GeometryInstance3D.extra_cull_margin in the engine.


int render_layers = 2147483649

  • void set_render_layers(value: int)

  • int get_render_layers()

The render layers the terrain is drawn on. This sets VisualInstance3D.layers in the engine. The defaults is layer 1 and 32 (for the mouse cursor). When you set this, make sure the layer for render_mouse_layer is included, or set that variable again after this so that the mouse cursor works.


int render_mouse_layer = 32

  • void set_mouse_layer(value: int)

  • int get_mouse_layer()

Godot supports 32 render layers. For most objects, only layers 1-20 are available for selection in the inspector. 21-32 are settable via code, and are considered reserved for editor plugins.

This variable sets the editor render layer (21-32) to be used by get_intersection, which the mouse cursor uses.

You may place other objects on this layer, however get_intersection will report intersections with them. So either dedicate this layer to Terrain3D, or if you must use all 32 layers, dedicate this one during editing or when using get_intersection, and then you can use it during game play.

See get_intersection.


Terrain3DStorage storage

The object that houses all Terrain3D region, height, control, and color maps. Make sure to save this as an external .res binary file.


Terrain3DTextureList texture_list

The list of texture files used by Terrain3D. You can optionally save this as an external .tres text file if you wish to share it with instances of Terrain3D in other scenes.


String version = "0.9.2-dev"

  • String get_version()

The current version of Terrain3D.


Method Descriptions

Mesh bake_mesh(lod: int, filter: HeightFilter)

Generates a static ArrayMesh for the terrain.

lod - Determines the granularity of the generated mesh. The range is 0-8. 4 is recommended.

filter - Controls how vertex Y coordinates are generated from the height map. See HeightFilter.


PackedVector3Array generate_nav_mesh_source_geometry(global_aabb: AABB, require_nav: bool = true)

Generates source geometry faces for input to nav mesh baking. Geometry is only generated where there are no holes and the terrain has been painted as navigable.

global_aabb - If non-empty, geometry will be generated only within this AABB. If empty, geometry will be generated for the entire terrain.

require_nav - If true, this function will only generate geometry for terrain marked navigable. Otherwise, geometry is generated for the entire terrain within the AABB (which can be useful for dynamic and/or runtime nav mesh baking).


Camera3D get_camera()

Returns the camera the terrain is currently snapping to.


Vector3 get_intersection(src_pos: Vector3, direction: Vector3)

Casts a ray from src_pos pointing towards direction, attempting to intersect the terrain.

Possible return values:

  • If the terrain is hit, the intersection point is returned.

  • If there is no intersection, eg. the ray points towards the sky, it returns the maximum double float value Vector3(3.402823466e+38F,...). You can check this case with this code: if point.z > 3.4e38:

  • On error, it returns Vector3(NAN, NAN, NAN) and prints a message to the console.

This ray cast does not use physics, so enabling collision is unnecessary. It places a camera at the specified point and “looks” at the terrain. It then uses the renderer’s depth texture to determine how far away the intersection point is.

This function is used by the editor plugin to place the mouse cursor. It can also be used by 3rd party plugins, and even during gameplay, such as a space ship firing lasers at the terrain and causing an explosion at the hit point.

It does require the use of an editor render layer (21-32) that should be dedicated while using this function. See render_mouse_layer.


EditorPlugin get_plugin()

Returns the EditorPlugin connected to Terrain3D.


void set_camera(camera: Camera3D)

Sets the camera the terrain snaps to.


void set_plugin(plugin: EditorPlugin)

Sets the EditorPlugin connected to Terrain3D.