diff --git a/src/Shaders/AutoInvertColors.gdshader b/src/Shaders/AutoInvertColors.gdshader index 0f28ee869..28d1e4e54 100644 --- a/src/Shaders/AutoInvertColors.gdshader +++ b/src/Shaders/AutoInvertColors.gdshader @@ -1,13 +1,25 @@ shader_type canvas_item; +#include "CanvasCommon.gdshaderinc" uniform sampler2D screen_texture : hint_screen_texture; +uniform bool hollow_shapes = true; void fragment() { vec4 color = texture(TEXTURE, UV); - COLOR = color; vec3 inverted = vec3(1.0) - color.rgb; vec3 screen_color = textureLod(screen_texture, SCREEN_UV, 0.0).rgb; float screen_avg = (screen_color.r + screen_color.g + screen_color.b) / 3.0; - COLOR.rgb = inverted * step(0.5, screen_avg) + color.rgb * step(screen_avg, 0.5); + color.rgb = inverted * step(0.5, screen_avg) + color.rgb * step(screen_avg, 0.5); + if (hollow_shapes) { + if (COLOR.a > 0.0 && has_contrary_neighbour(UV, TEXTURE_PIXEL_SIZE, TEXTURE)) { + COLOR = color; + } + else { // Erase the texture's pixels in order to only keep the outline visible + COLOR.a = 0.0; + } + } + else { + COLOR = color; + } } diff --git a/src/Shaders/CanvasCommon.gdshaderinc b/src/Shaders/CanvasCommon.gdshaderinc new file mode 100644 index 000000000..6127ebbe3 --- /dev/null +++ b/src/Shaders/CanvasCommon.gdshaderinc @@ -0,0 +1,24 @@ +uniform float width : hint_range(0, 2) = 0.05; + +bool is_zero_approx(float num) { + return num < 0.0001; +} + + +bool has_contrary_neighbour(vec2 uv, vec2 texture_pixel_size, sampler2D tex) { + float i = -ceil(width); + float j = ceil(width); + float x1 = abs(i) > width ? width * sign(i) : i; + float x2 = abs(j) > width ? width * sign(j) : j; + float y1 = abs(i) > width ? width * sign(i) : i; + float y2 = abs(j) > width ? width * sign(j) : j; + + vec2 xy1 = uv + texture_pixel_size * vec2(x1, y1); + vec2 xy2 = uv + texture_pixel_size * vec2(x2, y2); + + if (xy1 != clamp(xy1, vec2(0.0), vec2(1.0)) || is_zero_approx(texture(tex, xy1).a) || xy2 != clamp(xy2, vec2(0.0), vec2(1.0)) || is_zero_approx(texture(tex, xy2).a)) { + return true; + } + + return false; +} diff --git a/src/Shaders/MarchingAntsOutline.gdshader b/src/Shaders/MarchingAntsOutline.gdshader index 2b99519b3..06205b034 100644 --- a/src/Shaders/MarchingAntsOutline.gdshader +++ b/src/Shaders/MarchingAntsOutline.gdshader @@ -2,39 +2,15 @@ // Also thanks to https://andreashackel.de/tech-art/stripes-shader-1/ for the stripe tutorial shader_type canvas_item; +#include "CanvasCommon.gdshaderinc" uniform vec4 first_color : source_color = vec4(1.0); uniform vec4 second_color : source_color = vec4(0.0, 0.0, 0.0, 1.0); uniform bool animated = true; -uniform float width : hint_range(0, 2) = 0.05; uniform float frequency = 50.0; uniform float stripe_direction : hint_range(0, 1) = 0.5; -bool is_zero_approx(float num) { - return num < 0.0001; -} - - -bool has_contrary_neighbour(vec2 uv, vec2 texture_pixel_size, sampler2D tex) { - float i = -ceil(width); - float j = ceil(width); - float x1 = abs(i) > width ? width * sign(i) : i; - float x2 = abs(j) > width ? width * sign(j) : j; - float y1 = abs(i) > width ? width * sign(i) : i; - float y2 = abs(j) > width ? width * sign(j) : j; - - vec2 xy1 = uv + texture_pixel_size * vec2(x1, y1); - vec2 xy2 = uv + texture_pixel_size * vec2(x2, y2); - - if (xy1 != clamp(xy1, vec2(0.0), vec2(1.0)) || is_zero_approx(texture(tex, xy1).a) || xy2 != clamp(xy2, vec2(0.0), vec2(1.0)) || is_zero_approx(texture(tex, xy2).a)) { - return true; - } - - return false; -} - void fragment() { - COLOR = texture(TEXTURE, UV); vec2 ts = TEXTURE_PIXEL_SIZE; if (COLOR.a > 0.0 && has_contrary_neighbour(UV, ts, TEXTURE)) { @@ -47,8 +23,7 @@ void fragment() { float value = floor(fract(pos) + 0.5); COLOR = mix(first_color, second_color, step(1.0, mod(value, 2.0))); } - else { - // Erase the texture's pixels in order to only keep the outline visible + else { // Erase the texture's pixels in order to only keep the outline visible COLOR.a = 0.0; } } diff --git a/src/UI/Canvas/Canvas.tscn b/src/UI/Canvas/Canvas.tscn index 9981e961f..1f7f66329 100644 --- a/src/UI/Canvas/Canvas.tscn +++ b/src/UI/Canvas/Canvas.tscn @@ -28,15 +28,17 @@ blend_mode = 4 [sub_resource type="ShaderMaterial" id="2"] shader = ExtResource("9") +shader_parameter/width = 0.05 shader_parameter/first_color = Color(1, 1, 1, 1) shader_parameter/second_color = Color(0, 0, 0, 1) shader_parameter/animated = true -shader_parameter/width = 0.05 shader_parameter/frequency = 200.0 shader_parameter/stripe_direction = 0.5 [sub_resource type="ShaderMaterial" id="3"] shader = ExtResource("17_lowhf") +shader_parameter/width = 0.05 +shader_parameter/hollow_shapes = true [node name="Canvas" type="Node2D"] material = SubResource("ShaderMaterial_6b0ox") diff --git a/src/UI/Canvas/Previews.gd b/src/UI/Canvas/Previews.gd index 82340a881..1ef10fcee 100644 --- a/src/UI/Canvas/Previews.gd +++ b/src/UI/Canvas/Previews.gd @@ -1,6 +1,10 @@ extends Node2D +func _ready() -> void: + Global.camera.zoom_changed.connect(_update_on_zoom) + + func _input(event: InputEvent) -> void: if event is InputEventMouse or event is InputEventKey: queue_redraw() @@ -9,3 +13,7 @@ func _input(event: InputEvent) -> void: func _draw() -> void: if Global.can_draw: Tools.draw_preview() + + +func _update_on_zoom() -> void: + material.set_shader_parameter("width", 1.0 / Global.camera.zoom.x)