From 16571d6efae378a2ef8a3ff8950e0ebd8e327b54 Mon Sep 17 00:00:00 2001 From: kayomn Date: Thu, 12 Jan 2023 15:47:42 +0000 Subject: [PATCH 01/27] Replace hardcoded brush with support for raster brush masks --- brush_soft_mask.png | 3 +++ brush_soft_mask.png.import | 14 ++++++++++++ editor.scn | 4 ++-- terrain_cursor_emission.png | 3 --- terrain_cursor_emission.png.import | 36 ------------------------------ 5 files changed, 19 insertions(+), 41 deletions(-) create mode 100644 brush_soft_mask.png create mode 100644 brush_soft_mask.png.import delete mode 100644 terrain_cursor_emission.png delete mode 100644 terrain_cursor_emission.png.import diff --git a/brush_soft_mask.png b/brush_soft_mask.png new file mode 100644 index 0000000..6f52c3d --- /dev/null +++ b/brush_soft_mask.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b10ccded55e2a53b86a495fdcb501f5391bec01d478dae056d60474fcc13dc5 +size 1717 diff --git a/brush_soft_mask.png.import b/brush_soft_mask.png.import new file mode 100644 index 0000000..352c9d7 --- /dev/null +++ b/brush_soft_mask.png.import @@ -0,0 +1,14 @@ +[remap] + +importer="image" +type="Image" +uid="uid://bbdh4btpg08do" +path="res://.godot/imported/brush_soft_mask.png-211f364dba674d8d697543d1b1246d6a.image" + +[deps] + +source_file="res://brush_soft_mask.png" +dest_files=["res://.godot/imported/brush_soft_mask.png-211f364dba674d8d697543d1b1246d6a.image"] + +[params] + diff --git a/editor.scn b/editor.scn index 681b5de..aba5510 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2aa052c695e7875d548df6dc3fa6bf06f4294490d04a82bc4992923e959c4e8 -size 6597 +oid sha256:b93aced3d5e01f7a38c96c1138a98398171ffefafa481074d0776f351d76b904 +size 6649 diff --git a/terrain_cursor_emission.png b/terrain_cursor_emission.png deleted file mode 100644 index bdb6d4e..0000000 --- a/terrain_cursor_emission.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:495e7874b1a3d3c20fbf8644f5ca3242bea67ffe23775d349598876dd130df69 -size 27850 diff --git a/terrain_cursor_emission.png.import b/terrain_cursor_emission.png.import deleted file mode 100644 index 96764a5..0000000 --- a/terrain_cursor_emission.png.import +++ /dev/null @@ -1,36 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dmbae0p1ujwcv" -path.s3tc="res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.s3tc.ctex" -path.etc2="res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.etc2.ctex" -metadata={ -"imported_formats": ["s3tc", "etc2"], -"vram_texture": true -} - -[deps] - -source_file="res://terrain_cursor_emission.png" -dest_files=["res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.s3tc.ctex", "res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.etc2.ctex"] - -[params] - -compress/mode=2 -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/bptc_ldr=0 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=true -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=true -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=0 From 68308b4ea45f5b063d3a5fa83688726043c60f7a Mon Sep 17 00:00:00 2001 From: kayomn Date: Thu, 12 Jan 2023 15:55:09 +0000 Subject: [PATCH 02/27] Fix editor terrain brush cursor not visualising scale --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index aba5510..0e67f5a 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b93aced3d5e01f7a38c96c1138a98398171ffefafa481074d0776f351d76b904 -size 6649 +oid sha256:9269797759b845865f28b0a4214feafb26f714a20b8e0fafa7d3e2b057a9677f +size 6825 From 96c1d69e9c14a301ce3f7142e13905ab2fe78a27 Mon Sep 17 00:00:00 2001 From: kayomn Date: Thu, 12 Jan 2023 15:59:01 +0000 Subject: [PATCH 03/27] Fix inaccurate terrain smoothness sampling causing crash --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index 0e67f5a..5d0c16c 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9269797759b845865f28b0a4214feafb26f714a20b8e0fafa7d3e2b057a9677f -size 6825 +oid sha256:44983fe9c01b17d070c314e16abd4aeeec6f87a45bea3ced58a0c944d2cde5f0 +size 6829 From 2c6d01f146b2072603a0ef7abc5cee929e318d0c Mon Sep 17 00:00:00 2001 From: kayomn Date: Thu, 12 Jan 2023 16:05:19 +0000 Subject: [PATCH 04/27] Fix unchecked division by zero when painting terrain --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index 5d0c16c..00ca9cd 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44983fe9c01b17d070c314e16abd4aeeec6f87a45bea3ced58a0c944d2cde5f0 -size 6829 +oid sha256:8901e35c58da7c05043e0211e60df9bae3610c340de473305610ee1648587b11 +size 6828 From 0ab18050ad0d1c3ccf49edd5aa28ebb5dbd8dcd0 Mon Sep 17 00:00:00 2001 From: kayomn Date: Thu, 12 Jan 2023 16:52:33 +0000 Subject: [PATCH 05/27] Fix terrain brush always being active --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index 00ca9cd..a608282 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8901e35c58da7c05043e0211e60df9bae3610c340de473305610ee1648587b11 -size 6828 +oid sha256:97bb96d844de0fd20acaa3c96dc809913496dd41da46dd0024ef7bb98f07f914 +size 6834 From 1765ed9947f3ee9d5bdc4b5407dfcc503e68e2fa Mon Sep 17 00:00:00 2001 From: kayomn Date: Fri, 13 Jan 2023 00:36:09 +0000 Subject: [PATCH 06/27] Add initial support for hardcoded terrain switching --- brush_soft_mask.png.import | 14 ---- editor.scn | 4 +- .../brush_soft_mask.png | 0 editor/brush_soft_mask.png.import | 14 ++++ editor_theme.res => editor/menus_theme.res | 0 .../default_albedo.png | 0 .../default_albedo.png.import | 8 +-- terrain/desert_sand_albedo.png | 3 + terrain/desert_sand_albedo.png.import | 34 ++++++++++ terrain/desert_sand_depth.png | 3 + terrain/desert_sand_depth.png.import | 34 ++++++++++ terrain/desert_sand_normal.png | 3 + terrain/desert_sand_normal.png.import | 34 ++++++++++ terrain_instance_3d.gd | 64 +++++++++---------- terrain_shader.gdshader | 40 ++++++------ 15 files changed, 183 insertions(+), 72 deletions(-) delete mode 100644 brush_soft_mask.png.import rename brush_soft_mask.png => editor/brush_soft_mask.png (100%) create mode 100644 editor/brush_soft_mask.png.import rename editor_theme.res => editor/menus_theme.res (100%) rename prototype_tiles_large_albedo.png => terrain/default_albedo.png (100%) rename prototype_tiles_large_albedo.png.import => terrain/default_albedo.png.import (54%) create mode 100644 terrain/desert_sand_albedo.png create mode 100644 terrain/desert_sand_albedo.png.import create mode 100644 terrain/desert_sand_depth.png create mode 100644 terrain/desert_sand_depth.png.import create mode 100644 terrain/desert_sand_normal.png create mode 100644 terrain/desert_sand_normal.png.import diff --git a/brush_soft_mask.png.import b/brush_soft_mask.png.import deleted file mode 100644 index 352c9d7..0000000 --- a/brush_soft_mask.png.import +++ /dev/null @@ -1,14 +0,0 @@ -[remap] - -importer="image" -type="Image" -uid="uid://bbdh4btpg08do" -path="res://.godot/imported/brush_soft_mask.png-211f364dba674d8d697543d1b1246d6a.image" - -[deps] - -source_file="res://brush_soft_mask.png" -dest_files=["res://.godot/imported/brush_soft_mask.png-211f364dba674d8d697543d1b1246d6a.image"] - -[params] - diff --git a/editor.scn b/editor.scn index a608282..d4a8843 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97bb96d844de0fd20acaa3c96dc809913496dd41da46dd0024ef7bb98f07f914 -size 6834 +oid sha256:b841803f8745cadd71a2e9ae8c0eeae8f2a5a449558dca5a24f43d87a904c312 +size 7748 diff --git a/brush_soft_mask.png b/editor/brush_soft_mask.png similarity index 100% rename from brush_soft_mask.png rename to editor/brush_soft_mask.png diff --git a/editor/brush_soft_mask.png.import b/editor/brush_soft_mask.png.import new file mode 100644 index 0000000..187ed45 --- /dev/null +++ b/editor/brush_soft_mask.png.import @@ -0,0 +1,14 @@ +[remap] + +importer="image" +type="Image" +uid="uid://bbdh4btpg08do" +path="res://.godot/imported/brush_soft_mask.png-cec601fece9e15b1942ebb0d73b51015.image" + +[deps] + +source_file="res://editor/brush_soft_mask.png" +dest_files=["res://.godot/imported/brush_soft_mask.png-cec601fece9e15b1942ebb0d73b51015.image"] + +[params] + diff --git a/editor_theme.res b/editor/menus_theme.res similarity index 100% rename from editor_theme.res rename to editor/menus_theme.res diff --git a/prototype_tiles_large_albedo.png b/terrain/default_albedo.png similarity index 100% rename from prototype_tiles_large_albedo.png rename to terrain/default_albedo.png diff --git a/prototype_tiles_large_albedo.png.import b/terrain/default_albedo.png.import similarity index 54% rename from prototype_tiles_large_albedo.png.import rename to terrain/default_albedo.png.import index 073e101..3be27a2 100644 --- a/prototype_tiles_large_albedo.png.import +++ b/terrain/default_albedo.png.import @@ -3,8 +3,8 @@ importer="texture" type="CompressedTexture2D" uid="uid://bgpk15qrqxly8" -path.s3tc="res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.s3tc.ctex" -path.etc2="res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.etc2.ctex" +path.s3tc="res://.godot/imported/default_albedo.png-92a6d62c2ead547c4c35766bdeaf9065.s3tc.ctex" +path.etc2="res://.godot/imported/default_albedo.png-92a6d62c2ead547c4c35766bdeaf9065.etc2.ctex" metadata={ "imported_formats": ["s3tc", "etc2"], "vram_texture": true @@ -12,8 +12,8 @@ metadata={ [deps] -source_file="res://prototype_tiles_large_albedo.png" -dest_files=["res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.s3tc.ctex", "res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.etc2.ctex"] +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"] [params] diff --git a/terrain/desert_sand_albedo.png b/terrain/desert_sand_albedo.png new file mode 100644 index 0000000..10b6a16 --- /dev/null +++ b/terrain/desert_sand_albedo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:620d5c5b1421ee188681e1f2dd184b56787c9225b1f606f13802b64de0fdf811 +size 3433382 diff --git a/terrain/desert_sand_albedo.png.import b/terrain/desert_sand_albedo.png.import new file mode 100644 index 0000000..783a2e1 --- /dev/null +++ b/terrain/desert_sand_albedo.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b8cv4q43fsglu" +path="res://.godot/imported/desert_sand_albedo.png-5307ce3455129127b5c6f3a135f5cbc7.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"] + +[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 diff --git a/terrain/desert_sand_depth.png b/terrain/desert_sand_depth.png new file mode 100644 index 0000000..6aa3a34 --- /dev/null +++ b/terrain/desert_sand_depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:299d87da87ba51e2bef7963fe0f7a393a0028b91a01c7f7b334ff553542f9798 +size 3749261 diff --git a/terrain/desert_sand_depth.png.import b/terrain/desert_sand_depth.png.import new file mode 100644 index 0000000..0fecb9c --- /dev/null +++ b/terrain/desert_sand_depth.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cb4ldm1dda1bo" +path="res://.godot/imported/desert_sand_depth.png-add0a002b33efe8fd04b2cf4bf524515.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://terrain/desert_sand_depth.png" +dest_files=["res://.godot/imported/desert_sand_depth.png-add0a002b33efe8fd04b2cf4bf524515.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 diff --git a/terrain/desert_sand_normal.png b/terrain/desert_sand_normal.png new file mode 100644 index 0000000..4bd2790 --- /dev/null +++ b/terrain/desert_sand_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b79420ad4ad1863b9b82dbe8ee93fdbac60f693c1a0842afe6969d552c21697b +size 10321853 diff --git a/terrain/desert_sand_normal.png.import b/terrain/desert_sand_normal.png.import new file mode 100644 index 0000000..6efdb8b --- /dev/null +++ b/terrain/desert_sand_normal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c40cc5b5sq4yu" +path="res://.godot/imported/desert_sand_normal.png-9b37ed7fc3712ce013db97500f604934.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"] + +[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 diff --git a/terrain_instance_3d.gd b/terrain_instance_3d.gd index f70fcaa..361ce96 100644 --- a/terrain_instance_3d.gd +++ b/terrain_instance_3d.gd @@ -37,105 +37,105 @@ var size: Vector2i = Vector2i.ZERO: ## ## @export -var layer_1_albedo: Texture2D = null: +var albedo_map: Texture2D = null: get: - return layer_1_albedo + return albedo_map set(value): - self._material.set_shader_parameter("LAYER_1_ALBEDO", value) + self._material.set_shader_parameter("ALBEDO_MAP_0", value) - layer_1_albedo = value + albedo_map = value ## ## ## @export -var layer_1_normal_map: Texture2D = null: +var albedo_map_b: Texture2D = null: get: - return layer_1_normal_map + return albedo_map_b set(value): - self._material.set_shader_parameter("LAYER_1_NORMAL_MAP", value) + self._material.set_shader_parameter("ALBEDO_MAP_B", value) - layer_1_normal_map = value + albedo_map_b = value ## ## ## @export -var layer_2_albedo: Texture2D = null: +var albedo_map_g: Texture2D = null: get: - return layer_2_albedo + return albedo_map_g set(value): - self._material.set_shader_parameter("LAYER_2_ALBEDO", value) + self._material.set_shader_parameter("ALBEDO_MAP_G", value) - layer_2_albedo = value + albedo_map_g = value ## ## ## @export -var layer_2_normal_map: Texture2D = null: +var albedo_map_r: Texture2D = null: get: - return layer_2_normal_map + return albedo_map_r set(value): - self._material.set_shader_parameter("LAYER_2_NORMAL_MAP", value) + self._material.set_shader_parameter("ALBEDO_MAP_R", value) - layer_2_normal_map = value + albedo_map_r = value ## ## ## @export -var layer_3_albedo: Texture2D = null: +var normal_map: Texture2D = null: get: - return layer_3_albedo + return normal_map set(value): - self._material.set_shader_parameter("LAYER_3_ALBEDO", value) + self._material.set_shader_parameter("NORMAL_MAP_0", value) - layer_3_albedo = value + normal_map = value ## ## ## @export -var layer_3_normal_map: Texture2D = null: +var normal_map_b: Texture2D = null: get: - return layer_3_normal_map + return normal_map_b set(value): - self._material.set_shader_parameter("LAYER_3_NORMAL_MAP", value) + self._material.set_shader_parameter("NORMAL_MAP_B", value) - layer_3_normal_map = value + normal_map_b = value ## ## ## @export -var layer_4_albedo: Texture2D = null: +var normal_map_g: Texture2D = null: get: - return layer_4_albedo + return normal_map_g set(value): - self._material.set_shader_parameter("LAYER_4_ALBEDO", value) + self._material.set_shader_parameter("NORMAL_MAP_G", value) - layer_4_albedo = value + normal_map_g = value ## ## ## @export -var layer_4_normal_map: Texture2D = null: +var normal_map_r: Texture2D = null: get: - return layer_4_normal_map + return normal_map_r set(value): - self._material.set_shader_parameter("LAYER_4_NORMAL_MAP", value) + self._material.set_shader_parameter("ALBEDO_MAP_R", value) - layer_4_normal_map = value + normal_map_r = value ## ## diff --git a/terrain_shader.gdshader b/terrain_shader.gdshader index dfac4b8..933a6cf 100644 --- a/terrain_shader.gdshader +++ b/terrain_shader.gdshader @@ -1,23 +1,23 @@ shader_type spatial; -uniform sampler2D LAYER_1_ALBEDO : hint_default_black; +uniform sampler2D ALBEDO_MAP_0 : hint_default_black; -uniform sampler2D LAYER_1_NORMAL_MAP : hint_default_black; +uniform sampler2D ALBEDO_MAP_R : hint_default_black; -uniform sampler2D LAYER_2_ALBEDO : hint_default_black; +uniform sampler2D ALBEDO_MAP_G : hint_default_black; -uniform sampler2D LAYER_2_NORMAL_MAP : hint_default_black; - -uniform sampler2D LAYER_3_ALBEDO : hint_default_black; - -uniform sampler2D LAYER_3_NORMAL_MAP : hint_default_black; - -uniform sampler2D LAYER_4_ALBEDO : hint_default_black; - -uniform sampler2D LAYER_4_NORMAL_MAP : 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; @@ -28,15 +28,15 @@ void fragment() { 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(LAYER_1_ALBEDO, uv).rgb + texture(LAYER_1_ALBEDO, uv_alt).rgb); - ALBEDO += splat_map.r * 0.5 * (texture(LAYER_2_ALBEDO, uv).rgb + texture(LAYER_2_ALBEDO, uv_alt).rgb); - ALBEDO += splat_map.g * 0.5 * (texture(LAYER_3_ALBEDO, uv).rgb + texture(LAYER_3_ALBEDO, uv_alt).rgb); - ALBEDO += splat_map.b * 0.5 * (texture(LAYER_4_ALBEDO, uv).rgb + texture(LAYER_4_ALBEDO, uv_alt).rgb); + 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(LAYER_1_NORMAL_MAP, uv).rgb + texture(LAYER_1_NORMAL_MAP, uv_alt).rgb); - NORMAL_MAP += splat_map.r * 0.5 * (texture(LAYER_1_NORMAL_MAP, uv).rgb + texture(LAYER_2_NORMAL_MAP, uv_alt).rgb); - NORMAL_MAP += splat_map.g * 0.5 * (texture(LAYER_2_NORMAL_MAP, uv).rgb + texture(LAYER_3_NORMAL_MAP, uv_alt).rgb); - NORMAL_MAP += splat_map.b * 0.5 * (texture(LAYER_3_NORMAL_MAP, uv).rgb + texture(LAYER_4_NORMAL_MAP, 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) { From 808a3a2c3ef0d192f88e543a6654386aeb095845 Mon Sep 17 00:00:00 2001 From: kayomn Date: Fri, 13 Jan 2023 00:46:09 +0000 Subject: [PATCH 07/27] Make terrain edit menu close when the 'new' button is clicked --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index d4a8843..b5481be 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b841803f8745cadd71a2e9ae8c0eeae8f2a5a449558dca5a24f43d87a904c312 -size 7748 +oid sha256:4a4c758a9efa9c039e4eee380f93e038c4163c673871385bbc170480c47380c3 +size 7836 From e0a7006be3fcb2f4497fccdf29540d93b7766500 Mon Sep 17 00:00:00 2001 From: kayomn Date: Fri, 13 Jan 2023 09:10:28 +0000 Subject: [PATCH 08/27] Make terrain selector close when toolbox is minimized --- editor.scn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor.scn b/editor.scn index b5481be..3f3637f 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4a4c758a9efa9c039e4eee380f93e038c4163c673871385bbc170480c47380c3 +oid sha256:3993b07a19be59808c02d1e6c008fe0772bef23a9e6bced821639d9a7d3b81b3 size 7836 From 64d0280b1fdcf8c967b3c85831a622c461b6b44c Mon Sep 17 00:00:00 2001 From: kayomn Date: Fri, 13 Jan 2023 10:08:56 +0000 Subject: [PATCH 09/27] Refactor terrain map code into own file --- editor.scn | 4 +- editor/editable_terrain.gd | 100 +++++++++++++++++++++++++++++++++++++ project.godot | 6 +++ 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 editor/editable_terrain.gd diff --git a/editor.scn b/editor.scn index 3f3637f..7107b41 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3993b07a19be59808c02d1e6c008fe0772bef23a9e6bced821639d9a7d3b81b3 -size 7836 +oid sha256:c94d6be56f13b82f5ddf4c6904a65e6b213dc2ae16cdd837b112f31e80ac8439 +size 6867 diff --git a/editor/editable_terrain.gd b/editor/editable_terrain.gd new file mode 100644 index 0000000..1a0f5d7 --- /dev/null +++ b/editor/editable_terrain.gd @@ -0,0 +1,100 @@ +class_name EditableTerrain extends Node + +var _image := Image.create(1, 1, false, Image.FORMAT_RGBAF) + +## +## +## +@export +var channels := Vector3.ZERO + +## +## +## +@export +var size := Vector2i.ZERO: + get: + return size + + set(value): + _image.resize(value.x, value.y) + _image.fill(Color(0.0, 0.0, 0.0, 0.5)) + + size = value + +## +## +## +func get_image() -> void: + return _image + +## +## +## +func paint(point: Vector2i, elevation_level: float, + brush_mask: Image, brush_scale: float, brush_intensity: float) -> void: + + # Convert worldspace point to image-space coordinates for brush and calculate drawable area. + var brush_mask_size := brush_mask.get_size() + var brush_size := brush_mask_size * brush_scale + var image_size := _image.get_size() + + var draw_area := Rect2i(Vector2i.ZERO, image_size).intersection( + Rect2i((point - Vector2i(brush_size * 0.5)) + Vector2i(image_size * 0.5), brush_size)) + + if draw_area.has_area(): + var scaled_brush_mask_size := brush_mask_size / draw_area.size + + elevation_level = clampf(elevation_level, -1.0, 1.0) + + for y in draw_area.size.y: + var brush_mask_y := int(y * scaled_brush_mask_size.y) + + for x in draw_area.size.x: + var terrain_map_coord := draw_area.position + Vector2i(x, y) + var pixel := _image.get_pixelv(terrain_map_coord) + + var mask := brush_mask.get_pixel( + int(x * scaled_brush_mask_size.x), brush_mask_y).a + + var mask_intensity := brush_intensity * mask + + _image.set_pixelv(terrain_map_coord, Color( + lerpf(pixel.r, channels.x, mask_intensity), + lerpf(pixel.g, channels.y, mask_intensity), + lerpf(pixel.b, channels.z, mask_intensity), + lerpf(pixel.a, pixel.a + (elevation_level * mask), brush_intensity))) + +## +## +## +func smooth(point: Vector2i, smoothing_level: float, + brush_mask: Image, brush_scale: float, brush_intensity: float) -> void: + + # Convert worldspace point to image-space coordinates for brush and calculate drawable area. + var brush_mask_size := brush_mask.get_size() + var brush_size := brush_mask_size * brush_scale + var terrain_map_size := _image.get_size() + + var draw_area := Rect2i(Vector2i.ZERO, terrain_map_size).intersection( + Rect2i((point - Vector2i(brush_size * 0.5)) +\ + Vector2i(terrain_map_size * 0.5), brush_size)) + + if draw_area.has_area(): + var scaled_brush_mask_size := brush_mask_size / draw_area.size + + for y in draw_area.size.y: + var brush_mask_y := int(y * scaled_brush_mask_size.y) + + for x in draw_area.size.x: + var terrain_map_coord := draw_area.position + Vector2i(x, y) + var pixel := _image.get_pixelv(terrain_map_coord) + + var mask_intensity := brush_intensity * brush_mask.get_pixel( + int(x * scaled_brush_mask_size.x), brush_mask_y).a + + _image.set_pixelv(terrain_map_coord, Color( + lerpf(pixel.r, channels.x, mask_intensity), + lerpf(pixel.g, channels.y, mask_intensity), + lerpf(pixel.b, channels.z, mask_intensity), + lerpf(pixel.a, smoothing_level, mask_intensity))) diff --git a/project.godot b/project.godot index 7e196d1..b91a50f 100644 --- a/project.godot +++ b/project.godot @@ -9,6 +9,11 @@ config_version=5 _global_script_classes=[{ +"base": "Node", +"class": &"EditableTerrain", +"language": &"GDScript", +"path": "res://editor/editable_terrain.gd" +}, { "base": "Node3D", "class": &"PlayerController", "language": &"GDScript", @@ -25,6 +30,7 @@ _global_script_classes=[{ "path": "res://terrain_instance_3d.gd" }] _global_script_class_icons={ +"EditableTerrain": "", "PlayerController": "", "Settings": "", "TerrainInstance3D": "" From 6a4cb1a4317cc0faa7fd228afbd80a1d47a43623 Mon Sep 17 00:00:00 2001 From: kayomn Date: Fri, 13 Jan 2023 17:32:48 +0000 Subject: [PATCH 10/27] Fix leaky abstractions in EditableTerrain --- editor.scn | 4 +-- editor/editable_terrain.gd | 68 +++++++++++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/editor.scn b/editor.scn index 7107b41..5e9f5be 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c94d6be56f13b82f5ddf4c6904a65e6b213dc2ae16cdd837b112f31e80ac8439 -size 6867 +oid sha256:84bbd898923e8925575ebb3da006cf31db975f1c4f01267f65c36b41f4b0aa9e +size 6804 diff --git a/editor/editable_terrain.gd b/editor/editable_terrain.gd index 1a0f5d7..9367480 100644 --- a/editor/editable_terrain.gd +++ b/editor/editable_terrain.gd @@ -1,15 +1,37 @@ class_name EditableTerrain extends Node +const _DEFAULT_COLOR := Color(0.0, 0.0, 0.0, 0.5) + +## +## Blank sample value. +## +const BLANK := Color(0.0, 0.0, 0.0, 0.0) + var _image := Image.create(1, 1, false, Image.FORMAT_RGBAF) ## +## Terrain texture channel mixing values. ## +## Affects the color that terrain is mixed into during editing operations like [method paint]. ## @export var channels := Vector3.ZERO ## +## Tracked [TerrainInstance3D] to echo all terrain editing changes to. ## +var instance: TerrainInstance3D = null: + get: + return instance + + 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. ## @export var size := Vector2i.ZERO: @@ -18,18 +40,23 @@ var size := Vector2i.ZERO: set(value): _image.resize(value.x, value.y) - _image.fill(Color(0.0, 0.0, 0.0, 0.5)) + + if instance != null: + instance.size = value + instance.terrain_map = ImageTexture.create_from_image(_image) size = value -## -## -## -func get_image() -> void: - return _image +func _init() -> void: + _image.fill(_DEFAULT_COLOR) ## +## Mixes the texture [member channels] and raises the terrain by [code]elevation_level[/code] in a +## brush pattern masked by [code]brush_mask[/code] to the worldspace [code]point[/code] with +## [code]brush_intensity[/code] as the intensity of the applied effects for a single paint. ## +## For continuous painting, a delta value may be supplied to [code]brush_intensity[/code] to avoid +## issues with variable-rate paint updates. ## func paint(point: Vector2i, elevation_level: float, brush_mask: Image, brush_scale: float, brush_intensity: float) -> void: @@ -37,10 +64,9 @@ func paint(point: Vector2i, elevation_level: float, # Convert worldspace point to image-space coordinates for brush and calculate drawable area. var brush_mask_size := brush_mask.get_size() var brush_size := brush_mask_size * brush_scale - var image_size := _image.get_size() - var draw_area := Rect2i(Vector2i.ZERO, image_size).intersection( - Rect2i((point - Vector2i(brush_size * 0.5)) + Vector2i(image_size * 0.5), brush_size)) + var draw_area := Rect2i(Vector2i.ZERO, size).intersection( + Rect2i((point - Vector2i(brush_size * 0.5)) + Vector2i(size * 0.5), brush_size)) if draw_area.has_area(): var scaled_brush_mask_size := brush_mask_size / draw_area.size @@ -65,8 +91,30 @@ func paint(point: Vector2i, elevation_level: float, lerpf(pixel.b, channels.z, mask_intensity), lerpf(pixel.a, pixel.a + (elevation_level * mask), brush_intensity))) + instance.terrain_map.update(_image) + ## +## Samples the color value in the editable terrain at the worldspace [code]point[/code], returning +## its respective [Color] value. ## +## For sample coordinates outside of the terrain map worldspace, [code]BLANK[/code] is returned +## instead. +## +func sample(point: Vector2i) -> Color: + var image_point := point + Vector2i(size * 0.5) + + if Rect2i(Vector2i.ZERO, size).has_point(image_point): + return _image.get_pixelv(image_point) + + return BLANK + +## +## Mixes the texture [member channels] and smooths the terrain to [code]smoothing_level[/code] in a +## brush pattern masked by [code]brush_mask[/code] to the worldspace [code]point[/code] with +## [code]brush_intensity[/code] as the intensity of the applied effects for a single paint. +## +## For continuous smoothing, a delta value may be supplied to [code]brush_intensity[/code] to avoid +## issues with variable-rate smooth updates. ## func smooth(point: Vector2i, smoothing_level: float, brush_mask: Image, brush_scale: float, brush_intensity: float) -> void: @@ -98,3 +146,5 @@ func smooth(point: Vector2i, smoothing_level: float, lerpf(pixel.g, channels.y, mask_intensity), lerpf(pixel.b, channels.z, mask_intensity), lerpf(pixel.a, smoothing_level, mask_intensity))) + + instance.terrain_map.update(_image) From 91790f458995821fb9077d0e5db07a3138010bc6 Mon Sep 17 00:00:00 2001 From: kayomn Date: Fri, 13 Jan 2023 18:00:13 +0000 Subject: [PATCH 11/27] Fix mismatched shader uniform property in TerrainInstance3D --- terrain_instance_3d.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terrain_instance_3d.gd b/terrain_instance_3d.gd index 361ce96..712eed8 100644 --- a/terrain_instance_3d.gd +++ b/terrain_instance_3d.gd @@ -133,7 +133,7 @@ var normal_map_r: Texture2D = null: return normal_map_r set(value): - self._material.set_shader_parameter("ALBEDO_MAP_R", value) + self._material.set_shader_parameter("NORMAL_MAP_R", value) normal_map_r = value From b06837f819d4a4008be597e40567ca19d916d3ce Mon Sep 17 00:00:00 2001 From: kayomn Date: Fri, 13 Jan 2023 18:11:49 +0000 Subject: [PATCH 12/27] Fix duplicated G texture channel reading --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index 5e9f5be..5a1ba47 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:84bbd898923e8925575ebb3da006cf31db975f1c4f01267f65c36b41f4b0aa9e -size 6804 +oid sha256:613571169891763c7ce7a3cbcf1b255aa0ac7ce23df7b8fe3afdf005c61a06c6 +size 6808 From 8613d415503eb412e04513cbc9de13f9c6e3c67b Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 16 Jan 2023 00:57:17 +0000 Subject: [PATCH 13/27] Expose player controller frozen property in editor --- player_controller.gd | 1 + 1 file changed, 1 insertion(+) diff --git a/player_controller.gd b/player_controller.gd index 20a044b..c7f6114 100644 --- a/player_controller.gd +++ b/player_controller.gd @@ -72,6 +72,7 @@ var movement_smoothing := 0.5 ## ## Whether or not player movement input processed by the controller should be ignored. ## +@export var frozen := false func _input(event: InputEvent) -> void: From aa12a9ef2b8dd565e0e3ded41021a1be933533f0 Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 16 Jan 2023 00:58:11 +0000 Subject: [PATCH 14/27] Refactor editor UI logic and structure --- editor.scn | 4 +- editor/editable_terrain.gd | 217 +++++++++++++++++++++++++------------ editor/menus_theme.res | 4 +- 3 files changed, 153 insertions(+), 72 deletions(-) diff --git a/editor.scn b/editor.scn index 5a1ba47..16c682e 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:613571169891763c7ce7a3cbcf1b255aa0ac7ce23df7b8fe3afdf005c61a06c6 -size 6808 +oid sha256:9a348c339533c9794110b4ba88e8ba5317123d63885aef8cd73204bec5d6683a +size 7471 diff --git a/editor/editable_terrain.gd b/editor/editable_terrain.gd index 9367480..c7e5335 100644 --- a/editor/editable_terrain.gd +++ b/editor/editable_terrain.gd @@ -1,7 +1,5 @@ class_name EditableTerrain extends Node -const _DEFAULT_COLOR := Color(0.0, 0.0, 0.0, 0.5) - ## ## Blank sample value. ## @@ -9,14 +7,6 @@ const BLANK := Color(0.0, 0.0, 0.0, 0.0) var _image := Image.create(1, 1, false, Image.FORMAT_RGBAF) -## -## Terrain texture channel mixing values. -## -## Affects the color that terrain is mixed into during editing operations like [method paint]. -## -@export -var channels := Vector3.ZERO - ## ## Tracked [TerrainInstance3D] to echo all terrain editing changes to. ## @@ -33,7 +23,6 @@ var instance: TerrainInstance3D = null: ## ## Width and height of the editable terrain in units. ## -@export var size := Vector2i.ZERO: get: return size @@ -47,51 +36,162 @@ var size := Vector2i.ZERO: size = value -func _init() -> void: - _image.fill(_DEFAULT_COLOR) - -## -## Mixes the texture [member channels] and raises the terrain by [code]elevation_level[/code] in a -## brush pattern masked by [code]brush_mask[/code] to the worldspace [code]point[/code] with -## [code]brush_intensity[/code] as the intensity of the applied effects for a single paint. -## -## For continuous painting, a delta value may be supplied to [code]brush_intensity[/code] to avoid -## issues with variable-rate paint updates. -## -func paint(point: Vector2i, elevation_level: float, - brush_mask: Image, brush_scale: float, brush_intensity: float) -> void: - +func _get_draw_area(point: Vector2i, mask: Image, scale: float) -> Rect2i: # Convert worldspace point to image-space coordinates for brush and calculate drawable area. - var brush_mask_size := brush_mask.get_size() - var brush_size := brush_mask_size * brush_scale + var mask_size := mask.get_size() + var scaled_mask_size := mask_size * scale - var draw_area := Rect2i(Vector2i.ZERO, size).intersection( - Rect2i((point - Vector2i(brush_size * 0.5)) + Vector2i(size * 0.5), brush_size)) + return Rect2i(Vector2i.ZERO, size).intersection( + Rect2i((point - Vector2i(scaled_mask_size * 0.5)) + Vector2i(size * 0.5), scaled_mask_size)) + +func _init() -> void: + clear(BLANK) + +## +## Clears the image to the value of [code]clear_color[/code]. +## +func clear(clear_color: Color) -> void: + _image.fill(clear_color) + +## +## +## +func erase(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: + var draw_area := _get_draw_area(point, mask, scale) if draw_area.has_area(): - var scaled_brush_mask_size := brush_mask_size / draw_area.size - - elevation_level = clampf(elevation_level, -1.0, 1.0) + var mask_ratio := mask.get_size() / draw_area.size for y in draw_area.size.y: - var brush_mask_y := int(y * scaled_brush_mask_size.y) + var brush_mask_y := int(y * mask_ratio.y) for x in draw_area.size.x: var terrain_map_coord := draw_area.position + Vector2i(x, y) var pixel := _image.get_pixelv(terrain_map_coord) - var mask := brush_mask.get_pixel( - int(x * scaled_brush_mask_size.x), brush_mask_y).a - - var mask_intensity := brush_intensity * mask + var mask_intensity_delta := intensity *\ + delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a _image.set_pixelv(terrain_map_coord, Color( - lerpf(pixel.r, channels.x, mask_intensity), - lerpf(pixel.g, channels.y, mask_intensity), - lerpf(pixel.b, channels.z, mask_intensity), - lerpf(pixel.a, pixel.a + (elevation_level * mask), brush_intensity))) + lerpf(pixel.r, 0.0, mask_intensity_delta), + lerpf(pixel.g, 0.0, mask_intensity_delta), + lerpf(pixel.b, 0.0, mask_intensity_delta), + pixel.a)) - instance.terrain_map.update(_image) + instance.terrain_map.update(_image) + +## +## +## +func lower(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: + var draw_area := _get_draw_area(point, mask, scale) + + if draw_area.has_area(): + var mask_ratio := mask.get_size() / draw_area.size + + for y in draw_area.size.y: + var brush_mask_y := int(y * mask_ratio.y) + + for x in draw_area.size.x: + var terrain_map_coord := draw_area.position + Vector2i(x, y) + var pixel := _image.get_pixelv(terrain_map_coord) + + _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, + lerpf(pixel.a, pixel.a - (intensity * + mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), delta))) + + instance.terrain_map.update(_image) + +## +## +## +func paint_blue(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: + var draw_area := _get_draw_area(point, mask, scale) + + if draw_area.has_area(): + var mask_ratio := mask.get_size() / draw_area.size + + for y in draw_area.size.y: + var brush_mask_y := int(y * mask_ratio.y) + + for x in draw_area.size.x: + var terrain_map_coord := draw_area.position + Vector2i(x, y) + var pixel := _image.get_pixelv(terrain_map_coord) + + _image.set_pixelv(terrain_map_coord, Color( + pixel.r, pixel.g, lerpf(pixel.b, intensity, delta *\ + mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), + pixel.a)) + + instance.terrain_map.update(_image) + +## +## +## +func paint_green(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: + var draw_area := _get_draw_area(point, mask, scale) + + if draw_area.has_area(): + var mask_ratio := mask.get_size() / draw_area.size + + for y in draw_area.size.y: + var brush_mask_y := int(y * mask_ratio.y) + + for x in draw_area.size.x: + var terrain_map_coord := draw_area.position + Vector2i(x, y) + var pixel := _image.get_pixelv(terrain_map_coord) + + _image.set_pixelv(terrain_map_coord, Color( + pixel.r, lerpf(pixel.g, intensity, delta *\ + mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), + pixel.b, pixel.a)) + + instance.terrain_map.update(_image) + +## +## +## +func paint_red(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: + var draw_area := _get_draw_area(point, mask, scale) + + if draw_area.has_area(): + var mask_ratio := mask.get_size() / draw_area.size + + for y in draw_area.size.y: + var brush_mask_y := int(y * mask_ratio.y) + + for x in draw_area.size.x: + var terrain_map_coord := draw_area.position + Vector2i(x, y) + var pixel := _image.get_pixelv(terrain_map_coord) + + _image.set_pixelv(terrain_map_coord, Color( + lerpf(pixel.r, intensity, delta *\ + mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), + pixel.g, pixel.b, pixel.a)) + + instance.terrain_map.update(_image) + +## +## +## +func raise(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: + var draw_area := _get_draw_area(point, mask, scale) + + if draw_area.has_area(): + var mask_ratio := mask.get_size() / draw_area.size + + for y in draw_area.size.y: + var brush_mask_y := int(y * mask_ratio.y) + + for x in draw_area.size.x: + var terrain_map_coord := draw_area.position + Vector2i(x, y) + var pixel := _image.get_pixelv(terrain_map_coord) + + _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, + lerpf(pixel.a, pixel.a + (intensity * + mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), delta))) + + instance.terrain_map.update(_image) ## ## Samples the color value in the editable terrain at the worldspace [code]point[/code], returning @@ -109,42 +209,23 @@ func sample(point: Vector2i) -> Color: return BLANK ## -## Mixes the texture [member channels] and smooths the terrain to [code]smoothing_level[/code] in a -## brush pattern masked by [code]brush_mask[/code] to the worldspace [code]point[/code] with -## [code]brush_intensity[/code] as the intensity of the applied effects for a single paint. ## -## For continuous smoothing, a delta value may be supplied to [code]brush_intensity[/code] to avoid -## issues with variable-rate smooth updates. ## -func smooth(point: Vector2i, smoothing_level: float, - brush_mask: Image, brush_scale: float, brush_intensity: float) -> void: - - # Convert worldspace point to image-space coordinates for brush and calculate drawable area. - var brush_mask_size := brush_mask.get_size() - var brush_size := brush_mask_size * brush_scale - var terrain_map_size := _image.get_size() - - var draw_area := Rect2i(Vector2i.ZERO, terrain_map_size).intersection( - Rect2i((point - Vector2i(brush_size * 0.5)) +\ - Vector2i(terrain_map_size * 0.5), brush_size)) +func smooth(point: Vector2i, mask: Image, scale: float, level: float, delta: float) -> void: + var draw_area := _get_draw_area(point, mask, scale) if draw_area.has_area(): - var scaled_brush_mask_size := brush_mask_size / draw_area.size + var mask_ratio := mask.get_size() / draw_area.size for y in draw_area.size.y: - var brush_mask_y := int(y * scaled_brush_mask_size.y) + var brush_mask_y := int(y * mask_ratio.y) for x in draw_area.size.x: var terrain_map_coord := draw_area.position + Vector2i(x, y) var pixel := _image.get_pixelv(terrain_map_coord) - var mask_intensity := brush_intensity * brush_mask.get_pixel( - int(x * scaled_brush_mask_size.x), brush_mask_y).a - - _image.set_pixelv(terrain_map_coord, Color( - lerpf(pixel.r, channels.x, mask_intensity), - lerpf(pixel.g, channels.y, mask_intensity), - lerpf(pixel.b, channels.z, mask_intensity), - lerpf(pixel.a, smoothing_level, mask_intensity))) + _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, + lerpf(pixel.a, level, delta * mask.get_pixel( + int(x * mask_ratio.x), brush_mask_y).a))) instance.terrain_map.update(_image) diff --git a/editor/menus_theme.res b/editor/menus_theme.res index 8dd9794..6cca010 100644 --- a/editor/menus_theme.res +++ b/editor/menus_theme.res @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68b3bc205138b626fa79896fd4ae0343ff7c46f660cf060ddd23454f240e9145 -size 390 +oid sha256:db4d594edbfef1f0df9288dad701bbdb989e70fa2e13887a77684f107c08e698 +size 773 From a296f010a22f300d55fef02860b23a207aa4d95f Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 16 Jan 2023 01:43:24 +0000 Subject: [PATCH 15/27] Fix paint selection not resetting in editor UI --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index 16c682e..2620c3d 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a348c339533c9794110b4ba88e8ba5317123d63885aef8cd73204bec5d6683a -size 7471 +oid sha256:3f405ae5ed81dc55819cfd41ca1c990d2d3790fe532f11672319927efb4649ff +size 7496 From b80004117350401ab256e066c0b49dbb870a747d Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 16 Jan 2023 17:44:14 +0000 Subject: [PATCH 16/27] Add more style appropriate terrain assets --- terrain/arid_grass_albedo.png | 3 ++ ...ng.import => arid_grass_albedo.png.import} | 8 ++--- terrain/arid_grass_displacement.png | 3 ++ terrain/arid_grass_displacement.png.import | 34 +++++++++++++++++++ terrain/arid_grass_normal.png | 3 ++ terrain/arid_grass_normal.png.import | 34 +++++++++++++++++++ terrain/arid_grass_roughness.png | 3 ++ terrain/arid_grass_roughness.png.import | 34 +++++++++++++++++++ terrain/desert_sand_albedo.png | 4 +-- terrain/desert_sand_depth.png | 3 -- terrain/desert_sand_displacement.png | 3 ++ terrain/desert_sand_displacement.png.import | 34 +++++++++++++++++++ terrain/desert_sand_normal.png | 4 +-- terrain/desert_sand_roughness.png | 3 ++ terrain/desert_sand_roughness.png.import | 34 +++++++++++++++++++ terrain/dry_mud_albedo.png | 3 ++ terrain/dry_mud_albedo.png.import | 34 +++++++++++++++++++ terrain/dry_mud_displacement.png | 3 ++ terrain/dry_mud_displacement.png.import | 34 +++++++++++++++++++ terrain/dry_mud_normal.png | 3 ++ terrain/dry_mud_normal.png.import | 34 +++++++++++++++++++ terrain/dry_mud_roughness.png | 3 ++ terrain/dry_mud_roughness.png.import | 34 +++++++++++++++++++ 23 files changed, 344 insertions(+), 11 deletions(-) create mode 100644 terrain/arid_grass_albedo.png rename terrain/{desert_sand_depth.png.import => arid_grass_albedo.png.import} (66%) create mode 100644 terrain/arid_grass_displacement.png create mode 100644 terrain/arid_grass_displacement.png.import create mode 100644 terrain/arid_grass_normal.png create mode 100644 terrain/arid_grass_normal.png.import create mode 100644 terrain/arid_grass_roughness.png create mode 100644 terrain/arid_grass_roughness.png.import delete mode 100644 terrain/desert_sand_depth.png create mode 100644 terrain/desert_sand_displacement.png create mode 100644 terrain/desert_sand_displacement.png.import create mode 100644 terrain/desert_sand_roughness.png create mode 100644 terrain/desert_sand_roughness.png.import create mode 100644 terrain/dry_mud_albedo.png create mode 100644 terrain/dry_mud_albedo.png.import create mode 100644 terrain/dry_mud_displacement.png create mode 100644 terrain/dry_mud_displacement.png.import create mode 100644 terrain/dry_mud_normal.png create mode 100644 terrain/dry_mud_normal.png.import create mode 100644 terrain/dry_mud_roughness.png create mode 100644 terrain/dry_mud_roughness.png.import diff --git a/terrain/arid_grass_albedo.png b/terrain/arid_grass_albedo.png new file mode 100644 index 0000000..6761466 --- /dev/null +++ b/terrain/arid_grass_albedo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b0f159785fc28ed062e74f270d5897ad5cfc08141962bfa52f168df02658ab0 +size 2524391 diff --git a/terrain/desert_sand_depth.png.import b/terrain/arid_grass_albedo.png.import similarity index 66% rename from terrain/desert_sand_depth.png.import rename to terrain/arid_grass_albedo.png.import index 0fecb9c..0f79b47 100644 --- a/terrain/desert_sand_depth.png.import +++ b/terrain/arid_grass_albedo.png.import @@ -2,16 +2,16 @@ importer="texture" type="CompressedTexture2D" -uid="uid://cb4ldm1dda1bo" -path="res://.godot/imported/desert_sand_depth.png-add0a002b33efe8fd04b2cf4bf524515.ctex" +uid="uid://jcmf7j3qo6ea" +path="res://.godot/imported/arid_grass_albedo.png-cac7ceff15cf65e54d8ee36a70e05853.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://terrain/desert_sand_depth.png" -dest_files=["res://.godot/imported/desert_sand_depth.png-add0a002b33efe8fd04b2cf4bf524515.ctex"] +source_file="res://terrain/arid_grass_albedo.png" +dest_files=["res://.godot/imported/arid_grass_albedo.png-cac7ceff15cf65e54d8ee36a70e05853.ctex"] [params] diff --git a/terrain/arid_grass_displacement.png b/terrain/arid_grass_displacement.png new file mode 100644 index 0000000..13d2d85 --- /dev/null +++ b/terrain/arid_grass_displacement.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8073d5c82878ea87ae09a5856c6e13282bd46093e8867a79c9419e7def34cf45 +size 368090 diff --git a/terrain/arid_grass_displacement.png.import b/terrain/arid_grass_displacement.png.import new file mode 100644 index 0000000..2231012 --- /dev/null +++ b/terrain/arid_grass_displacement.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://co0jompch208v" +path="res://.godot/imported/arid_grass_displacement.png-66c8c71a36e11168aed23cd0531ba7bd.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"] + +[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 diff --git a/terrain/arid_grass_normal.png b/terrain/arid_grass_normal.png new file mode 100644 index 0000000..53b9ddf --- /dev/null +++ b/terrain/arid_grass_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:822937d4cb546d433562390277652a4e3f373328f6045480fa7905d8c163b814 +size 781967 diff --git a/terrain/arid_grass_normal.png.import b/terrain/arid_grass_normal.png.import new file mode 100644 index 0000000..22fb4d4 --- /dev/null +++ b/terrain/arid_grass_normal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bh141jkgbmya8" +path="res://.godot/imported/arid_grass_normal.png-6cfb96e0a0b1eac890998accab9c7109.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"] + +[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 diff --git a/terrain/arid_grass_roughness.png b/terrain/arid_grass_roughness.png new file mode 100644 index 0000000..c56136a --- /dev/null +++ b/terrain/arid_grass_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d36c8bf74944ea23945b7fdc254b64dfc2c8b18aa84a3a861406a8fe9c5fae4 +size 375431 diff --git a/terrain/arid_grass_roughness.png.import b/terrain/arid_grass_roughness.png.import new file mode 100644 index 0000000..2bdf3d4 --- /dev/null +++ b/terrain/arid_grass_roughness.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://jdq8kwjo3uap" +path="res://.godot/imported/arid_grass_roughness.png-8ff0f34a3348350d0edc5e43b43bcd0e.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"] + +[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 diff --git a/terrain/desert_sand_albedo.png b/terrain/desert_sand_albedo.png index 10b6a16..3c9cd8c 100644 --- a/terrain/desert_sand_albedo.png +++ b/terrain/desert_sand_albedo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:620d5c5b1421ee188681e1f2dd184b56787c9225b1f606f13802b64de0fdf811 -size 3433382 +oid sha256:321a1d55f3b1779b4e5c34ac1bdbd192e7b3099db59017422d0b6ed993bde624 +size 1160665 diff --git a/terrain/desert_sand_depth.png b/terrain/desert_sand_depth.png deleted file mode 100644 index 6aa3a34..0000000 --- a/terrain/desert_sand_depth.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:299d87da87ba51e2bef7963fe0f7a393a0028b91a01c7f7b334ff553542f9798 -size 3749261 diff --git a/terrain/desert_sand_displacement.png b/terrain/desert_sand_displacement.png new file mode 100644 index 0000000..dc6845a --- /dev/null +++ b/terrain/desert_sand_displacement.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bda6bc2f9922061f8537cfc90387f1dae6165bebcac4f27d78884b5ffac8eb84 +size 133165 diff --git a/terrain/desert_sand_displacement.png.import b/terrain/desert_sand_displacement.png.import new file mode 100644 index 0000000..64aea08 --- /dev/null +++ b/terrain/desert_sand_displacement.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bdacir1igfinb" +path="res://.godot/imported/desert_sand_displacement.png-3674eb6c274d21b1ddd14b8c6ce982fe.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"] + +[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 diff --git a/terrain/desert_sand_normal.png b/terrain/desert_sand_normal.png index 4bd2790..90c96b8 100644 --- a/terrain/desert_sand_normal.png +++ b/terrain/desert_sand_normal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b79420ad4ad1863b9b82dbe8ee93fdbac60f693c1a0842afe6969d552c21697b -size 10321853 +oid sha256:97baa2a6fc1773429f1a68504b65e1d78b3ae078fb457f3d5798493279c59dd8 +size 547227 diff --git a/terrain/desert_sand_roughness.png b/terrain/desert_sand_roughness.png new file mode 100644 index 0000000..38e1172 --- /dev/null +++ b/terrain/desert_sand_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ee3bc561047543c235f7763dd1a3dedd70bf9dd1c59168189873b046c899f5b +size 186636 diff --git a/terrain/desert_sand_roughness.png.import b/terrain/desert_sand_roughness.png.import new file mode 100644 index 0000000..f1bcb24 --- /dev/null +++ b/terrain/desert_sand_roughness.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bwkcsnjetn5wr" +path="res://.godot/imported/desert_sand_roughness.png-c85e29a6965b06eac0c712e74b047821.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"] + +[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 diff --git a/terrain/dry_mud_albedo.png b/terrain/dry_mud_albedo.png new file mode 100644 index 0000000..6cb95b2 --- /dev/null +++ b/terrain/dry_mud_albedo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a2959f3617ed501b38b80af6349507578e1f76984598ae3943178f809a1d99b +size 1073364 diff --git a/terrain/dry_mud_albedo.png.import b/terrain/dry_mud_albedo.png.import new file mode 100644 index 0000000..1c786de --- /dev/null +++ b/terrain/dry_mud_albedo.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://eqbk8dx3px02" +path="res://.godot/imported/dry_mud_albedo.png-0fe12d446fc4e93e2a42ccc9303ac693.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"] + +[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 diff --git a/terrain/dry_mud_displacement.png b/terrain/dry_mud_displacement.png new file mode 100644 index 0000000..b33f758 --- /dev/null +++ b/terrain/dry_mud_displacement.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ec39bdd368da7aaed43273028ea07880f9f156f3b0f6624d6718f1ca9632761 +size 177014 diff --git a/terrain/dry_mud_displacement.png.import b/terrain/dry_mud_displacement.png.import new file mode 100644 index 0000000..7e09efe --- /dev/null +++ b/terrain/dry_mud_displacement.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bwqtubithbfsy" +path="res://.godot/imported/dry_mud_displacement.png-459305492d2f8cba90344ad67808cc02.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"] + +[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 diff --git a/terrain/dry_mud_normal.png b/terrain/dry_mud_normal.png new file mode 100644 index 0000000..2eb62e3 --- /dev/null +++ b/terrain/dry_mud_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ac5cdf2b5857c5497e39d0e49c074b601fbf9e5e23ca507ba1915bd190be6ba +size 669314 diff --git a/terrain/dry_mud_normal.png.import b/terrain/dry_mud_normal.png.import new file mode 100644 index 0000000..0ac7cfa --- /dev/null +++ b/terrain/dry_mud_normal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c86r5niid1hp1" +path="res://.godot/imported/dry_mud_normal.png-bbedc7a55f837a837bfdab39fcbc7272.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"] + +[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 diff --git a/terrain/dry_mud_roughness.png b/terrain/dry_mud_roughness.png new file mode 100644 index 0000000..492f5b4 --- /dev/null +++ b/terrain/dry_mud_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:419427d9102eb71e2bfc4cca2b26ab67787c24811bce9efc0b9889f9a8c915b5 +size 296976 diff --git a/terrain/dry_mud_roughness.png.import b/terrain/dry_mud_roughness.png.import new file mode 100644 index 0000000..c70c4af --- /dev/null +++ b/terrain/dry_mud_roughness.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://7xnkstxa6q65" +path="res://.godot/imported/dry_mud_roughness.png-0d5a4572411f8d454ef69ed8b252672b.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"] + +[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 From 9982cae13b172eff796acd9e8aaf268012892e28 Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 16 Jan 2023 18:25:35 +0000 Subject: [PATCH 17/27] Add cobbled limestone terrain --- terrain/cobbled_limestone_albedo.png | 3 + terrain/cobbled_limestone_albedo.png.import | 34 ++++ terrain/cobbled_limestone_displacement.png | 3 + .../cobbled_limestone_displacement.png.import | 34 ++++ terrain/cobbled_limestone_normal.png | 3 + terrain/cobbled_limestone_normal.png.import | 34 ++++ terrain/cobbled_limestone_roughness.png | 3 + .../cobbled_limestone_roughness.png.import | 34 ++++ terrain/terrain_instance_3d.gd | 169 ++++++++++++++++++ 9 files changed, 317 insertions(+) create mode 100644 terrain/cobbled_limestone_albedo.png create mode 100644 terrain/cobbled_limestone_albedo.png.import create mode 100644 terrain/cobbled_limestone_displacement.png create mode 100644 terrain/cobbled_limestone_displacement.png.import create mode 100644 terrain/cobbled_limestone_normal.png create mode 100644 terrain/cobbled_limestone_normal.png.import create mode 100644 terrain/cobbled_limestone_roughness.png create mode 100644 terrain/cobbled_limestone_roughness.png.import create mode 100644 terrain/terrain_instance_3d.gd diff --git a/terrain/cobbled_limestone_albedo.png b/terrain/cobbled_limestone_albedo.png new file mode 100644 index 0000000..9f80ce4 --- /dev/null +++ b/terrain/cobbled_limestone_albedo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03f34c2cdf4e3f941d62bed684cc05017c8daea13218bcc61433a97917770a96 +size 1615088 diff --git a/terrain/cobbled_limestone_albedo.png.import b/terrain/cobbled_limestone_albedo.png.import new file mode 100644 index 0000000..f5e6ff0 --- /dev/null +++ b/terrain/cobbled_limestone_albedo.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cs06oiwrord6t" +path="res://.godot/imported/cobbled_limestone_albedo.png-cbafb40d3c6fc43ce00d68cb02456536.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"] + +[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 diff --git a/terrain/cobbled_limestone_displacement.png b/terrain/cobbled_limestone_displacement.png new file mode 100644 index 0000000..b04dbd2 --- /dev/null +++ b/terrain/cobbled_limestone_displacement.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79990410d9c9212930e7d3e59e2825c3ba9d3c3354ae4e52ddb988d49ee282e5 +size 189441 diff --git a/terrain/cobbled_limestone_displacement.png.import b/terrain/cobbled_limestone_displacement.png.import new file mode 100644 index 0000000..8b1c968 --- /dev/null +++ b/terrain/cobbled_limestone_displacement.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://mkxbjfwdwkaq" +path="res://.godot/imported/cobbled_limestone_displacement.png-8e8b27438ff815a9d58d4a490e04203c.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"] + +[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 diff --git a/terrain/cobbled_limestone_normal.png b/terrain/cobbled_limestone_normal.png new file mode 100644 index 0000000..c5396be --- /dev/null +++ b/terrain/cobbled_limestone_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ef381960a013f47fb6c1334f36ef99662df8938bdc2b5004ff4fb76dcf93e77 +size 627601 diff --git a/terrain/cobbled_limestone_normal.png.import b/terrain/cobbled_limestone_normal.png.import new file mode 100644 index 0000000..d72444f --- /dev/null +++ b/terrain/cobbled_limestone_normal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ukk0161x3eg2" +path="res://.godot/imported/cobbled_limestone_normal.png-4d7b2eb9c070e06256eb42d408ff4a14.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"] + +[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 diff --git a/terrain/cobbled_limestone_roughness.png b/terrain/cobbled_limestone_roughness.png new file mode 100644 index 0000000..d74e666 --- /dev/null +++ b/terrain/cobbled_limestone_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:002b4dd1f43e3159e5def14b451942db30d75c49e121fcceb7addd0c83e1530f +size 228583 diff --git a/terrain/cobbled_limestone_roughness.png.import b/terrain/cobbled_limestone_roughness.png.import new file mode 100644 index 0000000..0c2675e --- /dev/null +++ b/terrain/cobbled_limestone_roughness.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bcybapft8tl2x" +path="res://.godot/imported/cobbled_limestone_roughness.png-f78cac7004d15ddc2a00fd10f74b8c10.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"] + +[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 diff --git a/terrain/terrain_instance_3d.gd b/terrain/terrain_instance_3d.gd new file mode 100644 index 0000000..712eed8 --- /dev/null +++ b/terrain/terrain_instance_3d.gd @@ -0,0 +1,169 @@ +@tool +class_name TerrainInstance3D extends GeometryInstance3D + +const _DETAIL := 2 + +var _mesh := PlaneMesh.new() + +var _material := ShaderMaterial.new() + +## +## +## +@export +var size: Vector2i = Vector2i.ZERO: + get: + return size + + set(value): + var width := maxi(value.x, 0) + var height := maxi(value.y, 0) + + if (width != size.x) or (height != size.y): + if (width == 0) and (height == 0): + RenderingServer.instance_set_base(self.get_instance(), RID()) + + 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) + +func _init() -> void: + self._material.shader = preload("res://terrain_shader.gdshader") + + self._mesh.surface_set_material(0, self._material) From 0b19b9729313b526ae1e9918b98f5229b5853b85 Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 16 Jan 2023 18:54:06 +0000 Subject: [PATCH 18/27] Various editor and editor GUI fixes --- editor.scn | 4 +- editor/editable_terrain.gd | 114 +++++++----- editor/menus_theme.res | 4 +- project.godot | 2 +- terrain/terrain_instance_3d.gd | 2 +- .../terrain_shader.gdshader | 2 +- terrain_instance_3d.gd | 169 ------------------ 7 files changed, 75 insertions(+), 222 deletions(-) rename terrain_shader.gdshader => terrain/terrain_shader.gdshader (98%) delete mode 100644 terrain_instance_3d.gd diff --git a/editor.scn b/editor.scn index 2620c3d..7556254 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f405ae5ed81dc55819cfd41ca1c990d2d3790fe532f11672319927efb4649ff -size 7496 +oid sha256:bcf7028b082f7667e47971dacc43da0ac6e70b150f3c39b1df92016f3dd3da27 +size 7744 diff --git a/editor/editable_terrain.gd b/editor/editable_terrain.gd index c7e5335..101e6dd 100644 --- a/editor/editable_terrain.gd +++ b/editor/editable_terrain.gd @@ -53,31 +53,7 @@ func _init() -> void: func clear(clear_color: Color) -> void: _image.fill(clear_color) -## -## -## -func erase(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: - var draw_area := _get_draw_area(point, mask, scale) - - if draw_area.has_area(): - var mask_ratio := mask.get_size() / draw_area.size - - for y in draw_area.size.y: - var brush_mask_y := int(y * mask_ratio.y) - - for x in draw_area.size.x: - var terrain_map_coord := draw_area.position + Vector2i(x, y) - var pixel := _image.get_pixelv(terrain_map_coord) - - var mask_intensity_delta := intensity *\ - delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a - - _image.set_pixelv(terrain_map_coord, Color( - lerpf(pixel.r, 0.0, mask_intensity_delta), - lerpf(pixel.g, 0.0, mask_intensity_delta), - lerpf(pixel.b, 0.0, mask_intensity_delta), - pixel.a)) - + if instance != null: instance.terrain_map.update(_image) ## @@ -98,9 +74,10 @@ func lower(point: Vector2i, mask: Image, scale: float, intensity: float, delta: _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, lerpf(pixel.a, pixel.a - (intensity * - mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), delta))) + mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), delta)).clamp()) - instance.terrain_map.update(_image) + if instance != null: + instance.terrain_map.update(_image) ## ## @@ -118,12 +95,45 @@ func paint_blue(point: Vector2i, mask: Image, scale: float, intensity: float, de var terrain_map_coord := draw_area.position + Vector2i(x, y) var pixel := _image.get_pixelv(terrain_map_coord) - _image.set_pixelv(terrain_map_coord, Color( - pixel.r, pixel.g, lerpf(pixel.b, intensity, delta *\ - mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), - pixel.a)) + var mask_intensity_delta := intensity *\ + delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a - instance.terrain_map.update(_image) + _image.set_pixelv(terrain_map_coord, Color( + lerpf(pixel.r, 0.0, mask_intensity_delta), + lerpf(pixel.g, 0.0, mask_intensity_delta), + lerpf(pixel.b, 1.0, mask_intensity_delta), + pixel.a).clamp()) + + if instance != null: + instance.terrain_map.update(_image) + +## +## +## +func paint_erase(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: + var draw_area := _get_draw_area(point, mask, scale) + + if draw_area.has_area(): + var mask_ratio := mask.get_size() / draw_area.size + + for y in draw_area.size.y: + var brush_mask_y := int(y * mask_ratio.y) + + for x in draw_area.size.x: + var terrain_map_coord := draw_area.position + Vector2i(x, y) + var pixel := _image.get_pixelv(terrain_map_coord) + + var mask_intensity_delta := intensity *\ + delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a + + _image.set_pixelv(terrain_map_coord, Color( + lerpf(pixel.r, 0.0, mask_intensity_delta), + lerpf(pixel.g, 0.0, mask_intensity_delta), + lerpf(pixel.b, 0.0, mask_intensity_delta), + pixel.a).clamp()) + + if instance != null: + instance.terrain_map.update(_image) ## ## @@ -141,12 +151,17 @@ func paint_green(point: Vector2i, mask: Image, scale: float, intensity: float, d var terrain_map_coord := draw_area.position + Vector2i(x, y) var pixel := _image.get_pixelv(terrain_map_coord) - _image.set_pixelv(terrain_map_coord, Color( - pixel.r, lerpf(pixel.g, intensity, delta *\ - mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), - pixel.b, pixel.a)) + var mask_intensity_delta := intensity *\ + delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a - instance.terrain_map.update(_image) + _image.set_pixelv(terrain_map_coord, Color( + lerpf(pixel.r, 0.0, mask_intensity_delta), + lerpf(pixel.g, 1.0, mask_intensity_delta), + lerpf(pixel.b, 0.0, mask_intensity_delta), + pixel.a).clamp()) + + if instance != null: + instance.terrain_map.update(_image) ## ## @@ -164,12 +179,17 @@ func paint_red(point: Vector2i, mask: Image, scale: float, intensity: float, del var terrain_map_coord := draw_area.position + Vector2i(x, y) var pixel := _image.get_pixelv(terrain_map_coord) - _image.set_pixelv(terrain_map_coord, Color( - lerpf(pixel.r, intensity, delta *\ - mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), - pixel.g, pixel.b, pixel.a)) + var mask_intensity_delta := intensity *\ + delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a - instance.terrain_map.update(_image) + _image.set_pixelv(terrain_map_coord, Color( + lerpf(pixel.r, 1.0, mask_intensity_delta), + lerpf(pixel.g, 0.0, mask_intensity_delta), + lerpf(pixel.b, 0.0, mask_intensity_delta), + pixel.a).clamp()) + + if instance != null: + instance.terrain_map.update(_image) ## ## @@ -189,9 +209,10 @@ func raise(point: Vector2i, mask: Image, scale: float, intensity: float, delta: _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, lerpf(pixel.a, pixel.a + (intensity * - mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), delta))) + mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), delta)).clamp()) - instance.terrain_map.update(_image) + if instance != null: + instance.terrain_map.update(_image) ## ## Samples the color value in the editable terrain at the worldspace [code]point[/code], returning @@ -226,6 +247,7 @@ func smooth(point: Vector2i, mask: Image, scale: float, level: float, delta: flo _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, lerpf(pixel.a, level, delta * mask.get_pixel( - int(x * mask_ratio.x), brush_mask_y).a))) + int(x * mask_ratio.x), brush_mask_y).a)).clamp()) - instance.terrain_map.update(_image) + if instance != null: + instance.terrain_map.update(_image) diff --git a/editor/menus_theme.res b/editor/menus_theme.res index 6cca010..fc3811b 100644 --- a/editor/menus_theme.res +++ b/editor/menus_theme.res @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db4d594edbfef1f0df9288dad701bbdb989e70fa2e13887a77684f107c08e698 -size 773 +oid sha256:b55d3216b44258c8ff007f8689e217104125c485810aeb1d180093fe35032551 +size 798 diff --git a/project.godot b/project.godot index b91a50f..86fc427 100644 --- a/project.godot +++ b/project.godot @@ -27,7 +27,7 @@ _global_script_classes=[{ "base": "GeometryInstance3D", "class": &"TerrainInstance3D", "language": &"GDScript", -"path": "res://terrain_instance_3d.gd" +"path": "res://terrain/terrain_instance_3d.gd" }] _global_script_class_icons={ "EditableTerrain": "", diff --git a/terrain/terrain_instance_3d.gd b/terrain/terrain_instance_3d.gd index 712eed8..951fcce 100644 --- a/terrain/terrain_instance_3d.gd +++ b/terrain/terrain_instance_3d.gd @@ -164,6 +164,6 @@ var max_height := 100.0: max_height = max(value, 0.0) func _init() -> void: - self._material.shader = preload("res://terrain_shader.gdshader") + self._material.shader = preload("res://terrain/terrain_shader.gdshader") self._mesh.surface_set_material(0, self._material) diff --git a/terrain_shader.gdshader b/terrain/terrain_shader.gdshader similarity index 98% rename from terrain_shader.gdshader rename to terrain/terrain_shader.gdshader index 933a6cf..2af40b6 100644 --- a/terrain_shader.gdshader +++ b/terrain/terrain_shader.gdshader @@ -23,7 +23,7 @@ uniform vec2 SIZE; uniform sampler2D TERRAIN_MAP : hint_default_transparent, repeat_disable; void fragment() { - vec2 uv = UV * SIZE; + vec2 uv = UV * (SIZE / 2.0); vec2 uv_alt = uv * -0.25; 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); diff --git a/terrain_instance_3d.gd b/terrain_instance_3d.gd deleted file mode 100644 index 712eed8..0000000 --- a/terrain_instance_3d.gd +++ /dev/null @@ -1,169 +0,0 @@ -@tool -class_name TerrainInstance3D extends GeometryInstance3D - -const _DETAIL := 2 - -var _mesh := PlaneMesh.new() - -var _material := ShaderMaterial.new() - -## -## -## -@export -var size: Vector2i = Vector2i.ZERO: - get: - return size - - set(value): - var width := maxi(value.x, 0) - var height := maxi(value.y, 0) - - if (width != size.x) or (height != size.y): - if (width == 0) and (height == 0): - RenderingServer.instance_set_base(self.get_instance(), RID()) - - 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) - -func _init() -> void: - self._material.shader = preload("res://terrain_shader.gdshader") - - self._mesh.surface_set_material(0, self._material) From 81abb0d8d90dd25dc736f509ea721cd9923f1458 Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 16 Jan 2023 23:48:13 +0000 Subject: [PATCH 19/27] Fix errors in editable terrain painting calculations --- editor.scn | 4 +- editor/editable_terrain.gd | 205 ++++++++----------------------------- 2 files changed, 45 insertions(+), 164 deletions(-) diff --git a/editor.scn b/editor.scn index 7556254..28398bb 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bcf7028b082f7667e47971dacc43da0ac6e70b150f3c39b1df92016f3dd3da27 -size 7744 +oid sha256:558a400fc6ab4940424ae7485c20d64f277eb631a649057e48186308fe9db4f6 +size 7782 diff --git a/editor/editable_terrain.gd b/editor/editable_terrain.gd index 101e6dd..7682acb 100644 --- a/editor/editable_terrain.gd +++ b/editor/editable_terrain.gd @@ -36,13 +36,11 @@ var size := Vector2i.ZERO: size = value -func _get_draw_area(point: Vector2i, mask: Image, scale: float) -> Rect2i: - # Convert worldspace point to image-space coordinates for brush and calculate drawable area. - var mask_size := mask.get_size() - var scaled_mask_size := mask_size * scale +func _get_brush_area(point: Vector2i, mask_size: Vector2i, scale: float) -> Rect2i: + # Convert worldspace point to image-space coordinates for mask. + var scaled_mask_size := Vector2i(mask_size * scale) - return Rect2i(Vector2i.ZERO, size).intersection( - Rect2i((point - Vector2i(scaled_mask_size * 0.5)) + Vector2i(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: clear(BLANK) @@ -59,22 +57,29 @@ func clear(clear_color: Color) -> void: ## ## ## -func lower(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: - var draw_area := _get_draw_area(point, mask, scale) +func oscillate(point: Vector2i, level: float, + mask: Image, scale: float, intensity: float, delta: float) -> void: - if draw_area.has_area(): - var mask_ratio := mask.get_size() / draw_area.size + var mask_size := mask.get_size() + var brush_source := _get_brush_area(point, mask_size, scale) - for y in draw_area.size.y: - var brush_mask_y := int(y * mask_ratio.y) + if brush_source.has_area(): + var brush_target := Rect2i(Vector2i.ZERO, size).intersection(brush_source) - for x in draw_area.size.x: - var terrain_map_coord := draw_area.position + Vector2i(x, y) - var pixel := _image.get_pixelv(terrain_map_coord) + if brush_target.has_area(): + var mask_ratio := mask_size / brush_source.size + var offset := brush_target.position - brush_source.position - _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, - lerpf(pixel.a, pixel.a - (intensity * - mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), delta)).clamp()) + for y in brush_target.size.y: + var mask_y := int((offset.y + y) * mask_ratio.y) + + for x in brush_target.size.x: + var coord := brush_target.position + Vector2i(x, y) + var pixel := _image.get_pixelv(coord) + + _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) @@ -82,134 +87,33 @@ func lower(point: Vector2i, mask: Image, scale: float, intensity: float, delta: ## ## ## -func paint_blue(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: - var draw_area := _get_draw_area(point, mask, scale) +func paint(point: Vector2i, color: Color, + mask: Image, scale: float, intensity: float, delta: float) -> void: - if draw_area.has_area(): - var mask_ratio := mask.get_size() / draw_area.size + var mask_size := mask.get_size() + var brush_source := _get_brush_area(point, mask_size, scale) - for y in draw_area.size.y: - var brush_mask_y := int(y * mask_ratio.y) + if brush_source.has_area(): + var brush_target := Rect2i(Vector2i.ZERO, size).intersection(brush_source) - for x in draw_area.size.x: - var terrain_map_coord := draw_area.position + Vector2i(x, y) - var pixel := _image.get_pixelv(terrain_map_coord) + if brush_target.has_area(): + var mask_ratio := mask_size / brush_source.size + var offset := brush_target.position - brush_source.position - var mask_intensity_delta := intensity *\ - delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a + for y in brush_target.size.y: + var mask_y := int((offset.y + y) * mask_ratio.y) - _image.set_pixelv(terrain_map_coord, Color( - lerpf(pixel.r, 0.0, mask_intensity_delta), - lerpf(pixel.g, 0.0, mask_intensity_delta), - lerpf(pixel.b, 1.0, mask_intensity_delta), - pixel.a).clamp()) + for x in brush_target.size.x: + var coord := brush_target.position + Vector2i(x, y) + var pixel := _image.get_pixelv(coord) - if instance != null: - instance.terrain_map.update(_image) + var mask_intensity_delta := intensity * delta *\ + mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a -## -## -## -func paint_erase(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: - var draw_area := _get_draw_area(point, mask, scale) - - if draw_area.has_area(): - var mask_ratio := mask.get_size() / draw_area.size - - for y in draw_area.size.y: - var brush_mask_y := int(y * mask_ratio.y) - - for x in draw_area.size.x: - var terrain_map_coord := draw_area.position + Vector2i(x, y) - var pixel := _image.get_pixelv(terrain_map_coord) - - var mask_intensity_delta := intensity *\ - delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a - - _image.set_pixelv(terrain_map_coord, Color( - lerpf(pixel.r, 0.0, mask_intensity_delta), - lerpf(pixel.g, 0.0, mask_intensity_delta), - lerpf(pixel.b, 0.0, mask_intensity_delta), - pixel.a).clamp()) - - if instance != null: - instance.terrain_map.update(_image) - -## -## -## -func paint_green(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: - var draw_area := _get_draw_area(point, mask, scale) - - if draw_area.has_area(): - var mask_ratio := mask.get_size() / draw_area.size - - for y in draw_area.size.y: - var brush_mask_y := int(y * mask_ratio.y) - - for x in draw_area.size.x: - var terrain_map_coord := draw_area.position + Vector2i(x, y) - var pixel := _image.get_pixelv(terrain_map_coord) - - var mask_intensity_delta := intensity *\ - delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a - - _image.set_pixelv(terrain_map_coord, Color( - lerpf(pixel.r, 0.0, mask_intensity_delta), - lerpf(pixel.g, 1.0, mask_intensity_delta), - lerpf(pixel.b, 0.0, mask_intensity_delta), - pixel.a).clamp()) - - if instance != null: - instance.terrain_map.update(_image) - -## -## -## -func paint_red(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: - var draw_area := _get_draw_area(point, mask, scale) - - if draw_area.has_area(): - var mask_ratio := mask.get_size() / draw_area.size - - for y in draw_area.size.y: - var brush_mask_y := int(y * mask_ratio.y) - - for x in draw_area.size.x: - var terrain_map_coord := draw_area.position + Vector2i(x, y) - var pixel := _image.get_pixelv(terrain_map_coord) - - var mask_intensity_delta := intensity *\ - delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a - - _image.set_pixelv(terrain_map_coord, Color( - lerpf(pixel.r, 1.0, mask_intensity_delta), - lerpf(pixel.g, 0.0, mask_intensity_delta), - lerpf(pixel.b, 0.0, mask_intensity_delta), - pixel.a).clamp()) - - if instance != null: - instance.terrain_map.update(_image) - -## -## -## -func raise(point: Vector2i, mask: Image, scale: float, intensity: float, delta: float) -> void: - var draw_area := _get_draw_area(point, mask, scale) - - if draw_area.has_area(): - var mask_ratio := mask.get_size() / draw_area.size - - for y in draw_area.size.y: - var brush_mask_y := int(y * mask_ratio.y) - - for x in draw_area.size.x: - var terrain_map_coord := draw_area.position + Vector2i(x, y) - var pixel := _image.get_pixelv(terrain_map_coord) - - _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, - lerpf(pixel.a, pixel.a + (intensity * - mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a), delta)).clamp()) + _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) @@ -228,26 +132,3 @@ func sample(point: Vector2i) -> Color: return _image.get_pixelv(image_point) return BLANK - -## -## -## -func smooth(point: Vector2i, mask: Image, scale: float, level: float, delta: float) -> void: - var draw_area := _get_draw_area(point, mask, scale) - - if draw_area.has_area(): - var mask_ratio := mask.get_size() / draw_area.size - - for y in draw_area.size.y: - var brush_mask_y := int(y * mask_ratio.y) - - for x in draw_area.size.x: - var terrain_map_coord := draw_area.position + Vector2i(x, y) - var pixel := _image.get_pixelv(terrain_map_coord) - - _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, - lerpf(pixel.a, level, delta * mask.get_pixel( - int(x * mask_ratio.x), brush_mask_y).a)).clamp()) - - if instance != null: - instance.terrain_map.update(_image) From 73de0506286124194abef2bebf35ffc1ce3d2cc7 Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 16 Jan 2023 23:48:56 +0000 Subject: [PATCH 20/27] Adjust scale of noise UV for terrain shading --- terrain/terrain_shader.gdshader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terrain/terrain_shader.gdshader b/terrain/terrain_shader.gdshader index 2af40b6..796de7b 100644 --- a/terrain/terrain_shader.gdshader +++ b/terrain/terrain_shader.gdshader @@ -24,7 +24,7 @@ uniform sampler2D TERRAIN_MAP : hint_default_transparent, repeat_disable; void fragment() { vec2 uv = UV * (SIZE / 2.0); - vec2 uv_alt = uv * -0.25; + 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); From ea5db595d4574030609e6aee1c00ec2bafab464b Mon Sep 17 00:00:00 2001 From: kayomn Date: Tue, 17 Jan 2023 15:22:15 +0000 Subject: [PATCH 21/27] Refactor and redesign editor UI --- editor.scn | 4 ++-- editor/menus_theme.res | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/editor.scn b/editor.scn index 28398bb..054ae5f 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:558a400fc6ab4940424ae7485c20d64f277eb631a649057e48186308fe9db4f6 -size 7782 +oid sha256:415ee1f41640db4b4356c1ab3eeddd93e9d858d20c7a5af394d16bf5e87858ec +size 7944 diff --git a/editor/menus_theme.res b/editor/menus_theme.res index fc3811b..e4ae784 100644 --- a/editor/menus_theme.res +++ b/editor/menus_theme.res @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b55d3216b44258c8ff007f8689e217104125c485810aeb1d180093fe35032551 -size 798 +oid sha256:6abf7dfa9a4e3b0da93384cd5600a50cb553a18f337dcb9b5aeaf5a52b871271 +size 825 From bf73abed8db6e250ae713b8e337fa13b9d75a87e Mon Sep 17 00:00:00 2001 From: kayomn Date: Tue, 17 Jan 2023 15:29:40 +0000 Subject: [PATCH 22/27] Fix editor crash at startup --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index 054ae5f..691f1a2 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:415ee1f41640db4b4356c1ab3eeddd93e9d858d20c7a5af394d16bf5e87858ec -size 7944 +oid sha256:21c5b33f3883f18db3672804d9664298aa0e8e161f77c214bc8e213a8936e459 +size 7971 From 5db227a8aca6dae1190bfb8cbc8fe8c6b1c65c46 Mon Sep 17 00:00:00 2001 From: kayomn Date: Tue, 17 Jan 2023 16:41:54 +0000 Subject: [PATCH 23/27] Expose hardcoded brush mask to editor UI --- editor.scn | 4 ++-- ...sh_soft_mask.png => brush_soft_circle_mask.png} | 0 editor/brush_soft_circle_mask.png.import | 14 ++++++++++++++ editor/brush_soft_mask.png.import | 14 -------------- 4 files changed, 16 insertions(+), 16 deletions(-) rename editor/{brush_soft_mask.png => brush_soft_circle_mask.png} (100%) create mode 100644 editor/brush_soft_circle_mask.png.import delete mode 100644 editor/brush_soft_mask.png.import diff --git a/editor.scn b/editor.scn index 691f1a2..7c78aae 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21c5b33f3883f18db3672804d9664298aa0e8e161f77c214bc8e213a8936e459 -size 7971 +oid sha256:27e4f2ad834896dd8e4ad335f3adc826b92c04a676bf9ae2a41d855ed1503113 +size 8518 diff --git a/editor/brush_soft_mask.png b/editor/brush_soft_circle_mask.png similarity index 100% rename from editor/brush_soft_mask.png rename to editor/brush_soft_circle_mask.png diff --git a/editor/brush_soft_circle_mask.png.import b/editor/brush_soft_circle_mask.png.import new file mode 100644 index 0000000..6b453bf --- /dev/null +++ b/editor/brush_soft_circle_mask.png.import @@ -0,0 +1,14 @@ +[remap] + +importer="image" +type="Image" +uid="uid://bbdh4btpg08do" +path="res://.godot/imported/brush_soft_circle_mask.png-5af527bedd556c2d7ed38b029e34527e.image" + +[deps] + +source_file="res://editor/brush_soft_circle_mask.png" +dest_files=["res://.godot/imported/brush_soft_circle_mask.png-5af527bedd556c2d7ed38b029e34527e.image"] + +[params] + diff --git a/editor/brush_soft_mask.png.import b/editor/brush_soft_mask.png.import deleted file mode 100644 index 187ed45..0000000 --- a/editor/brush_soft_mask.png.import +++ /dev/null @@ -1,14 +0,0 @@ -[remap] - -importer="image" -type="Image" -uid="uid://bbdh4btpg08do" -path="res://.godot/imported/brush_soft_mask.png-cec601fece9e15b1942ebb0d73b51015.image" - -[deps] - -source_file="res://editor/brush_soft_mask.png" -dest_files=["res://.godot/imported/brush_soft_mask.png-cec601fece9e15b1942ebb0d73b51015.image"] - -[params] - From 129c4f16d8915ed3a940a33184666cb0a9bee879 Mon Sep 17 00:00:00 2001 From: kayomn Date: Tue, 17 Jan 2023 16:44:21 +0000 Subject: [PATCH 24/27] Fix brush mask button group being ignored --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index 7c78aae..2a13719 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27e4f2ad834896dd8e4ad335f3adc826b92c04a676bf9ae2a41d855ed1503113 -size 8518 +oid sha256:473d8c0002a10dcfe0b5a949a50e89aa9c475a2838fa63df16db7e95c454178c +size 8512 From 2c24ec861f310b464ba9a19ace323c566227784a Mon Sep 17 00:00:00 2001 From: kayomn Date: Tue, 17 Jan 2023 19:53:09 +0000 Subject: [PATCH 25/27] More editor UI fixes --- editor.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor.scn b/editor.scn index 2a13719..118917f 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:473d8c0002a10dcfe0b5a949a50e89aa9c475a2838fa63df16db7e95c454178c -size 8512 +oid sha256:14a8eed4e79bdfd17670c48b25fcd5e8f278c0f2bdfed80dbe5714051390111e +size 8518 From c7a0d6bce2ac4dbb6c569570978f4c45425ee8b7 Mon Sep 17 00:00:00 2001 From: kayomn Date: Wed, 18 Jan 2023 17:15:41 +0000 Subject: [PATCH 26/27] Tidy up code and file structure --- black.png | 3 + black.png.import | 34 +++ editor.scn | 4 +- editor/brush_hard_circle_mask.png | 3 + editor/brush_hard_circle_mask.png.import | 14 ++ editor/edit_mode_button_group.res | 3 + project.godot | 17 +- .../dynamic_terrain_instance_3d.gd | 99 ++++---- terrain/{ => paints}/arid_grass_albedo.png | 0 .../{ => paints}/arid_grass_albedo.png.import | 6 +- .../{ => paints}/arid_grass_displacement.png | 0 .../arid_grass_displacement.png.import | 6 +- terrain/{ => paints}/arid_grass_normal.png | 0 .../{ => paints}/arid_grass_normal.png.import | 6 +- terrain/{ => paints}/arid_grass_roughness.png | 0 .../arid_grass_roughness.png.import | 6 +- terrain/paints/arid_grass_terrain_paint.res | 3 + .../cobblestone_albedo.png} | 0 .../cobblestone_albedo.png.import} | 6 +- .../cobblestone_displacement.png} | 0 .../cobblestone_displacement.png.import} | 6 +- .../cobblestone_normal.png} | 0 .../cobblestone_normal.png.import} | 6 +- .../cobblestone_roughness.png} | 0 .../cobblestone_roughness.png.import} | 6 +- terrain/paints/cobblestone_terrain_paint.res | 3 + terrain/{ => paints}/default_albedo.png | 0 .../{ => paints}/default_albedo.png.import | 8 +- terrain/paints/default_terrain_paint.res | 3 + terrain/{ => paints}/desert_sand_albedo.png | 0 .../desert_sand_albedo.png.import | 6 +- .../{ => paints}/desert_sand_displacement.png | 0 .../desert_sand_displacement.png.import | 6 +- terrain/{ => paints}/desert_sand_normal.png | 0 .../desert_sand_normal.png.import | 6 +- .../{ => paints}/desert_sand_roughness.png | 0 .../desert_sand_roughness.png.import | 6 +- terrain/paints/desert_sand_terrain_paint.res | 3 + terrain/{ => paints}/dry_mud_albedo.png | 0 .../{ => paints}/dry_mud_albedo.png.import | 6 +- terrain/{ => paints}/dry_mud_displacement.png | 0 .../dry_mud_displacement.png.import | 6 +- terrain/{ => paints}/dry_mud_normal.png | 0 .../{ => paints}/dry_mud_normal.png.import | 6 +- terrain/{ => paints}/dry_mud_roughness.png | 0 .../{ => paints}/dry_mud_roughness.png.import | 6 +- terrain/paints/dry_mud_terrain_paint.res | 3 + terrain/paints/terrain_paint.gd | 13 ++ terrain/terrain.gdshader | 57 +++++ terrain/terrain_instance_3d.gd | 220 ++++++------------ terrain/terrain_shader.gdshader | 58 ----- user_interface/screen_cursor.png | 3 + user_interface/screen_cursor.png.import | 34 +++ 53 files changed, 358 insertions(+), 323 deletions(-) create mode 100644 black.png create mode 100644 black.png.import create mode 100644 editor/brush_hard_circle_mask.png create mode 100644 editor/brush_hard_circle_mask.png.import create mode 100644 editor/edit_mode_button_group.res rename editor/editable_terrain.gd => terrain/dynamic_terrain_instance_3d.gd (50%) rename terrain/{ => paints}/arid_grass_albedo.png (100%) rename terrain/{ => paints}/arid_grass_albedo.png.import (69%) rename terrain/{ => paints}/arid_grass_displacement.png (100%) rename terrain/{ => paints}/arid_grass_displacement.png.import (67%) rename terrain/{ => paints}/arid_grass_normal.png (100%) rename terrain/{ => paints}/arid_grass_normal.png.import (69%) rename terrain/{ => paints}/arid_grass_roughness.png (100%) rename terrain/{ => paints}/arid_grass_roughness.png.import (68%) create mode 100644 terrain/paints/arid_grass_terrain_paint.res rename terrain/{cobbled_limestone_albedo.png => paints/cobblestone_albedo.png} (100%) rename terrain/{cobbled_limestone_albedo.png.import => paints/cobblestone_albedo.png.import} (68%) rename terrain/{cobbled_limestone_displacement.png => paints/cobblestone_displacement.png} (100%) rename terrain/{cobbled_limestone_displacement.png.import => paints/cobblestone_displacement.png.import} (66%) rename terrain/{cobbled_limestone_normal.png => paints/cobblestone_normal.png} (100%) rename terrain/{cobbled_limestone_normal.png.import => paints/cobblestone_normal.png.import} (68%) rename terrain/{cobbled_limestone_roughness.png => paints/cobblestone_roughness.png} (100%) rename terrain/{cobbled_limestone_roughness.png.import => paints/cobblestone_roughness.png.import} (67%) create mode 100644 terrain/paints/cobblestone_terrain_paint.res rename terrain/{ => paints}/default_albedo.png (100%) rename terrain/{ => paints}/default_albedo.png.import (57%) create mode 100644 terrain/paints/default_terrain_paint.res rename terrain/{ => paints}/desert_sand_albedo.png (100%) rename terrain/{ => paints}/desert_sand_albedo.png.import (69%) rename terrain/{ => paints}/desert_sand_displacement.png (100%) rename terrain/{ => paints}/desert_sand_displacement.png.import (75%) rename terrain/{ => paints}/desert_sand_normal.png (100%) rename terrain/{ => paints}/desert_sand_normal.png.import (69%) rename terrain/{ => paints}/desert_sand_roughness.png (100%) rename terrain/{ => paints}/desert_sand_roughness.png.import (68%) create mode 100644 terrain/paints/desert_sand_terrain_paint.res rename terrain/{ => paints}/dry_mud_albedo.png (100%) rename terrain/{ => paints}/dry_mud_albedo.png.import (70%) rename terrain/{ => paints}/dry_mud_displacement.png (100%) rename terrain/{ => paints}/dry_mud_displacement.png.import (68%) rename terrain/{ => paints}/dry_mud_normal.png (100%) rename terrain/{ => paints}/dry_mud_normal.png.import (70%) rename terrain/{ => paints}/dry_mud_roughness.png (100%) rename terrain/{ => paints}/dry_mud_roughness.png.import (69%) create mode 100644 terrain/paints/dry_mud_terrain_paint.res create mode 100644 terrain/paints/terrain_paint.gd create mode 100644 terrain/terrain.gdshader delete mode 100644 terrain/terrain_shader.gdshader create mode 100644 user_interface/screen_cursor.png create mode 100644 user_interface/screen_cursor.png.import diff --git a/black.png b/black.png new file mode 100644 index 0000000..ec595a4 --- /dev/null +++ b/black.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ce78e46a0340f336b19b46c5ae401650bd9ef87073dc096b22d8f523c8e9ca3 +size 86 diff --git a/black.png.import b/black.png.import new file mode 100644 index 0000000..3a677f9 --- /dev/null +++ b/black.png.import @@ -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 diff --git a/editor.scn b/editor.scn index 118917f..0abad7a 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14a8eed4e79bdfd17670c48b25fcd5e8f278c0f2bdfed80dbe5714051390111e -size 8518 +oid sha256:600cffba10aeef4586ec866fda388f7a80810e246c4f274f9a2c73216818fdd5 +size 8034 diff --git a/editor/brush_hard_circle_mask.png b/editor/brush_hard_circle_mask.png new file mode 100644 index 0000000..e2558d3 --- /dev/null +++ b/editor/brush_hard_circle_mask.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b2a9fa190051309bfc4f5aac029fee8a3a44f6e493aa0a27df8b99eb06100da +size 434 diff --git a/editor/brush_hard_circle_mask.png.import b/editor/brush_hard_circle_mask.png.import new file mode 100644 index 0000000..0c12c25 --- /dev/null +++ b/editor/brush_hard_circle_mask.png.import @@ -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] + diff --git a/editor/edit_mode_button_group.res b/editor/edit_mode_button_group.res new file mode 100644 index 0000000..589ebec --- /dev/null +++ b/editor/edit_mode_button_group.res @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae83902fc3965c6ed4c5a8fdcb1ebadf66fccd27ea585f0b80c71a3707190662 +size 194 diff --git a/project.godot b/project.godot index 86fc427..542c2e5 100644 --- a/project.godot +++ b/project.godot @@ -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" diff --git a/editor/editable_terrain.gd b/terrain/dynamic_terrain_instance_3d.gd similarity index 50% rename from editor/editable_terrain.gd rename to terrain/dynamic_terrain_instance_3d.gd index 7682acb..7b2ba12 100644 --- a/editor/editable_terrain.gd +++ b/terrain/dynamic_terrain_instance_3d.gd @@ -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 diff --git a/terrain/arid_grass_albedo.png b/terrain/paints/arid_grass_albedo.png similarity index 100% rename from terrain/arid_grass_albedo.png rename to terrain/paints/arid_grass_albedo.png diff --git a/terrain/arid_grass_albedo.png.import b/terrain/paints/arid_grass_albedo.png.import similarity index 69% rename from terrain/arid_grass_albedo.png.import rename to terrain/paints/arid_grass_albedo.png.import index 0f79b47..ec0dd15 100644 --- a/terrain/arid_grass_albedo.png.import +++ b/terrain/paints/arid_grass_albedo.png.import @@ -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] diff --git a/terrain/arid_grass_displacement.png b/terrain/paints/arid_grass_displacement.png similarity index 100% rename from terrain/arid_grass_displacement.png rename to terrain/paints/arid_grass_displacement.png diff --git a/terrain/arid_grass_displacement.png.import b/terrain/paints/arid_grass_displacement.png.import similarity index 67% rename from terrain/arid_grass_displacement.png.import rename to terrain/paints/arid_grass_displacement.png.import index 2231012..44bb805 100644 --- a/terrain/arid_grass_displacement.png.import +++ b/terrain/paints/arid_grass_displacement.png.import @@ -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] diff --git a/terrain/arid_grass_normal.png b/terrain/paints/arid_grass_normal.png similarity index 100% rename from terrain/arid_grass_normal.png rename to terrain/paints/arid_grass_normal.png diff --git a/terrain/arid_grass_normal.png.import b/terrain/paints/arid_grass_normal.png.import similarity index 69% rename from terrain/arid_grass_normal.png.import rename to terrain/paints/arid_grass_normal.png.import index 22fb4d4..fe11398 100644 --- a/terrain/arid_grass_normal.png.import +++ b/terrain/paints/arid_grass_normal.png.import @@ -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] diff --git a/terrain/arid_grass_roughness.png b/terrain/paints/arid_grass_roughness.png similarity index 100% rename from terrain/arid_grass_roughness.png rename to terrain/paints/arid_grass_roughness.png diff --git a/terrain/arid_grass_roughness.png.import b/terrain/paints/arid_grass_roughness.png.import similarity index 68% rename from terrain/arid_grass_roughness.png.import rename to terrain/paints/arid_grass_roughness.png.import index 2bdf3d4..577efda 100644 --- a/terrain/arid_grass_roughness.png.import +++ b/terrain/paints/arid_grass_roughness.png.import @@ -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] diff --git a/terrain/paints/arid_grass_terrain_paint.res b/terrain/paints/arid_grass_terrain_paint.res new file mode 100644 index 0000000..c74ae9f --- /dev/null +++ b/terrain/paints/arid_grass_terrain_paint.res @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa81b3c8d2c39bb6abcf24a5a021f12b3e1050cffeb9d94145dd57560255205b +size 297 diff --git a/terrain/cobbled_limestone_albedo.png b/terrain/paints/cobblestone_albedo.png similarity index 100% rename from terrain/cobbled_limestone_albedo.png rename to terrain/paints/cobblestone_albedo.png diff --git a/terrain/cobbled_limestone_albedo.png.import b/terrain/paints/cobblestone_albedo.png.import similarity index 68% rename from terrain/cobbled_limestone_albedo.png.import rename to terrain/paints/cobblestone_albedo.png.import index f5e6ff0..a6fb1ba 100644 --- a/terrain/cobbled_limestone_albedo.png.import +++ b/terrain/paints/cobblestone_albedo.png.import @@ -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] diff --git a/terrain/cobbled_limestone_displacement.png b/terrain/paints/cobblestone_displacement.png similarity index 100% rename from terrain/cobbled_limestone_displacement.png rename to terrain/paints/cobblestone_displacement.png diff --git a/terrain/cobbled_limestone_displacement.png.import b/terrain/paints/cobblestone_displacement.png.import similarity index 66% rename from terrain/cobbled_limestone_displacement.png.import rename to terrain/paints/cobblestone_displacement.png.import index 8b1c968..375525b 100644 --- a/terrain/cobbled_limestone_displacement.png.import +++ b/terrain/paints/cobblestone_displacement.png.import @@ -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] diff --git a/terrain/cobbled_limestone_normal.png b/terrain/paints/cobblestone_normal.png similarity index 100% rename from terrain/cobbled_limestone_normal.png rename to terrain/paints/cobblestone_normal.png diff --git a/terrain/cobbled_limestone_normal.png.import b/terrain/paints/cobblestone_normal.png.import similarity index 68% rename from terrain/cobbled_limestone_normal.png.import rename to terrain/paints/cobblestone_normal.png.import index d72444f..a1070c8 100644 --- a/terrain/cobbled_limestone_normal.png.import +++ b/terrain/paints/cobblestone_normal.png.import @@ -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] diff --git a/terrain/cobbled_limestone_roughness.png b/terrain/paints/cobblestone_roughness.png similarity index 100% rename from terrain/cobbled_limestone_roughness.png rename to terrain/paints/cobblestone_roughness.png diff --git a/terrain/cobbled_limestone_roughness.png.import b/terrain/paints/cobblestone_roughness.png.import similarity index 67% rename from terrain/cobbled_limestone_roughness.png.import rename to terrain/paints/cobblestone_roughness.png.import index 0c2675e..abc898b 100644 --- a/terrain/cobbled_limestone_roughness.png.import +++ b/terrain/paints/cobblestone_roughness.png.import @@ -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] diff --git a/terrain/paints/cobblestone_terrain_paint.res b/terrain/paints/cobblestone_terrain_paint.res new file mode 100644 index 0000000..2fcdbe9 --- /dev/null +++ b/terrain/paints/cobblestone_terrain_paint.res @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27eefce861ebe9d90bfc1ffa242cf38b96332f65d04aafe404f17f85f9d2daa3 +size 292 diff --git a/terrain/default_albedo.png b/terrain/paints/default_albedo.png similarity index 100% rename from terrain/default_albedo.png rename to terrain/paints/default_albedo.png diff --git a/terrain/default_albedo.png.import b/terrain/paints/default_albedo.png.import similarity index 57% rename from terrain/default_albedo.png.import rename to terrain/paints/default_albedo.png.import index 3be27a2..c64f065 100644 --- a/terrain/default_albedo.png.import +++ b/terrain/paints/default_albedo.png.import @@ -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] diff --git a/terrain/paints/default_terrain_paint.res b/terrain/paints/default_terrain_paint.res new file mode 100644 index 0000000..e8202f5 --- /dev/null +++ b/terrain/paints/default_terrain_paint.res @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f7bc9218bdd88690b9994999715acb1e1233299ba9fe008d835a6cc9ff592f0 +size 294 diff --git a/terrain/desert_sand_albedo.png b/terrain/paints/desert_sand_albedo.png similarity index 100% rename from terrain/desert_sand_albedo.png rename to terrain/paints/desert_sand_albedo.png diff --git a/terrain/desert_sand_albedo.png.import b/terrain/paints/desert_sand_albedo.png.import similarity index 69% rename from terrain/desert_sand_albedo.png.import rename to terrain/paints/desert_sand_albedo.png.import index 783a2e1..1f2e15d 100644 --- a/terrain/desert_sand_albedo.png.import +++ b/terrain/paints/desert_sand_albedo.png.import @@ -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] diff --git a/terrain/desert_sand_displacement.png b/terrain/paints/desert_sand_displacement.png similarity index 100% rename from terrain/desert_sand_displacement.png rename to terrain/paints/desert_sand_displacement.png diff --git a/terrain/desert_sand_displacement.png.import b/terrain/paints/desert_sand_displacement.png.import similarity index 75% rename from terrain/desert_sand_displacement.png.import rename to terrain/paints/desert_sand_displacement.png.import index 64aea08..82b5ebc 100644 --- a/terrain/desert_sand_displacement.png.import +++ b/terrain/paints/desert_sand_displacement.png.import @@ -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] diff --git a/terrain/desert_sand_normal.png b/terrain/paints/desert_sand_normal.png similarity index 100% rename from terrain/desert_sand_normal.png rename to terrain/paints/desert_sand_normal.png diff --git a/terrain/desert_sand_normal.png.import b/terrain/paints/desert_sand_normal.png.import similarity index 69% rename from terrain/desert_sand_normal.png.import rename to terrain/paints/desert_sand_normal.png.import index 6efdb8b..3a23fa6 100644 --- a/terrain/desert_sand_normal.png.import +++ b/terrain/paints/desert_sand_normal.png.import @@ -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] diff --git a/terrain/desert_sand_roughness.png b/terrain/paints/desert_sand_roughness.png similarity index 100% rename from terrain/desert_sand_roughness.png rename to terrain/paints/desert_sand_roughness.png diff --git a/terrain/desert_sand_roughness.png.import b/terrain/paints/desert_sand_roughness.png.import similarity index 68% rename from terrain/desert_sand_roughness.png.import rename to terrain/paints/desert_sand_roughness.png.import index f1bcb24..3ba225d 100644 --- a/terrain/desert_sand_roughness.png.import +++ b/terrain/paints/desert_sand_roughness.png.import @@ -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] diff --git a/terrain/paints/desert_sand_terrain_paint.res b/terrain/paints/desert_sand_terrain_paint.res new file mode 100644 index 0000000..e60460e --- /dev/null +++ b/terrain/paints/desert_sand_terrain_paint.res @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1908a2b3087d64658ebe340148554aa109658b52c1fbf662d340dec961f36a6 +size 293 diff --git a/terrain/dry_mud_albedo.png b/terrain/paints/dry_mud_albedo.png similarity index 100% rename from terrain/dry_mud_albedo.png rename to terrain/paints/dry_mud_albedo.png diff --git a/terrain/dry_mud_albedo.png.import b/terrain/paints/dry_mud_albedo.png.import similarity index 70% rename from terrain/dry_mud_albedo.png.import rename to terrain/paints/dry_mud_albedo.png.import index 1c786de..e09d798 100644 --- a/terrain/dry_mud_albedo.png.import +++ b/terrain/paints/dry_mud_albedo.png.import @@ -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] diff --git a/terrain/dry_mud_displacement.png b/terrain/paints/dry_mud_displacement.png similarity index 100% rename from terrain/dry_mud_displacement.png rename to terrain/paints/dry_mud_displacement.png diff --git a/terrain/dry_mud_displacement.png.import b/terrain/paints/dry_mud_displacement.png.import similarity index 68% rename from terrain/dry_mud_displacement.png.import rename to terrain/paints/dry_mud_displacement.png.import index 7e09efe..5390a1d 100644 --- a/terrain/dry_mud_displacement.png.import +++ b/terrain/paints/dry_mud_displacement.png.import @@ -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] diff --git a/terrain/dry_mud_normal.png b/terrain/paints/dry_mud_normal.png similarity index 100% rename from terrain/dry_mud_normal.png rename to terrain/paints/dry_mud_normal.png diff --git a/terrain/dry_mud_normal.png.import b/terrain/paints/dry_mud_normal.png.import similarity index 70% rename from terrain/dry_mud_normal.png.import rename to terrain/paints/dry_mud_normal.png.import index 0ac7cfa..0c6e5c3 100644 --- a/terrain/dry_mud_normal.png.import +++ b/terrain/paints/dry_mud_normal.png.import @@ -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] diff --git a/terrain/dry_mud_roughness.png b/terrain/paints/dry_mud_roughness.png similarity index 100% rename from terrain/dry_mud_roughness.png rename to terrain/paints/dry_mud_roughness.png diff --git a/terrain/dry_mud_roughness.png.import b/terrain/paints/dry_mud_roughness.png.import similarity index 69% rename from terrain/dry_mud_roughness.png.import rename to terrain/paints/dry_mud_roughness.png.import index c70c4af..b513027 100644 --- a/terrain/dry_mud_roughness.png.import +++ b/terrain/paints/dry_mud_roughness.png.import @@ -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] diff --git a/terrain/paints/dry_mud_terrain_paint.res b/terrain/paints/dry_mud_terrain_paint.res new file mode 100644 index 0000000..e6ff33e --- /dev/null +++ b/terrain/paints/dry_mud_terrain_paint.res @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:555af3c288502203b9fa4b8a71f5acdb273a988262a0bffb929a218540158561 +size 289 diff --git a/terrain/paints/terrain_paint.gd b/terrain/paints/terrain_paint.gd new file mode 100644 index 0000000..d03f0c8 --- /dev/null +++ b/terrain/paints/terrain_paint.gd @@ -0,0 +1,13 @@ +class_name TerrainPaint extends Resource + +## +## +## +@export +var albedo_map: Texture2D = null + +## +## +## +@export +var normal_map: Texture2D = null diff --git a/terrain/terrain.gdshader b/terrain/terrain.gdshader new file mode 100644 index 0000000..1985d01 --- /dev/null +++ b/terrain/terrain.gdshader @@ -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)); +} diff --git a/terrain/terrain_instance_3d.gd b/terrain/terrain_instance_3d.gd index 951fcce..6112823 100644 --- a/terrain/terrain_instance_3d.gd +++ b/terrain/terrain_instance_3d.gd @@ -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) diff --git a/terrain/terrain_shader.gdshader b/terrain/terrain_shader.gdshader deleted file mode 100644 index 796de7b..0000000 --- a/terrain/terrain_shader.gdshader +++ /dev/null @@ -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)); -} diff --git a/user_interface/screen_cursor.png b/user_interface/screen_cursor.png new file mode 100644 index 0000000..25806e0 --- /dev/null +++ b/user_interface/screen_cursor.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b8dab1e2c7e5332869da473f48344d1bc24f246b00b6c96f00fde340b9596c2 +size 22518 diff --git a/user_interface/screen_cursor.png.import b/user_interface/screen_cursor.png.import new file mode 100644 index 0000000..bef1a74 --- /dev/null +++ b/user_interface/screen_cursor.png.import @@ -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 From 748a22347a79289bb42b6762dbe6be8f9dda2452 Mon Sep 17 00:00:00 2001 From: kayomn Date: Thu, 19 Jan 2023 00:49:44 +0000 Subject: [PATCH 27/27] Amend code review changes --- editor.scn | 4 +- editor/edit_mode_button_group.res | 4 +- project.godot | 6 +++ terrain/dynamic_terrain_instance_3d.gd | 23 ++++---- terrain/paints/terrain_paint.gd | 4 +- user_interface/button_selection.gd | 75 ++++++++++++++++++++++++++ 6 files changed, 100 insertions(+), 16 deletions(-) create mode 100644 user_interface/button_selection.gd diff --git a/editor.scn b/editor.scn index 0abad7a..a04e07e 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:600cffba10aeef4586ec866fda388f7a80810e246c4f274f9a2c73216818fdd5 -size 8034 +oid sha256:f440fd5671e8668e3c627d3447cecb4d8b508cdd4590805726edadf663e4c6e7 +size 7923 diff --git a/editor/edit_mode_button_group.res b/editor/edit_mode_button_group.res index 589ebec..9e6a97d 100644 --- a/editor/edit_mode_button_group.res +++ b/editor/edit_mode_button_group.res @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae83902fc3965c6ed4c5a8fdcb1ebadf66fccd27ea585f0b80c71a3707190662 -size 194 +oid sha256:dcc7954349a7ed68391dfbfd0e8369169da156218b5b856dda3005ef0708ad16 +size 202 diff --git a/project.godot b/project.godot index 542c2e5..b065f79 100644 --- a/project.godot +++ b/project.godot @@ -14,6 +14,11 @@ _global_script_classes=[{ "language": &"GDScript", "path": "res://terrain/dynamic_terrain_instance_3d.gd" }, { +"base": "HFlowContainer", +"class": &"ItemSelection", +"language": &"GDScript", +"path": "res://user_interface/button_selection.gd" +}, { "base": "Node3D", "class": &"PlayerController", "language": &"GDScript", @@ -36,6 +41,7 @@ _global_script_classes=[{ }] _global_script_class_icons={ "DynamicTerrainInstance3D": "", +"ItemSelection": "", "PlayerController": "", "Settings": "", "TerrainInstance3D": "", diff --git a/terrain/dynamic_terrain_instance_3d.gd b/terrain/dynamic_terrain_instance_3d.gd index 7b2ba12..07f5d75 100644 --- a/terrain/dynamic_terrain_instance_3d.gd +++ b/terrain/dynamic_terrain_instance_3d.gd @@ -31,11 +31,11 @@ func clear(clear_elevation: float) -> void: _editable_texture.update(_editable_image) ## +## 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] +## 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, delta: float) -> void: - +func oscillate(point: Vector2i, level: float, mask: Image, mask_scale: float, intensity: float) -> void: var mask_size := mask.get_size() var brush_source := _get_brush_area(point, mask_size, mask_scale) @@ -54,17 +54,17 @@ func oscillate(point: Vector2i, level: float, var pixel := _editable_image.get_pixelv(coord) _editable_image.set_pixelv(coord, Color(pixel.r, pixel.g, pixel.b, - lerpf(pixel.a, level, intensity * delta *\ + lerpf(pixel.a, level, intensity *\ mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a)).clamp()) _editable_texture.update(_editable_image) ## +## Paints the texture of the terrain toward a value of [code]color[/code] multiplied by +## [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]. ## -## -func paint(point: Vector2i, color: Color, - mask: Image, mask_scale: float, intensity: float, delta: float) -> void: - +func paint(point: Vector2i, color: Color, mask: Image, mask_scale: float, intensity: float) -> void: var mask_size := mask.get_size() var brush_source := _get_brush_area(point, mask_size, mask_scale) @@ -82,7 +82,7 @@ func paint(point: Vector2i, color: Color, var coord := brush_target.position + Vector2i(x, y) var pixel := _editable_image.get_pixelv(coord) - var mask_intensity_delta := intensity * delta *\ + var mask_intensity_delta := intensity *\ mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a _editable_image.set_pixelv(coord, Color( @@ -93,7 +93,10 @@ func paint(point: Vector2i, color: Color, _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) diff --git a/terrain/paints/terrain_paint.gd b/terrain/paints/terrain_paint.gd index d03f0c8..450acfa 100644 --- a/terrain/paints/terrain_paint.gd +++ b/terrain/paints/terrain_paint.gd @@ -1,13 +1,13 @@ class_name TerrainPaint extends Resource ## -## +## Terrain albedo map data. ## @export var albedo_map: Texture2D = null ## -## +## Terrain normal map data. ## @export var normal_map: Texture2D = null diff --git a/user_interface/button_selection.gd b/user_interface/button_selection.gd new file mode 100644 index 0000000..d94a691 --- /dev/null +++ b/user_interface/button_selection.gd @@ -0,0 +1,75 @@ +@tool +class_name ItemSelection extends HFlowContainer + +## +## An item has been selected via GUI selection or [method select_item]. +## +signal item_selected(index: int) + +var _button_group := ButtonGroup.new() + +## +## Number of items in the selection. +## +var item_count: int: + get: + return _button_group.get_buttons().size() + +func _get_configuration_warnings() -> PackedStringArray: + return PackedStringArray() + +## +## Adds a new item with no text and only [code]icon[/code] as the icon to the selection. +## +func add_icon_item(icon: Texture2D) -> void: + var child_count := get_child_count() + var button := Button.new() + + button.icon = icon + button.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER + button.toggle_mode = true + button.button_group = _button_group + button.button_pressed = child_count == 0 + + button.pressed.connect(func () -> void: select_item(child_count)) + add_child(button) + +## +## Returns the icon used by the item at [code]index[/code]. +## +## An assertion is raised if [code]index[/code] is out of bounds from the item count. +## +func get_item_icon(index: int) -> Texture2D: + var buttons := _button_group.get_buttons() + + assert(index < buttons.size(), "index out of range") + + var button := buttons[index] as Button + + return null if (button == null) else button.icon + +## +## Returns the currently selected item index or [code]-1[/code] if no item is selected. +## +func get_selected_item() -> int: + var pressed_button := _button_group.get_pressed_button() + + return -1 if (pressed_button == null) else pressed_button.get_index() + +## +## Selects the item at [code]index[/code], emitting [signal item_selected] at the end. +## +## An assertion is raised if [code]index[/code] is out of bounds from the item count. +## +func select_item(index: int) -> void: + var buttons := _button_group.get_buttons() + + assert(index < buttons.size(), "index out of range") + + var pressed_button := _button_group.get_pressed_button() + + if pressed_button != null: + pressed_button.set_pressed_no_signal(false) + + buttons[index].set_pressed_no_signal(true) + item_selected.emit(index)