Editor Terrain Brush #2

Merged
kayomn merged 27 commits from editor-terrain-brush into main 2023-01-19 01:51:25 +01:00
7 changed files with 75 additions and 222 deletions
Showing only changes of commit 0b19b97293 - Show all commits

BIN
editor.scn (Stored with Git LFS)

Binary file not shown.

View File

@ -53,31 +53,7 @@ func _init() -> void:
func clear(clear_color: Color) -> void: func clear(clear_color: Color) -> void:
_image.fill(clear_color) _image.fill(clear_color)
## if instance != null:
##
##
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))
instance.terrain_map.update(_image) instance.terrain_map.update(_image)
## ##
@ -98,8 +74,9 @@ func lower(point: Vector2i, mask: Image, scale: float, intensity: float, delta:
_image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b,
lerpf(pixel.a, pixel.a - (intensity * 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())
if instance != null:
instance.terrain_map.update(_image) instance.terrain_map.update(_image)
## ##
@ -118,11 +95,44 @@ func paint_blue(point: Vector2i, mask: Image, scale: float, intensity: float, de
var terrain_map_coord := draw_area.position + Vector2i(x, y) var terrain_map_coord := draw_area.position + Vector2i(x, y)
var pixel := _image.get_pixelv(terrain_map_coord) var pixel := _image.get_pixelv(terrain_map_coord)
_image.set_pixelv(terrain_map_coord, Color( var mask_intensity_delta := intensity *\
pixel.r, pixel.g, lerpf(pixel.b, intensity, delta *\ delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a
mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a),
pixel.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, 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) instance.terrain_map.update(_image)
## ##
@ -141,11 +151,16 @@ func paint_green(point: Vector2i, mask: Image, scale: float, intensity: float, d
var terrain_map_coord := draw_area.position + Vector2i(x, y) var terrain_map_coord := draw_area.position + Vector2i(x, y)
var pixel := _image.get_pixelv(terrain_map_coord) var pixel := _image.get_pixelv(terrain_map_coord)
_image.set_pixelv(terrain_map_coord, Color( var mask_intensity_delta := intensity *\
pixel.r, lerpf(pixel.g, intensity, delta *\ delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a
mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a),
pixel.b, pixel.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) instance.terrain_map.update(_image)
## ##
@ -164,11 +179,16 @@ func paint_red(point: Vector2i, mask: Image, scale: float, intensity: float, del
var terrain_map_coord := draw_area.position + Vector2i(x, y) var terrain_map_coord := draw_area.position + Vector2i(x, y)
var pixel := _image.get_pixelv(terrain_map_coord) var pixel := _image.get_pixelv(terrain_map_coord)
_image.set_pixelv(terrain_map_coord, Color( var mask_intensity_delta := intensity *\
lerpf(pixel.r, intensity, delta *\ delta * mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a
mask.get_pixel(int(x * mask_ratio.x), brush_mask_y).a),
pixel.g, pixel.b, pixel.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) instance.terrain_map.update(_image)
## ##
@ -189,8 +209,9 @@ func raise(point: Vector2i, mask: Image, scale: float, intensity: float, delta:
_image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b, _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b,
lerpf(pixel.a, pixel.a + (intensity * 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())
if instance != null:
instance.terrain_map.update(_image) instance.terrain_map.update(_image)
## ##
@ -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, _image.set_pixelv(terrain_map_coord, Color(pixel.r, pixel.g, pixel.b,
lerpf(pixel.a, level, delta * mask.get_pixel( 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())
if instance != null:
instance.terrain_map.update(_image) instance.terrain_map.update(_image)

BIN
editor/menus_theme.res (Stored with Git LFS)

Binary file not shown.

View File

@ -27,7 +27,7 @@ _global_script_classes=[{
"base": "GeometryInstance3D", "base": "GeometryInstance3D",
"class": &"TerrainInstance3D", "class": &"TerrainInstance3D",
"language": &"GDScript", "language": &"GDScript",
"path": "res://terrain_instance_3d.gd" "path": "res://terrain/terrain_instance_3d.gd"
}] }]
_global_script_class_icons={ _global_script_class_icons={
"EditableTerrain": "", "EditableTerrain": "",

View File

@ -164,6 +164,6 @@ 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._material.shader = preload("res://terrain/terrain_shader.gdshader")
self._mesh.surface_set_material(0, self._material) self._mesh.surface_set_material(0, self._material)

View File

@ -23,7 +23,7 @@ uniform vec2 SIZE;
uniform sampler2D TERRAIN_MAP : hint_default_transparent, repeat_disable; uniform sampler2D TERRAIN_MAP : hint_default_transparent, repeat_disable;
void fragment() { void fragment() {
vec2 uv = UV * SIZE; vec2 uv = UV * (SIZE / 2.0);
vec2 uv_alt = uv * -0.25; vec2 uv_alt = uv * -0.25;
vec3 splat_map = texture(TERRAIN_MAP, UV).rgb; 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); float blank = clamp(1.0 - splat_map.r - splat_map.g - splat_map.b, 0.0, 1.0);

View File

@ -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)