From 5c4ff2b4caa835460a1cdaf0191f901109546568 Mon Sep 17 00:00:00 2001 From: kayomn Date: Tue, 10 Jan 2023 18:02:26 +0000 Subject: [PATCH] Improve terrain shading appearance --- editor.scn | 4 ++-- project.godot | 4 ++-- terrain_instance_3d.gd | 49 +++++++---------------------------------- terrain_shader.gdshader | 14 +++++++----- 4 files changed, 20 insertions(+), 51 deletions(-) diff --git a/editor.scn b/editor.scn index b6355a0..0226e59 100644 --- a/editor.scn +++ b/editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e5c5941e8562f7360298c2d3d03e21956cfa187424b2b1e01ba4bbba327f9ad -size 5123 +oid sha256:4d2a991052e7d0bfb3cb39dbcc6b609a97c192e36c4aa916602edba30e8bcbef +size 5163 diff --git a/project.godot b/project.godot index 71b682f..a9234d7 100644 --- a/project.godot +++ b/project.godot @@ -93,6 +93,6 @@ editor_paint={ [rendering] -lights_and_shadows/directional_shadow/soft_shadow_filter_quality=5 +lights_and_shadows/directional_shadow/soft_shadow_filter_quality=3 lights_and_shadows/directional_shadow/16_bits=false -lights_and_shadows/positional_shadow/soft_shadow_filter_quality=5 +lights_and_shadows/positional_shadow/soft_shadow_filter_quality=3 diff --git a/terrain_instance_3d.gd b/terrain_instance_3d.gd index c53cbc4..9680b6f 100644 --- a/terrain_instance_3d.gd +++ b/terrain_instance_3d.gd @@ -1,14 +1,9 @@ @tool class_name TerrainInstance3D extends GeometryInstance3D -var _mesh := ArrayMesh.new() +var _mesh := PlaneMesh.new() -var _material: ShaderMaterial = (func (): - var material := ShaderMaterial.new() - - material.shader = preload("res://terrain_shader.gdshader") - - return material).call() +var _material := ShaderMaterial.new() ## ## @@ -19,47 +14,16 @@ var size: Vector2i = Vector2i.ZERO: return size set(value): - self._mesh.clear_surfaces() - var width := value.x var height := value.y if (width != 0) and (height != 0): if (width != size.x) or (height != size.y): - var surface_tool := SurfaceTool.new() - - surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES) - - var center_x := width / 2.0 - var center_y := height / 2.0 - - for y in height + 1: - for x in width + 1: - surface_tool.set_uv(Vector2(x / float(width), y / float(height))) - surface_tool.set_color(Color(0.0, 0.0, 0.0, 0.0)) - surface_tool.set_normal(Vector3.UP) - surface_tool.add_vertex(Vector3(x - center_x, 0.0, y - center_y)) - - var vert := 0 - - for y in height: - for x in width: - surface_tool.add_index(vert + width + 2) - surface_tool.add_index(vert + width + 1) - surface_tool.add_index(vert + 1) - surface_tool.add_index(vert + 1) - surface_tool.add_index(vert + width + 1) - surface_tool.add_index(vert + 0) - - vert += 1 - - vert += 1 - - RenderingServer.instance_set_base(self.get_instance(), - surface_tool.commit(self._mesh).get_rid()) + self._mesh.subdivide_width = width + self._mesh.subdivide_depth = height + self._mesh.size = value self._material.set_shader_parameter("SIZE", Vector2(value)) - self._mesh.surface_set_material(0, self._material) size = value @@ -194,4 +158,7 @@ var max_height := 100.0: 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) RenderingServer.instance_set_base(self.get_instance(), self._mesh) diff --git a/terrain_shader.gdshader b/terrain_shader.gdshader index 2fca663..dfac4b8 100644 --- a/terrain_shader.gdshader +++ b/terrain_shader.gdshader @@ -46,11 +46,13 @@ float height(vec2 uv) { void vertex() { VERTEX.y = height(UV); - vec2 texel = vec2(1.0, 1.0) / SIZE; - float left = height(vec2(UV.x - texel.x, UV.y)); - float right = height(vec2(UV.x + texel.x, UV.y)); - float forward = height(vec2(UV.x, UV.y + texel.y)); - float backward = height(vec2(UV.x, UV.y - texel.y)); + vec2 texel_size = UV / SIZE; - NORMAL = normalize(vec3(left - right, 2.0, forward - forward)); + 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)); }