Improve terrain shading appearance

This commit is contained in:
kayomn 2023-01-10 18:02:26 +00:00
parent 0ba6f3e421
commit 5c4ff2b4ca
4 changed files with 20 additions and 51 deletions

BIN
editor.scn (Stored with Git LFS)

Binary file not shown.

View File

@ -93,6 +93,6 @@ editor_paint={
[rendering] [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/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

View File

@ -1,14 +1,9 @@
@tool @tool
class_name TerrainInstance3D extends GeometryInstance3D class_name TerrainInstance3D extends GeometryInstance3D
var _mesh := ArrayMesh.new() var _mesh := PlaneMesh.new()
var _material: ShaderMaterial = (func (): var _material := ShaderMaterial.new()
var material := ShaderMaterial.new()
material.shader = preload("res://terrain_shader.gdshader")
return material).call()
## ##
## ##
@ -19,47 +14,16 @@ var size: Vector2i = Vector2i.ZERO:
return size return size
set(value): set(value):
self._mesh.clear_surfaces()
var width := value.x var width := value.x
var height := value.y var height := value.y
if (width != 0) and (height != 0): if (width != 0) and (height != 0):
if (width != size.x) or (height != size.y): if (width != size.x) or (height != size.y):
var surface_tool := SurfaceTool.new() self._mesh.subdivide_width = width
self._mesh.subdivide_depth = height
surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES) self._mesh.size = value
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._material.set_shader_parameter("SIZE", Vector2(value)) self._material.set_shader_parameter("SIZE", Vector2(value))
self._mesh.surface_set_material(0, self._material)
size = value size = value
@ -194,4 +158,7 @@ var max_height := 100.0:
max_height = max(value, 0.0) max_height = max(value, 0.0)
func _init() -> void: 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) RenderingServer.instance_set_base(self.get_instance(), self._mesh)

View File

@ -46,11 +46,13 @@ float height(vec2 uv) {
void vertex() { void vertex() {
VERTEX.y = height(UV); VERTEX.y = height(UV);
vec2 texel = vec2(1.0, 1.0) / SIZE; vec2 texel_size = UV / 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));
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));
} }