Tidy up code and file structure

This commit is contained in:
kayomn 2023-01-18 17:15:41 +00:00
parent 2c24ec861f
commit c7a0d6bce2
53 changed files with 358 additions and 323 deletions

BIN
black.png (Stored with Git LFS) Normal file

Binary file not shown.

34
black.png.import Normal file
View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cj72ibo3c6x8e"
path="res://.godot/imported/black.png-19a8df0b1a4edb74ea2eecb66d46d03d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://black.png"
dest_files=["res://.godot/imported/black.png-19a8df0b1a4edb74ea2eecb66d46d03d.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
editor.scn (Stored with Git LFS)

Binary file not shown.

BIN
editor/brush_hard_circle_mask.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,14 @@
[remap]
importer="image"
type="Image"
uid="uid://drok88h02tdre"
path="res://.godot/imported/brush_hard_circle_mask.png-e647df7b970f00cdf2f3f2ac38ad8257.image"
[deps]
source_file="res://editor/brush_hard_circle_mask.png"
dest_files=["res://.godot/imported/brush_hard_circle_mask.png-e647df7b970f00cdf2f3f2ac38ad8257.image"]
[params]

BIN
editor/edit_mode_button_group.res (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -9,10 +9,10 @@
config_version=5
_global_script_classes=[{
"base": "Node",
"class": &"EditableTerrain",
"base": "TerrainInstance3D",
"class": &"DynamicTerrainInstance3D",
"language": &"GDScript",
"path": "res://editor/editable_terrain.gd"
"path": "res://terrain/dynamic_terrain_instance_3d.gd"
}, {
"base": "Node3D",
"class": &"PlayerController",
@ -28,18 +28,25 @@ _global_script_classes=[{
"class": &"TerrainInstance3D",
"language": &"GDScript",
"path": "res://terrain/terrain_instance_3d.gd"
}, {
"base": "Resource",
"class": &"TerrainPaint",
"language": &"GDScript",
"path": "res://terrain/paints/terrain_paint.gd"
}]
_global_script_class_icons={
"EditableTerrain": "",
"DynamicTerrainInstance3D": "",
"PlayerController": "",
"Settings": "",
"TerrainInstance3D": ""
"TerrainInstance3D": "",
"TerrainPaint": ""
}
[application]
config/name="Protectorate"
run/main_scene="res://editor.scn"
config/use_custom_user_dir=true
config/features=PackedStringArray("4.0", "Forward Plus")
config/icon="res://icon.png"

View File

@ -1,70 +1,46 @@
class_name EditableTerrain extends Node
class_name DynamicTerrainInstance3D extends TerrainInstance3D
##
## Blank sample value.
##
const BLANK := Color(0.0, 0.0, 0.0, 0.0)
var _image := Image.create(1, 1, false, Image.FORMAT_RGBAF)
var _editable_image: Image
##
## Tracked [TerrainInstance3D] to echo all terrain editing changes to.
##
var instance: TerrainInstance3D = null:
get:
return instance
var _editable_texture: ImageTexture
set(value):
if (value != null) and (value != instance):
value.terrain_map = ImageTexture.create_from_image(_image)
instance = value
##
## Width and height of the editable terrain in units.
##
var size := Vector2i.ZERO:
get:
return size
set(value):
_image.resize(value.x, value.y)
if instance != null:
instance.size = value
instance.terrain_map = ImageTexture.create_from_image(_image)
size = value
func _get_brush_area(point: Vector2i, mask_size: Vector2i, 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.
var scaled_mask_size := Vector2i(mask_size * scale)
var scaled_mask_size := Vector2i(mask_size * mask_scale)
return Rect2i((point + Vector2i(size * 0.5)) - Vector2i(scaled_mask_size * 0.5), scaled_mask_size)
return Rect2i((point + Vector2i(get_size() * 0.5)) - Vector2i(scaled_mask_size * 0.5), scaled_mask_size)
func _init() -> void:
clear(BLANK)
super._init()
_editable_image = Image.create(1, 1, false, Image.FORMAT_RGBAF)
_editable_texture = ImageTexture.create_from_image(_editable_image)
super.resize(Vector2i.ONE)
##
## Clears the image to the value of [code]clear_color[/code].
## Clears the terrain map to the value of [code]clear_elevation[/code].
##
func clear(clear_color: Color) -> void:
_image.fill(clear_color)
if instance != null:
instance.terrain_map.update(_image)
func clear(clear_elevation: float) -> void:
_editable_image.fill(Color(0.0, 0.0, 0.0, clampf(clear_elevation, 0.0, 1.0)))
_editable_texture.update(_editable_image)
##
##
##
func oscillate(point: Vector2i, level: float,
mask: Image, scale: float, intensity: float, delta: float) -> void:
mask: Image, mask_scale: float, intensity: float, delta: float) -> void:
var mask_size := mask.get_size()
var brush_source := _get_brush_area(point, mask_size, scale)
var brush_source := _get_brush_area(point, mask_size, mask_scale)
if brush_source.has_area():
var brush_target := Rect2i(Vector2i.ZERO, size).intersection(brush_source)
var brush_target := Rect2i(Vector2i.ZERO, get_size()).intersection(brush_source)
if brush_target.has_area():
var mask_ratio := mask_size / brush_source.size
@ -75,26 +51,25 @@ func oscillate(point: Vector2i, level: float,
for x in brush_target.size.x:
var coord := brush_target.position + Vector2i(x, y)
var pixel := _image.get_pixelv(coord)
var pixel := _editable_image.get_pixelv(coord)
_image.set_pixelv(coord, Color(pixel.r, pixel.g, pixel.b,
_editable_image.set_pixelv(coord, Color(pixel.r, pixel.g, pixel.b,
lerpf(pixel.a, level, intensity * delta *\
mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a)).clamp())
if instance != null:
instance.terrain_map.update(_image)
_editable_texture.update(_editable_image)
##
##
##
func paint(point: Vector2i, color: Color,
mask: Image, scale: float, intensity: float, delta: float) -> void:
mask: Image, mask_scale: float, intensity: float, delta: float) -> void:
var mask_size := mask.get_size()
var brush_source := _get_brush_area(point, mask_size, scale)
var brush_source := _get_brush_area(point, mask_size, mask_scale)
if brush_source.has_area():
var brush_target := Rect2i(Vector2i.ZERO, size).intersection(brush_source)
var brush_target := Rect2i(Vector2i.ZERO, get_size()).intersection(brush_source)
if brush_target.has_area():
var mask_ratio := mask_size / brush_source.size
@ -105,18 +80,31 @@ func paint(point: Vector2i, color: Color,
for x in brush_target.size.x:
var coord := brush_target.position + Vector2i(x, y)
var pixel := _image.get_pixelv(coord)
var pixel := _editable_image.get_pixelv(coord)
var mask_intensity_delta := intensity * delta *\
mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a
_image.set_pixelv(coord, Color(
_editable_image.set_pixelv(coord, Color(
lerpf(pixel.r, color.r, mask_intensity_delta),
lerpf(pixel.g, color.g, mask_intensity_delta),
lerpf(pixel.b, color.b, mask_intensity_delta), pixel.a).clamp())
if instance != null:
instance.terrain_map.update(_image)
_editable_texture.update(_editable_image)
##
##
##
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
@ -126,9 +114,10 @@ func paint(point: Vector2i, color: Color,
## instead.
##
func sample(point: Vector2i) -> Color:
var size := get_size()
var image_point := point + Vector2i(size * 0.5)
if Rect2i(Vector2i.ZERO, size).has_point(image_point):
return _image.get_pixelv(image_point)
return _editable_image.get_pixelv(image_point)
return BLANK

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://jcmf7j3qo6ea"
path="res://.godot/imported/arid_grass_albedo.png-cac7ceff15cf65e54d8ee36a70e05853.ctex"
path="res://.godot/imported/arid_grass_albedo.png-532bc188063dc524e2c08228bed13fa7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/arid_grass_albedo.png"
dest_files=["res://.godot/imported/arid_grass_albedo.png-cac7ceff15cf65e54d8ee36a70e05853.ctex"]
source_file="res://terrain/paints/arid_grass_albedo.png"
dest_files=["res://.godot/imported/arid_grass_albedo.png-532bc188063dc524e2c08228bed13fa7.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://co0jompch208v"
path="res://.godot/imported/arid_grass_displacement.png-66c8c71a36e11168aed23cd0531ba7bd.ctex"
path="res://.godot/imported/arid_grass_displacement.png-cad938b62195c0b0f41099d596594b8b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/arid_grass_displacement.png"
dest_files=["res://.godot/imported/arid_grass_displacement.png-66c8c71a36e11168aed23cd0531ba7bd.ctex"]
source_file="res://terrain/paints/arid_grass_displacement.png"
dest_files=["res://.godot/imported/arid_grass_displacement.png-cad938b62195c0b0f41099d596594b8b.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bh141jkgbmya8"
path="res://.godot/imported/arid_grass_normal.png-6cfb96e0a0b1eac890998accab9c7109.ctex"
path="res://.godot/imported/arid_grass_normal.png-7bf9fdf5f927fea47a2f86a9ffab326e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/arid_grass_normal.png"
dest_files=["res://.godot/imported/arid_grass_normal.png-6cfb96e0a0b1eac890998accab9c7109.ctex"]
source_file="res://terrain/paints/arid_grass_normal.png"
dest_files=["res://.godot/imported/arid_grass_normal.png-7bf9fdf5f927fea47a2f86a9ffab326e.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://jdq8kwjo3uap"
path="res://.godot/imported/arid_grass_roughness.png-8ff0f34a3348350d0edc5e43b43bcd0e.ctex"
path="res://.godot/imported/arid_grass_roughness.png-40299cbb0e24b392d013d45af79f5444.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/arid_grass_roughness.png"
dest_files=["res://.godot/imported/arid_grass_roughness.png-8ff0f34a3348350d0edc5e43b43bcd0e.ctex"]
source_file="res://terrain/paints/arid_grass_roughness.png"
dest_files=["res://.godot/imported/arid_grass_roughness.png-40299cbb0e24b392d013d45af79f5444.ctex"]
[params]

BIN
terrain/paints/arid_grass_terrain_paint.res (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cs06oiwrord6t"
path="res://.godot/imported/cobbled_limestone_albedo.png-cbafb40d3c6fc43ce00d68cb02456536.ctex"
path="res://.godot/imported/cobblestone_albedo.png-f0ce6b9d25b0c6c4130e70ff660bcbd6.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/cobbled_limestone_albedo.png"
dest_files=["res://.godot/imported/cobbled_limestone_albedo.png-cbafb40d3c6fc43ce00d68cb02456536.ctex"]
source_file="res://terrain/paints/cobblestone_albedo.png"
dest_files=["res://.godot/imported/cobblestone_albedo.png-f0ce6b9d25b0c6c4130e70ff660bcbd6.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://mkxbjfwdwkaq"
path="res://.godot/imported/cobbled_limestone_displacement.png-8e8b27438ff815a9d58d4a490e04203c.ctex"
path="res://.godot/imported/cobblestone_displacement.png-bcf2e2194862b85cb002d9559d57903b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/cobbled_limestone_displacement.png"
dest_files=["res://.godot/imported/cobbled_limestone_displacement.png-8e8b27438ff815a9d58d4a490e04203c.ctex"]
source_file="res://terrain/paints/cobblestone_displacement.png"
dest_files=["res://.godot/imported/cobblestone_displacement.png-bcf2e2194862b85cb002d9559d57903b.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://ukk0161x3eg2"
path="res://.godot/imported/cobbled_limestone_normal.png-4d7b2eb9c070e06256eb42d408ff4a14.ctex"
path="res://.godot/imported/cobblestone_normal.png-5130e667fa81f7452d15808908f4cb99.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/cobbled_limestone_normal.png"
dest_files=["res://.godot/imported/cobbled_limestone_normal.png-4d7b2eb9c070e06256eb42d408ff4a14.ctex"]
source_file="res://terrain/paints/cobblestone_normal.png"
dest_files=["res://.godot/imported/cobblestone_normal.png-5130e667fa81f7452d15808908f4cb99.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bcybapft8tl2x"
path="res://.godot/imported/cobbled_limestone_roughness.png-f78cac7004d15ddc2a00fd10f74b8c10.ctex"
path="res://.godot/imported/cobblestone_roughness.png-2f09da1d7000b898b80d7b177062e509.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/cobbled_limestone_roughness.png"
dest_files=["res://.godot/imported/cobbled_limestone_roughness.png-f78cac7004d15ddc2a00fd10f74b8c10.ctex"]
source_file="res://terrain/paints/cobblestone_roughness.png"
dest_files=["res://.godot/imported/cobblestone_roughness.png-2f09da1d7000b898b80d7b177062e509.ctex"]
[params]

BIN
terrain/paints/cobblestone_terrain_paint.res (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -3,8 +3,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bgpk15qrqxly8"
path.s3tc="res://.godot/imported/default_albedo.png-92a6d62c2ead547c4c35766bdeaf9065.s3tc.ctex"
path.etc2="res://.godot/imported/default_albedo.png-92a6d62c2ead547c4c35766bdeaf9065.etc2.ctex"
path.s3tc="res://.godot/imported/default_albedo.png-ec7b9bee606a4c8482c5f21d50eaafb2.s3tc.ctex"
path.etc2="res://.godot/imported/default_albedo.png-ec7b9bee606a4c8482c5f21d50eaafb2.etc2.ctex"
metadata={
"imported_formats": ["s3tc", "etc2"],
"vram_texture": true
@ -12,8 +12,8 @@ metadata={
[deps]
source_file="res://terrain/default_albedo.png"
dest_files=["res://.godot/imported/default_albedo.png-92a6d62c2ead547c4c35766bdeaf9065.s3tc.ctex", "res://.godot/imported/default_albedo.png-92a6d62c2ead547c4c35766bdeaf9065.etc2.ctex"]
source_file="res://terrain/paints/default_albedo.png"
dest_files=["res://.godot/imported/default_albedo.png-ec7b9bee606a4c8482c5f21d50eaafb2.s3tc.ctex", "res://.godot/imported/default_albedo.png-ec7b9bee606a4c8482c5f21d50eaafb2.etc2.ctex"]
[params]

BIN
terrain/paints/default_terrain_paint.res (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://b8cv4q43fsglu"
path="res://.godot/imported/desert_sand_albedo.png-5307ce3455129127b5c6f3a135f5cbc7.ctex"
path="res://.godot/imported/desert_sand_albedo.png-1f8394c37b6df0b83ddc4964049fe1fb.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/desert_sand_albedo.png"
dest_files=["res://.godot/imported/desert_sand_albedo.png-5307ce3455129127b5c6f3a135f5cbc7.ctex"]
source_file="res://terrain/paints/desert_sand_albedo.png"
dest_files=["res://.godot/imported/desert_sand_albedo.png-1f8394c37b6df0b83ddc4964049fe1fb.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bdacir1igfinb"
path="res://.godot/imported/desert_sand_displacement.png-3674eb6c274d21b1ddd14b8c6ce982fe.ctex"
path="res://.godot/imported/desert_sand_displacement.png-de6822961a581feed0d45f5f34fbb048.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/desert_sand_displacement.png"
dest_files=["res://.godot/imported/desert_sand_displacement.png-3674eb6c274d21b1ddd14b8c6ce982fe.ctex"]
source_file="res://terrain/paints/desert_sand_displacement.png"
dest_files=["res://.godot/imported/desert_sand_displacement.png-de6822961a581feed0d45f5f34fbb048.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://c40cc5b5sq4yu"
path="res://.godot/imported/desert_sand_normal.png-9b37ed7fc3712ce013db97500f604934.ctex"
path="res://.godot/imported/desert_sand_normal.png-4882d77c1942a502a8d07cd8761a392c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/desert_sand_normal.png"
dest_files=["res://.godot/imported/desert_sand_normal.png-9b37ed7fc3712ce013db97500f604934.ctex"]
source_file="res://terrain/paints/desert_sand_normal.png"
dest_files=["res://.godot/imported/desert_sand_normal.png-4882d77c1942a502a8d07cd8761a392c.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bwkcsnjetn5wr"
path="res://.godot/imported/desert_sand_roughness.png-c85e29a6965b06eac0c712e74b047821.ctex"
path="res://.godot/imported/desert_sand_roughness.png-0c32daf878e9b29d36631441877f21ac.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/desert_sand_roughness.png"
dest_files=["res://.godot/imported/desert_sand_roughness.png-c85e29a6965b06eac0c712e74b047821.ctex"]
source_file="res://terrain/paints/desert_sand_roughness.png"
dest_files=["res://.godot/imported/desert_sand_roughness.png-0c32daf878e9b29d36631441877f21ac.ctex"]
[params]

BIN
terrain/paints/desert_sand_terrain_paint.res (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://eqbk8dx3px02"
path="res://.godot/imported/dry_mud_albedo.png-0fe12d446fc4e93e2a42ccc9303ac693.ctex"
path="res://.godot/imported/dry_mud_albedo.png-6844f23cea910070ff2cf0d2e02e4e06.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/dry_mud_albedo.png"
dest_files=["res://.godot/imported/dry_mud_albedo.png-0fe12d446fc4e93e2a42ccc9303ac693.ctex"]
source_file="res://terrain/paints/dry_mud_albedo.png"
dest_files=["res://.godot/imported/dry_mud_albedo.png-6844f23cea910070ff2cf0d2e02e4e06.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bwqtubithbfsy"
path="res://.godot/imported/dry_mud_displacement.png-459305492d2f8cba90344ad67808cc02.ctex"
path="res://.godot/imported/dry_mud_displacement.png-84ac0ae4e00848577ccfe89d2c4787e8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/dry_mud_displacement.png"
dest_files=["res://.godot/imported/dry_mud_displacement.png-459305492d2f8cba90344ad67808cc02.ctex"]
source_file="res://terrain/paints/dry_mud_displacement.png"
dest_files=["res://.godot/imported/dry_mud_displacement.png-84ac0ae4e00848577ccfe89d2c4787e8.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://c86r5niid1hp1"
path="res://.godot/imported/dry_mud_normal.png-bbedc7a55f837a837bfdab39fcbc7272.ctex"
path="res://.godot/imported/dry_mud_normal.png-6211d1992b291d2e0174ec9de201218d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/dry_mud_normal.png"
dest_files=["res://.godot/imported/dry_mud_normal.png-bbedc7a55f837a837bfdab39fcbc7272.ctex"]
source_file="res://terrain/paints/dry_mud_normal.png"
dest_files=["res://.godot/imported/dry_mud_normal.png-6211d1992b291d2e0174ec9de201218d.ctex"]
[params]

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://7xnkstxa6q65"
path="res://.godot/imported/dry_mud_roughness.png-0d5a4572411f8d454ef69ed8b252672b.ctex"
path="res://.godot/imported/dry_mud_roughness.png-35dfe15111e09484a06efd2f6e55b73b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/dry_mud_roughness.png"
dest_files=["res://.godot/imported/dry_mud_roughness.png-0d5a4572411f8d454ef69ed8b252672b.ctex"]
source_file="res://terrain/paints/dry_mud_roughness.png"
dest_files=["res://.godot/imported/dry_mud_roughness.png-35dfe15111e09484a06efd2f6e55b73b.ctex"]
[params]

BIN
terrain/paints/dry_mud_terrain_paint.res (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,13 @@
class_name TerrainPaint extends Resource
##
##
##
@export
var albedo_map: Texture2D = null
##
##
##
@export
var normal_map: Texture2D = null

57
terrain/terrain.gdshader Normal file
View File

@ -0,0 +1,57 @@
shader_type spatial;
const int MAP_COUNT = 4;
uniform sampler2D[MAP_COUNT] ALBEDO_MAPS;
uniform float MAX_HEIGHT = 100.0;
uniform sampler2D[MAP_COUNT] NORMAL_MAPS;
uniform vec2 SIZE;
uniform sampler2D TERRAIN_MAP : hint_default_transparent, repeat_disable;
void fragment() {
vec2 uv = UV * (SIZE / 2.0);
vec2 uv_alt = uv * -0.5;
vec3 splat_map = texture(TERRAIN_MAP, UV).rgb;
float blank = clamp(1.0 - splat_map.r - splat_map.g - splat_map.b, 0.0, 1.0);
ALBEDO = blank * 0.5 * (texture(ALBEDO_MAPS[0], uv).rgb + texture(ALBEDO_MAPS[0], uv_alt).rgb);
for (int i = 0; i < (MAP_COUNT - 1); i += 1) {
int map_index = i + 1;
ALBEDO += splat_map[i] * 0.5 * (texture(ALBEDO_MAPS[map_index], uv).rgb +
texture(ALBEDO_MAPS[map_index], uv_alt).rgb);
}
NORMAL_MAP = blank * 0.5 *
(texture(NORMAL_MAPS[0], uv).rgb + texture(NORMAL_MAPS[0], uv_alt).rgb);
for (int i = 0; i < (MAP_COUNT - 1); i += 1) {
int map_index = i + 1;
NORMAL_MAP += splat_map[i] * 0.5 * (texture(NORMAL_MAPS[map_index], uv).rgb +
texture(NORMAL_MAPS[map_index], uv_alt).rgb);
}
}
float height(vec2 uv) {
return MAX_HEIGHT * texture(TERRAIN_MAP, uv).a;
}
void vertex() {
VERTEX.y = height(UV);
vec2 texel_size = UV / SIZE;
vec4 h = vec4(
height(UV + (texel_size * vec2(0, -1))),
height(UV + (texel_size * vec2(-1, 0))),
height(UV + (texel_size * vec2( 1, 0))),
height(UV + (texel_size * vec2( 0, 1))));
NORMAL = normalize(vec3(h.y - h.z, 2.0, h.x - h.w));
}

View File

@ -1,169 +1,87 @@
@tool
class_name TerrainInstance3D extends GeometryInstance3D
##
## Identifier constant for a paint slot channel.
##
enum PaintSlot {
ERASE,
RED,
GREEN,
BLUE,
}
const _DETAIL := 2
var _mesh := PlaneMesh.new()
var _albedo_map_textures: Array[Texture2D] = [null, null, null, null]
var _material := ShaderMaterial.new()
var _normal_map_textures: Array[Texture2D] = [null, null, null, null]
var _mesh := PlaneMesh.new()
##
##
## The height scale range that is used to determine the minimums and maximums of the terrain map.
##
@export
var size: Vector2i = Vector2i.ZERO:
var height_scale := 100.0:
get:
return size
return height_scale
set(value):
var width := maxi(value.x, 0)
var height := maxi(value.y, 0)
_material.set_shader_parameter("MAX_HEIGHT", value)
if (width != size.x) or (height != size.y):
if (width == 0) and (height == 0):
RenderingServer.instance_set_base(self.get_instance(), RID())
height_scale = max(value, 0.0)
else:
self._mesh.subdivide_width = width * _DETAIL
self._mesh.subdivide_depth = height * _DETAIL
self._mesh.size = value
self._material.set_shader_parameter("SIZE", Vector2(value))
RenderingServer.instance_set_base(self.get_instance(), self._mesh)
size = value
##
##
##
@export
var albedo_map: Texture2D = null:
get:
return albedo_map
set(value):
self._material.set_shader_parameter("ALBEDO_MAP_0", value)
albedo_map = value
##
##
##
@export
var albedo_map_b: Texture2D = null:
get:
return albedo_map_b
set(value):
self._material.set_shader_parameter("ALBEDO_MAP_B", value)
albedo_map_b = value
##
##
##
@export
var albedo_map_g: Texture2D = null:
get:
return albedo_map_g
set(value):
self._material.set_shader_parameter("ALBEDO_MAP_G", value)
albedo_map_g = value
##
##
##
@export
var albedo_map_r: Texture2D = null:
get:
return albedo_map_r
set(value):
self._material.set_shader_parameter("ALBEDO_MAP_R", value)
albedo_map_r = value
##
##
##
@export
var normal_map: Texture2D = null:
get:
return normal_map
set(value):
self._material.set_shader_parameter("NORMAL_MAP_0", value)
normal_map = value
##
##
##
@export
var normal_map_b: Texture2D = null:
get:
return normal_map_b
set(value):
self._material.set_shader_parameter("NORMAL_MAP_B", value)
normal_map_b = value
##
##
##
@export
var normal_map_g: Texture2D = null:
get:
return normal_map_g
set(value):
self._material.set_shader_parameter("NORMAL_MAP_G", value)
normal_map_g = value
##
##
##
@export
var normal_map_r: Texture2D = null:
get:
return normal_map_r
set(value):
self._material.set_shader_parameter("NORMAL_MAP_R", value)
normal_map_r = value
##
##
##
@export
var terrain_map: Texture2D = null:
get:
return terrain_map
set(value):
self._material.set_shader_parameter("TERRAIN_MAP", value)
terrain_map = value
##
##
##
@export
var max_height := 100.0:
get:
return max_height
set(value):
self._material.set_shader_parameter("MAX_HEIGHT", value)
max_height = max(value, 0.0)
var _size := Vector2i.ZERO
func _init() -> void:
self._material.shader = preload("res://terrain/terrain_shader.gdshader")
_material.shader = preload("res://terrain/terrain.gdshader")
self._mesh.surface_set_material(0, self._material)
RenderingServer.instance_set_base(get_instance(), _mesh)
_mesh.surface_set_material(0, _material)
##
## Returns the size of the terrain mesh (as in-engine units).
##
func get_size() -> Vector2i:
return _size
##
## Attempts to resize the terrain to be equal to [code]size[/code] (in-engine units), with
## [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].
##
func update_paint(paint_slot: PaintSlot, paint: TerrainPaint) -> void:
if paint == null:
_albedo_map_textures[paint_slot] = null
_normal_map_textures[paint_slot] = null
else:
_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)
_material.set_shader_parameter("NORMAL_MAPS", _normal_map_textures)
##
## Updates the terrain map to [code]terrain_map[/code].
##
func update_terrain(terrain_map: Texture2D) -> void:
_material.set_shader_parameter("TERRAIN_MAP", terrain_map)

View File

@ -1,58 +0,0 @@
shader_type spatial;
uniform sampler2D ALBEDO_MAP_0 : hint_default_black;
uniform sampler2D ALBEDO_MAP_R : hint_default_black;
uniform sampler2D ALBEDO_MAP_G : hint_default_black;
uniform sampler2D ALBEDO_MAP_B : hint_default_black;
uniform float MAX_HEIGHT = 100.0;
uniform sampler2D NORMAL_MAP_0 : hint_default_black;
uniform sampler2D NORMAL_MAP_R : hint_default_black;
uniform sampler2D NORMAL_MAP_G : hint_default_black;
uniform sampler2D NORMAL_MAP_B : hint_default_black;
uniform vec2 SIZE;
uniform sampler2D TERRAIN_MAP : hint_default_transparent, repeat_disable;
void fragment() {
vec2 uv = UV * (SIZE / 2.0);
vec2 uv_alt = uv * -0.5;
vec3 splat_map = texture(TERRAIN_MAP, UV).rgb;
float blank = clamp(1.0 - splat_map.r - splat_map.g - splat_map.b, 0.0, 1.0);
ALBEDO = blank * 0.5 * (texture(ALBEDO_MAP_0, uv).rgb + texture(ALBEDO_MAP_0, uv_alt).rgb);
ALBEDO += splat_map.r * 0.5 * (texture(ALBEDO_MAP_R, uv).rgb + texture(ALBEDO_MAP_R, uv_alt).rgb);
ALBEDO += splat_map.g * 0.5 * (texture(ALBEDO_MAP_G, uv).rgb + texture(ALBEDO_MAP_G, uv_alt).rgb);
ALBEDO += splat_map.b * 0.5 * (texture(ALBEDO_MAP_B, uv).rgb + texture(ALBEDO_MAP_B, uv_alt).rgb);
NORMAL_MAP = blank * 0.5 * (texture(NORMAL_MAP_0, uv).rgb + texture(NORMAL_MAP_0, uv_alt).rgb);
NORMAL_MAP += splat_map.r * 0.5 * (texture(NORMAL_MAP_R, uv).rgb + texture(NORMAL_MAP_R, uv_alt).rgb);
NORMAL_MAP += splat_map.g * 0.5 * (texture(NORMAL_MAP_G, uv).rgb + texture(NORMAL_MAP_G, uv_alt).rgb);
NORMAL_MAP += splat_map.b * 0.5 * (texture(NORMAL_MAP_B, uv).rgb + texture(NORMAL_MAP_B, uv_alt).rgb);
}
float height(vec2 uv) {
return MAX_HEIGHT * texture(TERRAIN_MAP, uv).a;
}
void vertex() {
VERTEX.y = height(UV);
vec2 texel_size = UV / SIZE;
vec4 h = vec4(
height(UV + (texel_size * vec2(0, -1))),
height(UV + (texel_size * vec2(-1, 0))),
height(UV + (texel_size * vec2( 1, 0))),
height(UV + (texel_size * vec2( 0, 1))));
NORMAL = normalize(vec3(h.y - h.z, 2.0, h.x - h.w));
}

BIN
user_interface/screen_cursor.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://crt8tmxbpu1hl"
path="res://.godot/imported/screen_cursor.png-46ebd33cd7dfb4c0211a698e6d39e483.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://user_interface/screen_cursor.png"
dest_files=["res://.godot/imported/screen_cursor.png-46ebd33cd7dfb4c0211a698e6d39e483.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