From 136dd038ab1cdbcf1de28752d379c07debee7f03 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas Date: Sun, 26 Jun 2022 01:21:01 +0300 Subject: [PATCH] Use shader for ColorSelect and add color similarity option --- src/Shaders/ColorSelect.gdshader | 29 ++++++++++++ src/Tools/SelectionTools/ColorSelect.gd | 57 ++++++++++++++++------- src/Tools/SelectionTools/ColorSelect.tscn | 47 +++++++++++++++++++ 3 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 src/Shaders/ColorSelect.gdshader diff --git a/src/Shaders/ColorSelect.gdshader b/src/Shaders/ColorSelect.gdshader new file mode 100644 index 00000000000..52b777df41f --- /dev/null +++ b/src/Shaders/ColorSelect.gdshader @@ -0,0 +1,29 @@ +shader_type canvas_item; +render_mode unshaded; + +uniform sampler2D selection : hint_black; +uniform vec4 color; +uniform float similarity_percent : hint_range(0.0, 100.0); +uniform int operation = 0; // 0 = add, 1 = subtract, 2 = intersect + +void fragment() { + vec4 original_color = texture(TEXTURE, UV); + float diff = distance(original_color, color); + float similarity = abs(2.0 - ((similarity_percent/100.0) * 2.0)); + vec4 col = texture(selection, UV); + if (col.rgb == vec3(0.0)) + col.a = 0.0; + + if (diff <= similarity) + { + if (operation == 0) + col = vec4(1.0); + else if (operation == 1) + col = vec4(0.0); + } + else + if (operation == 2) + col = vec4(0.0); + + COLOR = col; +} diff --git a/src/Tools/SelectionTools/ColorSelect.gd b/src/Tools/SelectionTools/ColorSelect.gd index e88a029c3cd..dfbe00b4e37 100644 --- a/src/Tools/SelectionTools/ColorSelect.gd +++ b/src/Tools/SelectionTools/ColorSelect.gd @@ -1,5 +1,27 @@ extends SelectionTool +var shader: Shader = preload("res://src/Shaders/ColorSelect.gdshader") +var _similarity := 100 + + +func get_config() -> Dictionary: + return {"similarity": _similarity} + + +func set_config(config: Dictionary) -> void: + _similarity = config.get("similarity", _similarity) + + +func update_config() -> void: + $Similarity/SimilaritySpinBox.value = _similarity + $Similarity/SimilaritySlider.value = _similarity + + +func _on_Similarity_value_changed(value: float) -> void: + _similarity = value + update_config() + save_config() + func apply_selection(position: Vector2) -> void: var project: Project = Global.current_project @@ -8,29 +30,28 @@ func apply_selection(position: Vector2) -> void: if position.x > project.size.x - 1 or position.y > project.size.y - 1: return - if !_add and !_subtract and !_intersect: - Global.canvas.selection.clear_selection() - - var selection_map_copy := SelectionMap.new() - selection_map_copy.copy_from(project.selection_map) - if _intersect: - selection_map_copy.clear() - var cel_image := Image.new() cel_image.copy_from(_get_draw_image()) cel_image.lock() var color := cel_image.get_pixelv(position) - for x in cel_image.get_width(): - for y in cel_image.get_height(): - var pos := Vector2(x, y) - if color.is_equal_approx(cel_image.get_pixelv(pos)): - if _intersect: - var selected: bool = project.selection_map.is_pixel_selected(pos) - selection_map_copy.select_pixel(pos, selected) - else: - selection_map_copy.select_pixel(pos, !_subtract) - cel_image.unlock() + var operation := 0 + if _subtract: + operation = 1 + elif _intersect: + operation = 2 + + var params := {"color": color, "similarity_percent": _similarity, "operation": operation} + if _add or _subtract or _intersect: + var selection_tex := ImageTexture.new() + selection_tex.create_from_image(project.selection_map, 0) + params["selection"] = selection_tex + var gen := ShaderImageEffect.new() + gen.generate_image(cel_image, shader, params, project.size) + cel_image.convert(Image.FORMAT_LA8) + + var selection_map_copy := SelectionMap.new() + selection_map_copy.copy_from(cel_image) project.selection_map = selection_map_copy Global.canvas.selection.big_bounding_rectangle = project.selection_map.get_used_rect() Global.canvas.selection.commit_undo("Select", undo_data) diff --git a/src/Tools/SelectionTools/ColorSelect.tscn b/src/Tools/SelectionTools/ColorSelect.tscn index e5c7a595339..96d9660f930 100644 --- a/src/Tools/SelectionTools/ColorSelect.tscn +++ b/src/Tools/SelectionTools/ColorSelect.tscn @@ -5,3 +5,50 @@ [node name="ToolOptions" instance=ExtResource( 1 )] script = ExtResource( 2 ) + +[node name="Similarity" type="VBoxContainer" parent="." index="8"] +margin_top = 166.0 +margin_right = 116.0 +margin_bottom = 228.0 +alignment = 1 + +[node name="Label" type="Label" parent="Similarity" index="0"] +margin_left = 26.0 +margin_right = 90.0 +margin_bottom = 14.0 +size_flags_horizontal = 4 +text = "Similarity:" + +[node name="SimilaritySpinBox" type="SpinBox" parent="Similarity" index="1"] +margin_left = 21.0 +margin_top = 18.0 +margin_right = 95.0 +margin_bottom = 42.0 +hint_tooltip = "How much two colors are Similar/Close together" +mouse_default_cursor_shape = 2 +size_flags_horizontal = 4 +value = 100.0 +align = 1 +suffix = "%" +__meta__ = { +"_editor_description_": "" +} + +[node name="SimilaritySlider" type="HSlider" parent="Similarity" index="2"] +margin_left = 12.0 +margin_top = 46.0 +margin_right = 104.0 +margin_bottom = 62.0 +rect_min_size = Vector2( 92, 0 ) +hint_tooltip = "How much two colors are Similar/Close together" +focus_mode = 0 +mouse_default_cursor_shape = 2 +size_flags_horizontal = 4 +size_flags_vertical = 1 +value = 100.0 +__meta__ = { +"_editor_description_": "" +} + +[connection signal="value_changed" from="Similarity/SimilaritySpinBox" to="." method="_on_Similarity_value_changed"] +[connection signal="value_changed" from="Similarity/SimilaritySlider" to="." method="_on_Similarity_value_changed"]