Merge pull request 'Fix Large Terrain Performance Issues' (#10) from large-terrain-performance-fix into main
Reviewed-on: #10
This commit is contained in:
commit
9cd33db1dd
BIN
map_editor.scn (Stored with Git LFS)
BIN
map_editor.scn (Stored with Git LFS)
Binary file not shown.
BIN
map_editor/camera_boundary_mesh.res (Stored with Git LFS)
BIN
map_editor/camera_boundary_mesh.res (Stored with Git LFS)
Binary file not shown.
BIN
map_editor/edit_mode_button_group.res (Stored with Git LFS)
BIN
map_editor/edit_mode_button_group.res (Stored with Git LFS)
Binary file not shown.
|
@ -1,143 +0,0 @@
|
||||||
class_name MapEditorController extends Node
|
|
||||||
|
|
||||||
##
|
|
||||||
## Default elevation height for terrain.
|
|
||||||
##
|
|
||||||
const DEFAULT_ELEVATION := 0.5
|
|
||||||
|
|
||||||
var _brush_selected := 0
|
|
||||||
|
|
||||||
@export
|
|
||||||
var _registered_brushes: Array[Image] = []
|
|
||||||
|
|
||||||
@export
|
|
||||||
var _registered_paints: Array[TerrainPaint] = []
|
|
||||||
|
|
||||||
var _paint_selected_erase := 0
|
|
||||||
|
|
||||||
var _paint_selected_blue := 0
|
|
||||||
|
|
||||||
var _paint_selected_green := 0
|
|
||||||
|
|
||||||
var _paint_selected_red := 0
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
var smooth_elevation := DEFAULT_ELEVATION
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func disable_controls() -> void:
|
|
||||||
set_process(false)
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func enable_controls() -> void:
|
|
||||||
set_process(true)
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func get_registered_brushes() -> Array[Image]:
|
|
||||||
return _registered_brushes
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func get_registered_paints() -> Array[TerrainPaint]:
|
|
||||||
return _registered_paints
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func get_selected_brush() -> int:
|
|
||||||
return _brush_selected
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func get_selected_paint_blue() -> int:
|
|
||||||
return _paint_selected_blue
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func get_selected_paint_erase() -> int:
|
|
||||||
return _paint_selected_erase
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func get_selected_paint_green() -> int:
|
|
||||||
return _paint_selected_green
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func get_selected_paint_red() -> int:
|
|
||||||
return _paint_selected_red
|
|
||||||
|
|
||||||
##
|
|
||||||
## Registers [code]brush_mask[/code] as a usable brush option in the editor.
|
|
||||||
##
|
|
||||||
func register_brush(brush_mask: Image) -> void:
|
|
||||||
_registered_brushes.append(brush_mask)
|
|
||||||
|
|
||||||
##
|
|
||||||
## Registers [code]terrain_paint[/code] as a usable paint option in the editor.
|
|
||||||
##
|
|
||||||
func register_paint(terrain_paint: TerrainPaint) -> void:
|
|
||||||
_registered_paints.append(terrain_paint)
|
|
||||||
|
|
||||||
##
|
|
||||||
## Resets the editor settings to their initial values.
|
|
||||||
##
|
|
||||||
func reset() -> void:
|
|
||||||
select_brush(0)
|
|
||||||
select_paint_erase(0)
|
|
||||||
select_paint_red(0)
|
|
||||||
select_paint_green(0)
|
|
||||||
select_paint_blue(0)
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func select_brush(selected_index: int) -> void:
|
|
||||||
assert((selected_index >= 0) or (selected_index < _registered_brushes.size()))
|
|
||||||
|
|
||||||
_brush_selected = selected_index
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func select_paint_blue(selected_index: int) -> void:
|
|
||||||
assert((selected_index >= 0) or (selected_index < _registered_paints.size()))
|
|
||||||
|
|
||||||
_paint_selected_blue = selected_index
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func select_paint_erase(selected_index: int) -> void:
|
|
||||||
assert((selected_index >= 0) or (selected_index < _registered_paints.size()))
|
|
||||||
|
|
||||||
_paint_selected_erase = selected_index
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func select_paint_green(selected_index: int) -> void:
|
|
||||||
assert((selected_index >= 0) or (selected_index < _registered_paints.size()))
|
|
||||||
|
|
||||||
_paint_selected_green = selected_index
|
|
||||||
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##
|
|
||||||
func select_paint_red(selected_index: int) -> void:
|
|
||||||
assert((selected_index >= 0) or (selected_index < _registered_paints.size()))
|
|
||||||
|
|
||||||
_paint_selected_red = selected_index
|
|
|
@ -1,27 +1,33 @@
|
||||||
class_name DynamicTerrainInstance3D extends TerrainInstance3D
|
class_name MapEditorTerrainCanvas extends Node
|
||||||
|
|
||||||
##
|
##
|
||||||
## Blank sample value.
|
## Blank sample value.
|
||||||
##
|
##
|
||||||
const BLANK := Color(0.0, 0.0, 0.0, 0.0)
|
const BLANK := Color(0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
var _editable_image: Image
|
var _editable_image := Image.create(1, 1, false, Image.FORMAT_RGBAF)
|
||||||
|
|
||||||
var _editable_texture: ImageTexture
|
var _editable_texture := ImageTexture.create_from_image(_editable_image)
|
||||||
|
|
||||||
|
##
|
||||||
|
## Width and height of the canvas (in pixels).
|
||||||
|
##
|
||||||
|
var size := Vector2i.ONE:
|
||||||
|
set(value):
|
||||||
|
size = Vector2(maxi(size.x, value.x), maxi(size.y, value.y))
|
||||||
|
|
||||||
|
_editable_image.resize(size.x, size.y)
|
||||||
|
_editable_texture.set_image(_editable_image)
|
||||||
|
|
||||||
func _get_brush_area(point: Vector2i, mask_size: Vector2i, mask_scale: float) -> Rect2i:
|
func _get_brush_area(point: Vector2i, mask_size: Vector2i, mask_scale: float) -> Rect2i:
|
||||||
# Convert worldspace point to image-space coordinates for mask.
|
# Convert worldspace point to image-space coordinates for mask.
|
||||||
var scaled_mask_size := Vector2i(mask_size * mask_scale)
|
var scaled_mask_size := Vector2i(mask_size * mask_scale)
|
||||||
|
|
||||||
return Rect2i((point + Vector2i(get_size() * 0.5)) - Vector2i(scaled_mask_size * 0.5), scaled_mask_size)
|
return Rect2i((point + Vector2i(size * 0.5)) -
|
||||||
|
Vector2i(scaled_mask_size * 0.5), scaled_mask_size)
|
||||||
|
|
||||||
func _init() -> void:
|
func _get_editable_area() -> Rect2i:
|
||||||
super._init()
|
return Rect2i(Vector2i.ZERO, size).grow(-1)
|
||||||
|
|
||||||
_editable_image = Image.create(1, 1, false, Image.FORMAT_RGBAF)
|
|
||||||
_editable_texture = ImageTexture.create_from_image(_editable_image)
|
|
||||||
|
|
||||||
super.resize(Vector2i.ONE)
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Clears the terrain map to the value of [code]clear_elevation[/code].
|
## Clears the terrain map to the value of [code]clear_elevation[/code].
|
||||||
|
@ -30,17 +36,23 @@ func clear(clear_elevation: float) -> void:
|
||||||
_editable_image.fill(Color(0.0, 0.0, 0.0, clampf(clear_elevation, 0.0, 1.0)))
|
_editable_image.fill(Color(0.0, 0.0, 0.0, clampf(clear_elevation, 0.0, 1.0)))
|
||||||
_editable_texture.update(_editable_image)
|
_editable_texture.update(_editable_image)
|
||||||
|
|
||||||
|
##
|
||||||
|
## Returns the canvas data as a [Texture2D].
|
||||||
|
##
|
||||||
|
func get_texture() -> Texture2D:
|
||||||
|
return _editable_texture
|
||||||
|
|
||||||
##
|
##
|
||||||
## Oscillates the height of terrain toward a value of [member height_scale] (multiplied by
|
## Oscillates the height of terrain toward a value of [member height_scale] (multiplied by
|
||||||
## [code]level[/code]) around the area of [code]point[/code] determined by [code]mask[/code]
|
## [code]level[/code]) around the area of [code]point[/code] determined by [code]mask[/code]
|
||||||
## multiplied by [code]mask_scale[/code] at a rate of [code]intensity[/code].
|
## multiplied by [code]mask_scale[/code] at a rate of [code]intensity[/code].
|
||||||
##
|
##
|
||||||
func oscillate(point: Vector2i, level: float, mask: Image, mask_scale: float, intensity: float) -> void:
|
func oscillate(level: float, point: Vector2i, mask: Image, mask_scale: float, intensity: float) -> void:
|
||||||
var mask_size := mask.get_size()
|
var mask_size := mask.get_size()
|
||||||
var brush_source := _get_brush_area(point, mask_size, mask_scale)
|
var brush_source := _get_brush_area(point, mask_size, mask_scale)
|
||||||
|
|
||||||
if brush_source.has_area():
|
if brush_source.has_area():
|
||||||
var brush_target := Rect2i(Vector2i.ZERO, get_size()).intersection(brush_source)
|
var brush_target := _get_editable_area().intersection(brush_source)
|
||||||
|
|
||||||
if brush_target.has_area():
|
if brush_target.has_area():
|
||||||
var mask_ratio := mask_size / brush_source.size
|
var mask_ratio := mask_size / brush_source.size
|
||||||
|
@ -64,12 +76,12 @@ func oscillate(point: Vector2i, level: float, mask: Image, mask_scale: float, in
|
||||||
## [code]intensity[/code] around the area of [code]point[/code] determined by [code]mask[/code]
|
## [code]intensity[/code] around the area of [code]point[/code] determined by [code]mask[/code]
|
||||||
## multiplied by [code]mask_scale[/code] at a rate of [code]intensity[/code].
|
## multiplied by [code]mask_scale[/code] at a rate of [code]intensity[/code].
|
||||||
##
|
##
|
||||||
func paint(point: Vector2i, color: Color, mask: Image, mask_scale: float, intensity: float) -> void:
|
func paint(color: Color, point: Vector2i, mask: Image, mask_scale: float, intensity: float) -> void:
|
||||||
var mask_size := mask.get_size()
|
var mask_size := mask.get_size()
|
||||||
var brush_source := _get_brush_area(point, mask_size, mask_scale)
|
var brush_source := _get_brush_area(point, mask_size, mask_scale)
|
||||||
|
|
||||||
if brush_source.has_area():
|
if brush_source.has_area():
|
||||||
var brush_target := Rect2i(Vector2i.ZERO, get_size()).intersection(brush_source)
|
var brush_target := _get_editable_area().intersection(brush_source)
|
||||||
|
|
||||||
if brush_target.has_area():
|
if brush_target.has_area():
|
||||||
var mask_ratio := mask_size / brush_source.size
|
var mask_ratio := mask_size / brush_source.size
|
||||||
|
@ -92,23 +104,6 @@ func paint(point: Vector2i, color: Color, mask: Image, mask_scale: float, intens
|
||||||
|
|
||||||
_editable_texture.update(_editable_image)
|
_editable_texture.update(_editable_image)
|
||||||
|
|
||||||
##
|
|
||||||
## Attempts to resize the terrain geometry and map to be equal to [code]size[/code] (in-engine
|
|
||||||
## units), with [code]Vector2i.ONE[/code] as the minimum size.
|
|
||||||
##
|
|
||||||
## In the process of growing the terrain map, existing edge data will be copied to fill it out.
|
|
||||||
##
|
|
||||||
func resize(size: Vector2i) -> void:
|
|
||||||
super.resize(size)
|
|
||||||
|
|
||||||
var actual_size := get_size()
|
|
||||||
|
|
||||||
_editable_image.resize(actual_size.x, actual_size.y)
|
|
||||||
|
|
||||||
_editable_texture = ImageTexture.create_from_image(_editable_image)
|
|
||||||
|
|
||||||
update_terrain(_editable_texture)
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Samples the color value in the editable terrain at the worldspace [code]point[/code], returning
|
## Samples the color value in the editable terrain at the worldspace [code]point[/code], returning
|
||||||
## its respective [Color] value.
|
## its respective [Color] value.
|
||||||
|
@ -117,7 +112,6 @@ func resize(size: Vector2i) -> void:
|
||||||
## instead.
|
## instead.
|
||||||
##
|
##
|
||||||
func sample(point: Vector2i) -> Color:
|
func sample(point: Vector2i) -> Color:
|
||||||
var size := get_size()
|
|
||||||
var image_point := point + Vector2i(size * 0.5)
|
var image_point := point + Vector2i(size * 0.5)
|
||||||
|
|
||||||
if Rect2i(Vector2i.ZERO, size).has_point(image_point):
|
if Rect2i(Vector2i.ZERO, size).has_point(image_point):
|
BIN
map_editor/menus_theme.res (Stored with Git LFS)
BIN
map_editor/menus_theme.res (Stored with Git LFS)
Binary file not shown.
|
@ -9,20 +9,15 @@
|
||||||
config_version=5
|
config_version=5
|
||||||
|
|
||||||
_global_script_classes=[{
|
_global_script_classes=[{
|
||||||
"base": "TerrainInstance3D",
|
|
||||||
"class": &"DynamicTerrainInstance3D",
|
|
||||||
"language": &"GDScript",
|
|
||||||
"path": "res://terrain/dynamic_terrain_instance_3d.gd"
|
|
||||||
}, {
|
|
||||||
"base": "HFlowContainer",
|
"base": "HFlowContainer",
|
||||||
"class": &"ItemSelection",
|
"class": &"ItemSelection",
|
||||||
"language": &"GDScript",
|
"language": &"GDScript",
|
||||||
"path": "res://user_interface/button_selection.gd"
|
"path": "res://user_interface/button_selection.gd"
|
||||||
}, {
|
}, {
|
||||||
"base": "Node",
|
"base": "Node",
|
||||||
"class": &"MapEditorController",
|
"class": &"MapEditorTerrainCanvas",
|
||||||
"language": &"GDScript",
|
"language": &"GDScript",
|
||||||
"path": "res://map_editor/map_editor_controller.gd"
|
"path": "res://map_editor/map_editor_terrain_canvas.gd"
|
||||||
}, {
|
}, {
|
||||||
"base": "Node3D",
|
"base": "Node3D",
|
||||||
"class": &"PlayerController",
|
"class": &"PlayerController",
|
||||||
|
@ -45,9 +40,8 @@ _global_script_classes=[{
|
||||||
"path": "res://terrain/paints/terrain_paint.gd"
|
"path": "res://terrain/paints/terrain_paint.gd"
|
||||||
}]
|
}]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
"DynamicTerrainInstance3D": "",
|
|
||||||
"ItemSelection": "",
|
"ItemSelection": "",
|
||||||
"MapEditorController": "",
|
"MapEditorTerrainCanvas": "",
|
||||||
"PlayerController": "",
|
"PlayerController": "",
|
||||||
"Settings": "",
|
"Settings": "",
|
||||||
"TerrainInstance3D": "",
|
"TerrainInstance3D": "",
|
||||||
|
|
BIN
terrain/paints/arid_grass_albedo.png (Stored with Git LFS)
BIN
terrain/paints/arid_grass_albedo.png (Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://jcmf7j3qo6ea"
|
|
||||||
path="res://.godot/imported/arid_grass_albedo.png-532bc188063dc524e2c08228bed13fa7.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://terrain/paints/arid_grass_albedo.png"
|
|
||||||
dest_files=["res://.godot/imported/arid_grass_albedo.png-532bc188063dc524e2c08228bed13fa7.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/bptc_ldr=0
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
BIN
terrain/paints/arid_grass_displacement.png (Stored with Git LFS)
BIN
terrain/paints/arid_grass_displacement.png (Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://co0jompch208v"
|
|
||||||
path="res://.godot/imported/arid_grass_displacement.png-cad938b62195c0b0f41099d596594b8b.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://terrain/paints/arid_grass_displacement.png"
|
|
||||||
dest_files=["res://.godot/imported/arid_grass_displacement.png-cad938b62195c0b0f41099d596594b8b.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/bptc_ldr=0
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
BIN
terrain/paints/arid_grass_normal.png (Stored with Git LFS)
BIN
terrain/paints/arid_grass_normal.png (Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://bh141jkgbmya8"
|
|
||||||
path="res://.godot/imported/arid_grass_normal.png-7bf9fdf5f927fea47a2f86a9ffab326e.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://terrain/paints/arid_grass_normal.png"
|
|
||||||
dest_files=["res://.godot/imported/arid_grass_normal.png-7bf9fdf5f927fea47a2f86a9ffab326e.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/bptc_ldr=0
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
BIN
terrain/paints/arid_grass_roughness.png (Stored with Git LFS)
BIN
terrain/paints/arid_grass_roughness.png (Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://jdq8kwjo3uap"
|
|
||||||
path="res://.godot/imported/arid_grass_roughness.png-40299cbb0e24b392d013d45af79f5444.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://terrain/paints/arid_grass_roughness.png"
|
|
||||||
dest_files=["res://.godot/imported/arid_grass_roughness.png-40299cbb0e24b392d013d45af79f5444.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/bptc_ldr=0
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
BIN
terrain/paints/arid_grass_terrain_paint.res (Stored with Git LFS)
BIN
terrain/paints/arid_grass_terrain_paint.res (Stored with Git LFS)
Binary file not shown.
BIN
terrain/paints/cobblestone_albedo.png (Stored with Git LFS)
BIN
terrain/paints/cobblestone_albedo.png (Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://cs06oiwrord6t"
|
|
||||||
path="res://.godot/imported/cobblestone_albedo.png-f0ce6b9d25b0c6c4130e70ff660bcbd6.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://terrain/paints/cobblestone_albedo.png"
|
|
||||||
dest_files=["res://.godot/imported/cobblestone_albedo.png-f0ce6b9d25b0c6c4130e70ff660bcbd6.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/bptc_ldr=0
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
BIN
terrain/paints/cobblestone_displacement.png (Stored with Git LFS)
BIN
terrain/paints/cobblestone_displacement.png (Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://mkxbjfwdwkaq"
|
|
||||||
path="res://.godot/imported/cobblestone_displacement.png-bcf2e2194862b85cb002d9559d57903b.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://terrain/paints/cobblestone_displacement.png"
|
|
||||||
dest_files=["res://.godot/imported/cobblestone_displacement.png-bcf2e2194862b85cb002d9559d57903b.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/bptc_ldr=0
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
BIN
terrain/paints/cobblestone_normal.png (Stored with Git LFS)
BIN
terrain/paints/cobblestone_normal.png (Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://ukk0161x3eg2"
|
|
||||||
path="res://.godot/imported/cobblestone_normal.png-5130e667fa81f7452d15808908f4cb99.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://terrain/paints/cobblestone_normal.png"
|
|
||||||
dest_files=["res://.godot/imported/cobblestone_normal.png-5130e667fa81f7452d15808908f4cb99.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/bptc_ldr=0
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
BIN
terrain/paints/cobblestone_roughness.png (Stored with Git LFS)
BIN
terrain/paints/cobblestone_roughness.png (Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://bcybapft8tl2x"
|
|
||||||
path="res://.godot/imported/cobblestone_roughness.png-2f09da1d7000b898b80d7b177062e509.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://terrain/paints/cobblestone_roughness.png"
|
|
||||||
dest_files=["res://.godot/imported/cobblestone_roughness.png-2f09da1d7000b898b80d7b177062e509.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/bptc_ldr=0
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
BIN
terrain/paints/cobblestone_terrain_paint.res (Stored with Git LFS)
BIN
terrain/paints/cobblestone_terrain_paint.res (Stored with Git LFS)
Binary file not shown.
|
@ -4,7 +4,7 @@ const int MAP_COUNT = 4;
|
||||||
|
|
||||||
uniform sampler2D[MAP_COUNT] ALBEDO_MAPS;
|
uniform sampler2D[MAP_COUNT] ALBEDO_MAPS;
|
||||||
|
|
||||||
uniform float MAX_HEIGHT = 100.0;
|
uniform float HEIGHT_SCALE = 100.0;
|
||||||
|
|
||||||
uniform sampler2D[MAP_COUNT] NORMAL_MAPS;
|
uniform sampler2D[MAP_COUNT] NORMAL_MAPS;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ void fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
float height(vec2 uv) {
|
float height(vec2 uv) {
|
||||||
return MAX_HEIGHT * texture(TERRAIN_MAP, uv).a;
|
return HEIGHT_SCALE * texture(TERRAIN_MAP, uv).a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vertex() {
|
void vertex() {
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
@tool
|
||||||
class_name TerrainInstance3D extends GeometryInstance3D
|
class_name TerrainInstance3D extends GeometryInstance3D
|
||||||
|
|
||||||
|
const _DETAIL := 2
|
||||||
|
|
||||||
|
const _SHADER := preload("res://terrain/terrain.gdshader")
|
||||||
|
|
||||||
##
|
##
|
||||||
## Identifier constant for a paint slot channel.
|
## Slots representing the paintable channels.
|
||||||
##
|
##
|
||||||
enum PaintSlot {
|
enum PaintSlot {
|
||||||
ERASE,
|
ERASE,
|
||||||
|
@ -10,78 +15,67 @@ enum PaintSlot {
|
||||||
BLUE,
|
BLUE,
|
||||||
}
|
}
|
||||||
|
|
||||||
const _DETAIL := 2
|
var _albedo_maps: Array[Texture2D] = [null, null, null, null]
|
||||||
|
|
||||||
var _albedo_map_textures: Array[Texture2D] = [null, null, null, null]
|
|
||||||
|
|
||||||
var _material := ShaderMaterial.new()
|
var _material := ShaderMaterial.new()
|
||||||
|
|
||||||
var _normal_map_textures: Array[Texture2D] = [null, null, null, null]
|
|
||||||
|
|
||||||
var _mesh := PlaneMesh.new()
|
var _mesh := PlaneMesh.new()
|
||||||
|
|
||||||
|
var _normal_maps: Array[Texture2D] = [null, null, null, null]
|
||||||
|
|
||||||
##
|
##
|
||||||
## The height scale range that is used to determine the minimums and maximums of the terrain map.
|
## Range of the height channel value, ranging from [code]0.0[/code] to [code]100.0[/code].
|
||||||
##
|
##
|
||||||
@export
|
@export
|
||||||
var height_scale := 100.0:
|
var height_scale := 100.0:
|
||||||
get:
|
|
||||||
return height_scale
|
|
||||||
|
|
||||||
set(value):
|
set(value):
|
||||||
_material.set_shader_parameter("MAX_HEIGHT", value)
|
value = maxf(value, 1.0)
|
||||||
|
|
||||||
height_scale = max(value, 0.0)
|
if not(is_equal_approx(value, height_scale)):
|
||||||
|
_material.set_shader_parameter("HEIGHT_SCALE", value)
|
||||||
|
|
||||||
var _size := Vector2i.ZERO
|
height_scale = value
|
||||||
|
|
||||||
|
##
|
||||||
|
## Size of the terrain geometry (in engine units).
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var size := Vector2i.ONE:
|
||||||
|
set(value):
|
||||||
|
value = Vector2i(maxi(value.x, 1), maxi(value.y, 1))
|
||||||
|
|
||||||
|
if (value.x != size.x) or (value.y != size.y):
|
||||||
|
_mesh.subdivide_width = value.x * _DETAIL
|
||||||
|
_mesh.subdivide_depth = value.y * _DETAIL
|
||||||
|
_mesh.size = value
|
||||||
|
|
||||||
|
_material.set_shader_parameter("SIZE", value)
|
||||||
|
|
||||||
|
size = value
|
||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
_material.shader = preload("res://terrain/terrain.gdshader")
|
_material.shader = _SHADER
|
||||||
|
|
||||||
RenderingServer.instance_set_base(get_instance(), _mesh)
|
|
||||||
_mesh.surface_set_material(0, _material)
|
_mesh.surface_set_material(0, _material)
|
||||||
|
RenderingServer.instance_set_base(get_instance(), _mesh)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Returns the size of the terrain mesh (as in-engine units).
|
## Updates the terrain map being used by the terrain to be [code]terrain_map[/code].
|
||||||
##
|
##
|
||||||
func get_size() -> Vector2i:
|
func update_map(terrain_map: Texture2D) -> void:
|
||||||
return _size
|
_material.set_shader_parameter("TERRAIN_MAP", terrain_map)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Attempts to resize the terrain to be equal to [code]size[/code] (in-engine units), with
|
## Updates the [TerrainPaint] being used by the terrain in [code]paint_slot[/code] to be
|
||||||
## [code]Vector2i.ONE[/code] as the minimum size.
|
|
||||||
##
|
|
||||||
func resize(size: Vector2i) -> void:
|
|
||||||
var width := maxi(size.x, 1)
|
|
||||||
var height := maxi(size.y, 1)
|
|
||||||
|
|
||||||
if (width != _size.x) or (height != _size.y):
|
|
||||||
_mesh.subdivide_width = width * _DETAIL
|
|
||||||
_mesh.subdivide_depth = height * _DETAIL
|
|
||||||
_mesh.size = size
|
|
||||||
|
|
||||||
_material.set_shader_parameter("SIZE", Vector2(size))
|
|
||||||
|
|
||||||
_size = size
|
|
||||||
|
|
||||||
##
|
|
||||||
## Updates the paint used by the paint channel identified by [code]paint_slot[/code] to
|
|
||||||
## [code]terrain_paint[/code].
|
## [code]terrain_paint[/code].
|
||||||
##
|
##
|
||||||
func update_paint(paint_slot: PaintSlot, paint: TerrainPaint) -> void:
|
func update_paint(paint_slot: PaintSlot, terrain_paint: TerrainPaint) -> void:
|
||||||
if paint == null:
|
if _albedo_maps[paint_slot] != terrain_paint.albedo_map:
|
||||||
_albedo_map_textures[paint_slot] = null
|
_albedo_maps[paint_slot] = terrain_paint.albedo_map
|
||||||
_normal_map_textures[paint_slot] = null
|
|
||||||
|
|
||||||
else:
|
_material.set_shader_parameter("ALBEDO_MAPS", _albedo_maps)
|
||||||
_albedo_map_textures[paint_slot] = paint.albedo_map
|
|
||||||
_normal_map_textures[paint_slot] = paint.normal_map
|
|
||||||
|
|
||||||
_material.set_shader_parameter("ALBEDO_MAPS", _albedo_map_textures)
|
if _normal_maps[paint_slot] != terrain_paint.normal_map:
|
||||||
_material.set_shader_parameter("NORMAL_MAPS", _normal_map_textures)
|
_normal_maps[paint_slot] = terrain_paint.normal_map
|
||||||
|
|
||||||
##
|
_material.set_shader_parameter("NORMAL_MAPS", _normal_maps)
|
||||||
## Updates the terrain map to [code]terrain_map[/code].
|
|
||||||
##
|
|
||||||
func update_terrain(terrain_map: Texture2D) -> void:
|
|
||||||
_material.set_shader_parameter("TERRAIN_MAP", terrain_map)
|
|
||||||
|
|
Loading…
Reference in New Issue