1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 09:09:47 +00:00

Add Gaussian Blur as an image effect

This commit is contained in:
Emmanouil Papadeas 2024-09-08 03:13:55 +03:00
parent c2ce4a4a69
commit 321102e8fe
7 changed files with 188 additions and 5 deletions

View file

@ -963,6 +963,26 @@ msgstr ""
msgid "Shadow color:"
msgstr ""
#. An image effect. https://en.wikipedia.org/wiki/Gaussian_blur
msgid "Gaussian Blur"
msgstr ""
#. The type of the Gaussian blur, an image effect.
msgid "Blur type:"
msgstr ""
#. The applied amount of Gaussian blur, an image effect.
msgid "Blur amount:"
msgstr ""
#. The applied radius of Gaussian blur, an image effect.
msgid "Blur radius:"
msgstr ""
#. The applied direction of Gaussian blur, an image effect.
msgid "Blur direction:"
msgstr ""
msgid "Gradient"
msgstr ""

View file

@ -884,6 +884,10 @@ change_layer_automatically={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"command_or_control_autoremap":true,"alt_pressed":false,"shift_pressed":true,"pressed":false,"keycode":0,"physical_keycode":4194328,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
gaussian_blur={
"deadzone": 0.5,
"events": []
}
[input_devices]

View file

@ -63,6 +63,7 @@ enum EffectsMenu {
PALETTIZE,
PIXELIZE,
POSTERIZE,
GAUSSIAN_BLUR,
GRADIENT,
GRADIENT_MAP,
SHADER
@ -762,6 +763,7 @@ func _initialize_keychain() -> void:
&"drop_shadow": Keychain.InputAction.new("", "Effects menu", true),
&"adjust_hsv": Keychain.InputAction.new("", "Effects menu", true),
&"adjust_brightness_contrast": Keychain.InputAction.new("", "Effects menu", true),
&"gaussian_blur": Keychain.InputAction.new("", "Effects menu", true),
&"gradient": Keychain.InputAction.new("", "Effects menu", true),
&"gradient_map": Keychain.InputAction.new("", "Effects menu", true),
&"palettize": Keychain.InputAction.new("", "Effects menu", true),

View file

@ -7,6 +7,7 @@ uniform int blur_type : hint_range(0, 3, 1) = 0;
uniform int blur_amount = 16;
uniform float blur_radius = 1.0;
uniform vec2 blur_direction = vec2(1, 1);
uniform sampler2D selection : filter_nearest;
// Xor's gaussian blur function
// Link: https://xorshaders.weebly.com/tutorials/blur-shaders-5-part-2
@ -93,6 +94,7 @@ vec4 texture_nodevgaussian_singlepass(sampler2D tex, vec2 uv, vec2 pixel_size, f
blurred_tex *= norm;
return blurred_tex;
}
vec4 texture_nodevgaussian_multipass(sampler2D tex, vec2 uv, vec2 pixel_size, float blurriness, vec2 direction) {
float n = 0.0015;
vec4 blurred_tex = vec4(0);
@ -112,23 +114,28 @@ vec4 texture_nodevgaussian_multipass(sampler2D tex, vec2 uv, vec2 pixel_size, fl
}
void fragment() {
vec4 original_color = texture(TEXTURE, UV);
vec4 selection_color = texture(selection, UV);
vec4 col = original_color;
if (blur_type == 0) {
vec4 xorgaussian = texture_xorgaussian(TEXTURE, UV, TEXTURE_PIXEL_SIZE, float(blur_amount), 16, 4);
COLOR = xorgaussian;
col = xorgaussian;
}
else if (blur_type == 1) {
vec4 monksgaussian_multipass = texture_monksgaussian_multipass(TEXTURE, UV, TEXTURE_PIXEL_SIZE, blur_amount, blur_direction);
COLOR = monksgaussian_multipass;
col = monksgaussian_multipass;
}
else if (blur_type == 2) {
vec4 nodevgaussian_singlepass = texture_nodevgaussian_singlepass(TEXTURE, UV, TEXTURE_PIXEL_SIZE, float(blur_amount), blur_radius);
COLOR = nodevgaussian_singlepass;
col = nodevgaussian_singlepass;
}
else if (blur_type == 3) {
vec4 nodevgaussian_multipass = texture_nodevgaussian_multipass(TEXTURE, UV, TEXTURE_PIXEL_SIZE, float(blur_amount), blur_direction);
COLOR = nodevgaussian_multipass;
col = nodevgaussian_multipass;
}
else {
COLOR = texture(TEXTURE, UV);
col = texture(TEXTURE, UV);
}
vec4 output = mix(original_color.rgba, col, selection_color.a);
COLOR = output;
}

View file

@ -0,0 +1,55 @@
extends ImageEffect
var blur_type := 0
var blur_amount := 16
var blur_radius := 1.0
var blur_direction := Vector2.ONE
var shader := preload("res://src/Shaders/Effects/GaussianBlur.gdshader")
func _ready() -> void:
super._ready()
var sm := ShaderMaterial.new()
sm.shader = shader
preview.set_material(sm)
func commit_action(cel: Image, project := Global.current_project) -> void:
var selection_tex: ImageTexture
if selection_checkbox.button_pressed and project.has_selection:
var selection := project.selection_map.return_cropped_copy(project.size)
selection_tex = ImageTexture.create_from_image(selection)
var params := {
"blur_type": blur_type,
"blur_amount": blur_amount,
"blur_radius": blur_radius,
"blur_direction": blur_direction,
"selection": selection_tex
}
if !has_been_confirmed:
for param in params:
preview.material.set_shader_parameter(param, params[param])
else:
var gen := ShaderImageEffect.new()
gen.generate_image(cel, shader, params, project.size)
func _on_blur_type_item_selected(index: int) -> void:
blur_type = index
update_preview()
func _on_blur_amount_value_changed(value: float) -> void:
blur_amount = value
update_preview()
func _on_blur_radius_value_changed(value: float) -> void:
blur_radius = value
update_preview()
func _on_blur_direction_value_changed(value: Vector2) -> void:
blur_direction = value
update_preview()

View file

@ -0,0 +1,91 @@
[gd_scene load_steps=5 format=3 uid="uid://beile55gp1bc"]
[ext_resource type="PackedScene" uid="uid://bybqhhayl5ay5" path="res://src/UI/Dialogs/ImageEffects/ImageEffectParent.tscn" id="1_cuu40"]
[ext_resource type="Script" path="res://src/UI/Dialogs/ImageEffects/GaussianBlur.gd" id="2_37xhl"]
[ext_resource type="Script" path="res://src/UI/Nodes/ValueSlider.gd" id="3_237k2"]
[ext_resource type="PackedScene" path="res://src/UI/Nodes/ValueSliderV2.tscn" id="4_yprgi"]
[node name="GaussianBlur" instance=ExtResource("1_cuu40")]
title = "Gaussian Blur"
size = Vector2i(427, 437)
visible = true
script = ExtResource("2_37xhl")
[node name="VBoxContainer" parent="." index="3"]
offset_right = 419.0
offset_bottom = 388.0
[node name="ShowAnimate" parent="VBoxContainer" index="0"]
visible = false
[node name="BlurOptions" type="GridContainer" parent="VBoxContainer" index="2"]
layout_mode = 2
columns = 2
[node name="BlurTypeLabel" type="Label" parent="VBoxContainer/BlurOptions" index="0"]
layout_mode = 2
size_flags_horizontal = 3
text = "Blur type:"
[node name="BlurType" type="OptionButton" parent="VBoxContainer/BlurOptions" index="1"]
layout_mode = 2
size_flags_horizontal = 3
selected = 0
item_count = 4
popup/item_0/text = "Xor's Gaussian Blur"
popup/item_1/text = "Monk's Multi-Pass Gaussian Blur"
popup/item_1/id = 1
popup/item_2/text = "NoDev's Single-Pass Gaussian Blur"
popup/item_2/id = 2
popup/item_3/text = "NoDev's Multi-Pass Gaussian Blur"
popup/item_3/id = 3
[node name="BlurAmountLabel" type="Label" parent="VBoxContainer/BlurOptions" index="2"]
layout_mode = 2
size_flags_horizontal = 3
text = "Blur amount:"
[node name="BlurAmount" type="TextureProgressBar" parent="VBoxContainer/BlurOptions" index="3"]
layout_mode = 2
focus_mode = 2
mouse_default_cursor_shape = 2
theme_type_variation = &"ValueSlider"
value = 16.0
nine_patch_stretch = true
stretch_margin_left = 3
stretch_margin_top = 3
stretch_margin_right = 3
stretch_margin_bottom = 3
script = ExtResource("3_237k2")
[node name="BlurRadiusLabel" type="Label" parent="VBoxContainer/BlurOptions" index="4"]
layout_mode = 2
size_flags_horizontal = 3
text = "Blur radius:"
[node name="BlurRadius" type="TextureProgressBar" parent="VBoxContainer/BlurOptions" index="5"]
layout_mode = 2
focus_mode = 2
mouse_default_cursor_shape = 2
theme_type_variation = &"ValueSlider"
value = 1.0
nine_patch_stretch = true
stretch_margin_left = 3
stretch_margin_top = 3
stretch_margin_right = 3
stretch_margin_bottom = 3
script = ExtResource("3_237k2")
[node name="BlurDirectionLabel" type="Label" parent="VBoxContainer/BlurOptions" index="6"]
layout_mode = 2
size_flags_horizontal = 3
text = "Blur direction:"
[node name="BlurDirection" parent="VBoxContainer/BlurOptions" index="7" instance=ExtResource("4_yprgi")]
layout_mode = 2
value = Vector2(1, 1)
[connection signal="item_selected" from="VBoxContainer/BlurOptions/BlurType" to="." method="_on_blur_type_item_selected"]
[connection signal="value_changed" from="VBoxContainer/BlurOptions/BlurAmount" to="." method="_on_blur_amount_value_changed"]
[connection signal="value_changed" from="VBoxContainer/BlurOptions/BlurRadius" to="." method="_on_blur_radius_value_changed"]
[connection signal="value_changed" from="VBoxContainer/BlurOptions/BlurDirection" to="." method="_on_blur_direction_value_changed"]

View file

@ -30,6 +30,7 @@ var hsv_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/HSVDialog.tscn")
var adjust_brightness_saturation_dialog := Dialog.new(
"res://src/UI/Dialogs/ImageEffects/BrightnessContrastDialog.tscn"
)
var gaussian_blur_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/GaussianBlur.tscn")
var gradient_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/GradientDialog.tscn")
var gradient_map_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/GradientMapDialog.tscn")
var palettize_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/PalettizeDialog.tscn")
@ -405,6 +406,7 @@ func _setup_effects_menu() -> void:
"Palettize": "palettize",
"Pixelize": "pixelize",
"Posterize": "posterize",
"Gaussian Blur": "gaussian_blur",
"Gradient": "gradient",
"Gradient Map": "gradient_map",
# "Shader": ""
@ -817,6 +819,8 @@ func effects_menu_id_pressed(id: int) -> void:
hsv_dialog.popup()
Global.EffectsMenu.BRIGHTNESS_SATURATION:
adjust_brightness_saturation_dialog.popup()
Global.EffectsMenu.GAUSSIAN_BLUR:
gaussian_blur_dialog.popup()
Global.EffectsMenu.GRADIENT:
gradient_dialog.popup()
Global.EffectsMenu.GRADIENT_MAP: