mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-02-22 21:43:13 +00:00
Compare commits
3 commits
28e143e033
...
321102e8fe
Author | SHA1 | Date | |
---|---|---|---|
|
321102e8fe | ||
|
c2ce4a4a69 | ||
|
b3021ceb67 |
10 changed files with 426 additions and 67 deletions
|
@ -963,6 +963,26 @@ msgstr ""
|
||||||
msgid "Shadow color:"
|
msgid "Shadow color:"
|
||||||
msgstr ""
|
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"
|
msgid "Gradient"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -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)
|
"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]
|
[input_devices]
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ enum EffectsMenu {
|
||||||
PALETTIZE,
|
PALETTIZE,
|
||||||
PIXELIZE,
|
PIXELIZE,
|
||||||
POSTERIZE,
|
POSTERIZE,
|
||||||
|
GAUSSIAN_BLUR,
|
||||||
GRADIENT,
|
GRADIENT,
|
||||||
GRADIENT_MAP,
|
GRADIENT_MAP,
|
||||||
SHADER
|
SHADER
|
||||||
|
@ -762,6 +763,7 @@ func _initialize_keychain() -> void:
|
||||||
&"drop_shadow": Keychain.InputAction.new("", "Effects menu", true),
|
&"drop_shadow": Keychain.InputAction.new("", "Effects menu", true),
|
||||||
&"adjust_hsv": Keychain.InputAction.new("", "Effects menu", true),
|
&"adjust_hsv": Keychain.InputAction.new("", "Effects menu", true),
|
||||||
&"adjust_brightness_contrast": 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": Keychain.InputAction.new("", "Effects menu", true),
|
||||||
&"gradient_map": Keychain.InputAction.new("", "Effects menu", true),
|
&"gradient_map": Keychain.InputAction.new("", "Effects menu", true),
|
||||||
&"palettize": Keychain.InputAction.new("", "Effects menu", true),
|
&"palettize": Keychain.InputAction.new("", "Effects menu", true),
|
||||||
|
|
|
@ -15,24 +15,27 @@ static func create_ui_for_shader_uniforms(
|
||||||
) -> void:
|
) -> void:
|
||||||
var code := shader.code.split("\n")
|
var code := shader.code.split("\n")
|
||||||
var uniforms: PackedStringArray = []
|
var uniforms: PackedStringArray = []
|
||||||
|
var uniform_data: PackedStringArray = []
|
||||||
var description: String = ""
|
var description: String = ""
|
||||||
var descriprion_began := false
|
var description_began := false
|
||||||
for line in code:
|
for line in code:
|
||||||
## Management of "end" tags
|
# Management of "end" tags
|
||||||
if line.begins_with("// (end DESCRIPTION)"):
|
if line.begins_with("// (end DESCRIPTION)"):
|
||||||
descriprion_began = false
|
description_began = false
|
||||||
if descriprion_began:
|
if description_began:
|
||||||
description += "\n" + line.strip_edges()
|
description += "\n" + line.strip_edges()
|
||||||
|
|
||||||
## Detection of uniforms
|
# Detection of uniforms
|
||||||
if line.begins_with("uniform"):
|
if line.begins_with("uniform"):
|
||||||
uniforms.append(line)
|
uniforms.append(line)
|
||||||
|
if line.begins_with("// uniform_data"):
|
||||||
|
uniform_data.append(line)
|
||||||
|
|
||||||
## Management of "begin" tags
|
# Management of "begin" tags
|
||||||
elif line.begins_with("// (begin DESCRIPTION)"):
|
elif line.begins_with("// (begin DESCRIPTION)"):
|
||||||
descriprion_began = true
|
description_began = true
|
||||||
## Validation of begin/end tags
|
# Validation of begin/end tags
|
||||||
if descriprion_began == true: ## Description started but never ended. treat it as an error
|
if description_began == true: # Description started but never ended. treat it as an error
|
||||||
print("Shader description started but never finished. Assuming empty description")
|
print("Shader description started but never finished. Assuming empty description")
|
||||||
description = ""
|
description = ""
|
||||||
if not description.is_empty():
|
if not description.is_empty():
|
||||||
|
@ -59,12 +62,51 @@ static func create_ui_for_shader_uniforms(
|
||||||
var u_init := u_left_side[0].split(" ")
|
var u_init := u_left_side[0].split(" ")
|
||||||
var u_type := u_init[1]
|
var u_type := u_init[1]
|
||||||
var u_name := u_init[2]
|
var u_name := u_init[2]
|
||||||
|
# Find custom data of the uniform, if any exists
|
||||||
|
# Right now it only checks if a uniform should have another type of node
|
||||||
|
# Such as integers having OptionButtons
|
||||||
|
# But in the future it could be expanded to include custom names or descriptions.
|
||||||
|
var custom_data: PackedStringArray = []
|
||||||
|
var type_override := ""
|
||||||
|
for data in uniform_data:
|
||||||
|
if u_name in data:
|
||||||
|
var line_to_examine := data.split(" ")
|
||||||
|
if line_to_examine[3] == "type::":
|
||||||
|
var temp_splitter := data.split("::")
|
||||||
|
if temp_splitter.size() > 1:
|
||||||
|
type_override = temp_splitter[1].strip_edges()
|
||||||
|
|
||||||
|
custom_data.append(data)
|
||||||
var humanized_u_name := Keychain.humanize_snake_case(u_name) + ":"
|
var humanized_u_name := Keychain.humanize_snake_case(u_name) + ":"
|
||||||
|
|
||||||
if u_type == "float" or u_type == "int":
|
if u_type == "float" or u_type == "int":
|
||||||
|
var hbox := HBoxContainer.new()
|
||||||
var label := Label.new()
|
var label := Label.new()
|
||||||
label.text = humanized_u_name
|
label.text = humanized_u_name
|
||||||
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
hbox.add_child(label)
|
||||||
|
if type_override.begins_with("OptionButton"):
|
||||||
|
var option_button := OptionButton.new()
|
||||||
|
option_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
option_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
||||||
|
option_button.item_selected.connect(value_changed.bind(u_name))
|
||||||
|
var items := (
|
||||||
|
type_override
|
||||||
|
. replace("OptionButton ", "")
|
||||||
|
. replace("[", "")
|
||||||
|
. replace("]", "")
|
||||||
|
. split("||")
|
||||||
|
)
|
||||||
|
for item in items:
|
||||||
|
option_button.add_item(item)
|
||||||
|
if u_value != "":
|
||||||
|
option_button.select(int(u_value))
|
||||||
|
if params.has(u_name):
|
||||||
|
option_button.select(params[u_name])
|
||||||
|
else:
|
||||||
|
params[u_name] = option_button.selected
|
||||||
|
hbox.add_child(option_button)
|
||||||
|
else:
|
||||||
var slider := ValueSlider.new()
|
var slider := ValueSlider.new()
|
||||||
slider.allow_greater = true
|
slider.allow_greater = true
|
||||||
slider.allow_lesser = true
|
slider.allow_lesser = true
|
||||||
|
@ -115,8 +157,6 @@ static func create_ui_for_shader_uniforms(
|
||||||
slider.step = step
|
slider.step = step
|
||||||
slider.value_changed.connect(value_changed.bind(u_name))
|
slider.value_changed.connect(value_changed.bind(u_name))
|
||||||
slider.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
slider.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
||||||
var hbox := HBoxContainer.new()
|
|
||||||
hbox.add_child(label)
|
|
||||||
hbox.add_child(slider)
|
hbox.add_child(slider)
|
||||||
parent_node.add_child(hbox)
|
parent_node.add_child(hbox)
|
||||||
elif u_type == "vec2" or u_type == "ivec2" or u_type == "uvec2":
|
elif u_type == "vec2" or u_type == "ivec2" or u_type == "uvec2":
|
||||||
|
@ -352,23 +392,23 @@ static func _get_loaded_texture(params: Dictionary, parameter_name: String) -> I
|
||||||
if parameter_name in params:
|
if parameter_name in params:
|
||||||
if params[parameter_name] is ImageTexture:
|
if params[parameter_name] is ImageTexture:
|
||||||
return params[parameter_name].get_image()
|
return params[parameter_name].get_image()
|
||||||
var image = Image.create_empty(64, 64, false, Image.FORMAT_RGBA8)
|
var image := Image.create_empty(64, 64, false, Image.FORMAT_RGBA8)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
|
||||||
static func _shader_update_texture(
|
static func _shader_update_texture(
|
||||||
resource_proj: ResourceProject, value_changed: Callable, parameter_name: String
|
resource_proj: ResourceProject, value_changed: Callable, parameter_name: String
|
||||||
) -> void:
|
) -> void:
|
||||||
var warnings = ""
|
var warnings := ""
|
||||||
if resource_proj.frames.size() > 1:
|
if resource_proj.frames.size() > 1:
|
||||||
warnings += "This resource is intended to have 1 frame only. Extra frames will be ignored."
|
warnings += "This resource is intended to have 1 frame only. Extra frames will be ignored."
|
||||||
if resource_proj.layers.size() > 1:
|
if resource_proj.layers.size() > 1:
|
||||||
warnings += "\nThis resource is intended to have 1 layer only. layers will be blended."
|
warnings += "\nThis resource is intended to have 1 layer only. layers will be blended."
|
||||||
|
|
||||||
var updated_image = Image.create_empty(
|
var updated_image := Image.create_empty(
|
||||||
resource_proj.size.x, resource_proj.size.y, false, Image.FORMAT_RGBA8
|
resource_proj.size.x, resource_proj.size.y, false, Image.FORMAT_RGBA8
|
||||||
)
|
)
|
||||||
var frame = resource_proj.frames[0]
|
var frame := resource_proj.frames[0]
|
||||||
DrawingAlgos.blend_layers(updated_image, frame, Vector2i.ZERO, resource_proj)
|
DrawingAlgos.blend_layers(updated_image, frame, Vector2i.ZERO, resource_proj)
|
||||||
value_changed.call(ImageTexture.create_from_image(updated_image), parameter_name)
|
value_changed.call(ImageTexture.create_from_image(updated_image), parameter_name)
|
||||||
if not warnings.is_empty():
|
if not warnings.is_empty():
|
||||||
|
@ -378,7 +418,7 @@ static func _shader_update_texture(
|
||||||
static func _modify_texture_resource(
|
static func _modify_texture_resource(
|
||||||
image: Image, resource_name: StringName, update_callable: Callable
|
image: Image, resource_name: StringName, update_callable: Callable
|
||||||
) -> void:
|
) -> void:
|
||||||
var resource_proj = ResourceProject.new([], resource_name, image.get_size())
|
var resource_proj := ResourceProject.new([], resource_name, image.get_size())
|
||||||
resource_proj.layers.append(PixelLayer.new(resource_proj))
|
resource_proj.layers.append(PixelLayer.new(resource_proj))
|
||||||
resource_proj.frames.append(resource_proj.new_empty_frame())
|
resource_proj.frames.append(resource_proj.new_empty_frame())
|
||||||
resource_proj.frames[0].cels[0].set_content(image)
|
resource_proj.frames[0].cels[0].set_content(image)
|
||||||
|
|
141
src/Shaders/Effects/GaussianBlur.gdshader
Normal file
141
src/Shaders/Effects/GaussianBlur.gdshader
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
// https://godotshaders.com/shader/gaussian-blur-functions-for-gles2/
|
||||||
|
// Licensed under MIT.
|
||||||
|
shader_type canvas_item;
|
||||||
|
|
||||||
|
// uniform_data blur_type type:: OptionButton [Xor's Gaussian Blur||Monk's Multi-Pass Gaussian Blur||NoDev's Single-Pass Gaussian Blur||NoDev's Multi-Pass Gaussian Blur]
|
||||||
|
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
|
||||||
|
// Defaults from: https://www.shadertoy.com/view/Xltfzj
|
||||||
|
//
|
||||||
|
// BLUR BLURRINESS (Default 8.0)
|
||||||
|
// BLUR ITERATIONS (Default 16.0 - More is better but slower)
|
||||||
|
// BLUR QUALITY (Default 4.0 - More is better but slower)
|
||||||
|
//
|
||||||
|
// Desc.: Don't have the best performance but will run on almost
|
||||||
|
// anything, although, if developing for mobile, is better to use
|
||||||
|
// 'texture_nodevgaussian(...) instead'.
|
||||||
|
vec4 texture_xorgaussian(sampler2D tex, vec2 uv, vec2 pixel_size, float blurriness, int iterations, int quality) {
|
||||||
|
vec2 radius = blurriness / (1.0 / pixel_size).xy;
|
||||||
|
vec4 blurred_tex = texture(tex, uv);
|
||||||
|
|
||||||
|
for(float d = 0.0; d < TAU; d += TAU / float(iterations)) {
|
||||||
|
for(float i = 1.0 / float(quality); i <= 1.0; i += 1.0 / float(quality)) {
|
||||||
|
vec2 directions = uv + vec2(cos(d), sin(d)) * radius * i;
|
||||||
|
blurred_tex += texture(tex, directions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blurred_tex /= float(quality) * float(iterations) + 1.0;
|
||||||
|
|
||||||
|
return blurred_tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Experience-Monks' fast gaussian blur function
|
||||||
|
// Link: https://github.com/Experience-Monks/glsl-fast-gaussian-blur/
|
||||||
|
//
|
||||||
|
// BLUR ITERATIONS (Default 16.0 - More is better but slower)
|
||||||
|
// BLUR DIRECTION (Direction in which the blur is applied, use vec2(1, 0) for first pass and vec2(0, 1) for second pass)
|
||||||
|
//
|
||||||
|
// Desc.: ACTUALLY PRETTY SLOW but still pretty good for custom cinematic
|
||||||
|
// bloom effects, since this needs render 2 passes
|
||||||
|
vec4 texture_monksgaussian_multipass(sampler2D tex, vec2 uv, vec2 pixel_size, int iterations, vec2 direction) {
|
||||||
|
vec4 blurred_tex = vec4(0.0);
|
||||||
|
vec2 resolution = 1.0 / pixel_size;
|
||||||
|
|
||||||
|
for (int i = 0; i < iterations; i++ ) {
|
||||||
|
float size = float(iterations - i);
|
||||||
|
|
||||||
|
vec2 off1 = vec2(1.3846153846) * (direction * size);
|
||||||
|
vec2 off2 = vec2(3.2307692308) * (direction * size);
|
||||||
|
|
||||||
|
blurred_tex += texture(tex, uv) * 0.2270270270;
|
||||||
|
blurred_tex += texture(tex, uv + (off1 / resolution)) * 0.3162162162;
|
||||||
|
blurred_tex += texture(tex, uv - (off1 / resolution)) * 0.3162162162;
|
||||||
|
blurred_tex += texture(tex, uv + (off2 / resolution)) * 0.0702702703;
|
||||||
|
blurred_tex += texture(tex, uv - (off2 / resolution)) * 0.0702702703;
|
||||||
|
}
|
||||||
|
|
||||||
|
blurred_tex /= float(iterations) + 1.0;
|
||||||
|
|
||||||
|
return blurred_tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// u/_NoDev_'s gaussian blur function
|
||||||
|
// Discussion Link: https://www.reddit.com/r/godot/comments/klgfo9/help_with_shaders_in_gles2/
|
||||||
|
// Code Link: https://postimg.cc/7JDJw80d
|
||||||
|
//
|
||||||
|
// BLUR BLURRINESS (Default 8.0 - More is better but slower)
|
||||||
|
// BLUR RADIUS (Default 1.5)
|
||||||
|
// BLUR DIRECTION (Direction in which the blur is applied, use vec2(1, 0) for first pass and vec2(0, 1) for second pass)
|
||||||
|
//
|
||||||
|
// Desc.: Really fast and GOOD FOR MOST CASES, but might NOT RUN IN THE WEB!
|
||||||
|
// use 'texture_xorgaussian' instead if you found any issues.
|
||||||
|
vec4 texture_nodevgaussian_singlepass(sampler2D tex, vec2 uv, vec2 pixel_size, float blurriness, float radius) {
|
||||||
|
float n = 0.0015;
|
||||||
|
vec4 blurred_tex = vec4(0);
|
||||||
|
float weight;
|
||||||
|
|
||||||
|
for (float i = -blurriness; i <= blurriness; i++) {
|
||||||
|
float d = i / PI;
|
||||||
|
vec2 anchor = vec2(cos(d), sin(d)) * radius * i;
|
||||||
|
vec2 directions = uv + pixel_size * anchor;
|
||||||
|
blurred_tex += texture(tex, directions) * n;
|
||||||
|
if (i <= 0.0) {n += 0.0015; }
|
||||||
|
if (i > 0.0) {n -= 0.0015; }
|
||||||
|
weight += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
float norm = 1.0 / weight;
|
||||||
|
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);
|
||||||
|
float weight;
|
||||||
|
|
||||||
|
for (float i = -blurriness; i <= blurriness; i++) {
|
||||||
|
vec2 directions = uv + pixel_size * (direction * i);
|
||||||
|
blurred_tex += texture(tex, directions) * n;
|
||||||
|
if (i <= 0.0) {n += 0.0015; }
|
||||||
|
if (i > 0.0) {n -= 0.0015; }
|
||||||
|
weight += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
float norm = 1.0 / weight;
|
||||||
|
blurred_tex *= norm;
|
||||||
|
return blurred_tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
col = xorgaussian;
|
||||||
|
}
|
||||||
|
else if (blur_type == 1) {
|
||||||
|
vec4 monksgaussian_multipass = texture_monksgaussian_multipass(TEXTURE, UV, TEXTURE_PIXEL_SIZE, blur_amount, blur_direction);
|
||||||
|
col = monksgaussian_multipass;
|
||||||
|
}
|
||||||
|
else if (blur_type == 2) {
|
||||||
|
vec4 nodevgaussian_singlepass = texture_nodevgaussian_singlepass(TEXTURE, UV, TEXTURE_PIXEL_SIZE, float(blur_amount), blur_radius);
|
||||||
|
col = nodevgaussian_singlepass;
|
||||||
|
}
|
||||||
|
else if (blur_type == 3) {
|
||||||
|
vec4 nodevgaussian_multipass = texture_nodevgaussian_multipass(TEXTURE, UV, TEXTURE_PIXEL_SIZE, float(blur_amount), blur_direction);
|
||||||
|
col = nodevgaussian_multipass;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
col = texture(TEXTURE, UV);
|
||||||
|
}
|
||||||
|
vec4 output = mix(original_color.rgba, col, selection_color.a);
|
||||||
|
COLOR = output;
|
||||||
|
}
|
|
@ -4,7 +4,8 @@ render_mode unshaded;
|
||||||
|
|
||||||
uniform vec4 color : source_color = vec4(1.0);
|
uniform vec4 color : source_color = vec4(1.0);
|
||||||
uniform float width : hint_range(0, 10, 1) = 1.0;
|
uniform float width : hint_range(0, 10, 1) = 1.0;
|
||||||
uniform int pattern : hint_range(0, 2) = 0; // diamond, circle, square
|
// uniform_data pattern type:: OptionButton [Diamond||Circle||Square]
|
||||||
|
uniform int pattern : hint_range(0, 2) = 0;
|
||||||
uniform bool inside = false;
|
uniform bool inside = false;
|
||||||
uniform sampler2D selection : filter_nearest;
|
uniform sampler2D selection : filter_nearest;
|
||||||
|
|
||||||
|
|
55
src/UI/Dialogs/ImageEffects/GaussianBlur.gd
Normal file
55
src/UI/Dialogs/ImageEffects/GaussianBlur.gd
Normal 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()
|
91
src/UI/Dialogs/ImageEffects/GaussianBlur.tscn
Normal file
91
src/UI/Dialogs/ImageEffects/GaussianBlur.tscn
Normal 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"]
|
|
@ -7,6 +7,7 @@ var effects: Array[LayerEffect] = [
|
||||||
LayerEffect.new(
|
LayerEffect.new(
|
||||||
"Convolution Matrix", preload("res://src/Shaders/Effects/ConvolutionMatrix.gdshader")
|
"Convolution Matrix", preload("res://src/Shaders/Effects/ConvolutionMatrix.gdshader")
|
||||||
),
|
),
|
||||||
|
LayerEffect.new("Gaussian Blur", preload("res://src/Shaders/Effects/GaussianBlur.gdshader")),
|
||||||
LayerEffect.new("Offset", preload("res://src/Shaders/Effects/OffsetPixels.gdshader")),
|
LayerEffect.new("Offset", preload("res://src/Shaders/Effects/OffsetPixels.gdshader")),
|
||||||
LayerEffect.new("Outline", preload("res://src/Shaders/Effects/OutlineInline.gdshader")),
|
LayerEffect.new("Outline", preload("res://src/Shaders/Effects/OutlineInline.gdshader")),
|
||||||
LayerEffect.new("Drop Shadow", preload("res://src/Shaders/Effects/DropShadow.gdshader")),
|
LayerEffect.new("Drop Shadow", preload("res://src/Shaders/Effects/DropShadow.gdshader")),
|
||||||
|
|
|
@ -30,6 +30,7 @@ var hsv_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/HSVDialog.tscn")
|
||||||
var adjust_brightness_saturation_dialog := Dialog.new(
|
var adjust_brightness_saturation_dialog := Dialog.new(
|
||||||
"res://src/UI/Dialogs/ImageEffects/BrightnessContrastDialog.tscn"
|
"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_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/GradientDialog.tscn")
|
||||||
var gradient_map_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/GradientMapDialog.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")
|
var palettize_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/PalettizeDialog.tscn")
|
||||||
|
@ -405,6 +406,7 @@ func _setup_effects_menu() -> void:
|
||||||
"Palettize": "palettize",
|
"Palettize": "palettize",
|
||||||
"Pixelize": "pixelize",
|
"Pixelize": "pixelize",
|
||||||
"Posterize": "posterize",
|
"Posterize": "posterize",
|
||||||
|
"Gaussian Blur": "gaussian_blur",
|
||||||
"Gradient": "gradient",
|
"Gradient": "gradient",
|
||||||
"Gradient Map": "gradient_map",
|
"Gradient Map": "gradient_map",
|
||||||
# "Shader": ""
|
# "Shader": ""
|
||||||
|
@ -817,6 +819,8 @@ func effects_menu_id_pressed(id: int) -> void:
|
||||||
hsv_dialog.popup()
|
hsv_dialog.popup()
|
||||||
Global.EffectsMenu.BRIGHTNESS_SATURATION:
|
Global.EffectsMenu.BRIGHTNESS_SATURATION:
|
||||||
adjust_brightness_saturation_dialog.popup()
|
adjust_brightness_saturation_dialog.popup()
|
||||||
|
Global.EffectsMenu.GAUSSIAN_BLUR:
|
||||||
|
gaussian_blur_dialog.popup()
|
||||||
Global.EffectsMenu.GRADIENT:
|
Global.EffectsMenu.GRADIENT:
|
||||||
gradient_dialog.popup()
|
gradient_dialog.popup()
|
||||||
Global.EffectsMenu.GRADIENT_MAP:
|
Global.EffectsMenu.GRADIENT_MAP:
|
||||||
|
|
Loading…
Add table
Reference in a new issue