mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 09:09:47 +00:00
Add an adjust brightness/contrast image effect
Thanks to https://godotshaders.com/shader/color-manipulator/ The shader has more options than just brightness and contrast though, but I didn't know how else to name the effect. "Adjust Brightness/Contrast" makes it immediately obvious as to what the effect is about.
This commit is contained in:
parent
4d26a6dd55
commit
0ea0406233
|
@ -956,9 +956,6 @@ msgstr ""
|
|||
msgid "Shadow color:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Adjust Hue/Saturation/Value"
|
||||
msgstr ""
|
||||
|
||||
msgid "Gradient"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1012,24 +1009,64 @@ msgstr ""
|
|||
msgid "Dithering pattern:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Adjust HSV"
|
||||
msgstr ""
|
||||
|
||||
msgid "Type:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Angle:"
|
||||
msgstr ""
|
||||
|
||||
#. An image effect. Adjusts the hue, saturation and value of the colors of an image.
|
||||
msgid "Adjust Hue/Saturation/Value"
|
||||
msgstr ""
|
||||
|
||||
#. HSV stands for Hue, Saturation & Value.
|
||||
msgid "Adjust HSV"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to the hue of the colors of an image.
|
||||
msgid "Hue:"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to the saturation of the colors of an image.
|
||||
msgid "Saturation:"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to the value (as in HSV) of the colors of an image.
|
||||
msgid "Value:"
|
||||
msgstr ""
|
||||
|
||||
#. An image effect. Adjusts the brightness and contrast of the colors of an image.
|
||||
msgid "Adjust Brightness/Contrast"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to the brightness of the colors of an image.
|
||||
msgid "Brightness:"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to the contrast of the colors of an image.
|
||||
msgid "Contrast:"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to the red value of the colors of an image.
|
||||
msgid "Red value:"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to the green value of the colors of an image.
|
||||
msgid "Green value:"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to the blue value of the colors of an image.
|
||||
msgid "Blue value:"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to a color that tints an image.
|
||||
msgid "Tint color:"
|
||||
msgstr ""
|
||||
|
||||
#. Refers to the factor (how much) a color tints an image.
|
||||
msgid "Tint effect factor:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Apply"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -677,6 +677,10 @@ adjust_hsv={
|
|||
"deadzone": 0.5,
|
||||
"events": []
|
||||
}
|
||||
adjust_brightness_saturation={
|
||||
"deadzone": 0.5,
|
||||
"events": []
|
||||
}
|
||||
gradient={
|
||||
"deadzone": 0.5,
|
||||
"events": []
|
||||
|
|
|
@ -59,6 +59,7 @@ enum EffectsMenu {
|
|||
INVERT_COLORS,
|
||||
DESATURATION,
|
||||
HSV,
|
||||
BRIGHTNESS_SATURATION,
|
||||
PALETTIZE,
|
||||
PIXELIZE,
|
||||
POSTERIZE,
|
||||
|
@ -746,6 +747,7 @@ func _initialize_keychain() -> void:
|
|||
&"outline": Keychain.InputAction.new("", "Effects menu", true),
|
||||
&"drop_shadow": Keychain.InputAction.new("", "Effects menu", true),
|
||||
&"adjust_hsv": Keychain.InputAction.new("", "Effects menu", true),
|
||||
&"adjust_brightness_saturation": 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),
|
||||
|
|
60
src/Shaders/Effects/BrightnessContrast.gdshader
Normal file
60
src/Shaders/Effects/BrightnessContrast.gdshader
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Shader from https://godotshaders.com/shader/color-manipulator/
|
||||
// Licensed under CC0
|
||||
shader_type canvas_item;
|
||||
render_mode unshaded;
|
||||
|
||||
uniform float brightness : hint_range(-1, 1) = 0;
|
||||
uniform float contrast : hint_range(0, 3) = 1.0;
|
||||
uniform float saturation : hint_range(0, 3) = 1.0;
|
||||
|
||||
uniform float red_value : hint_range(0, 1) = 1.0;
|
||||
uniform float green_value : hint_range(0, 1) = 1.0;
|
||||
uniform float blue_value : hint_range(0, 1) = 1.0;
|
||||
|
||||
uniform vec4 tint_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
uniform float tint_effect_factor : hint_range(0, 1) = 0.0;
|
||||
|
||||
uniform sampler2D selection : filter_nearest;
|
||||
|
||||
mat4 contrastMatrix( float _contrast )
|
||||
{
|
||||
float t = ( 1.0 - _contrast ) / 2.0;
|
||||
return mat4(
|
||||
vec4(_contrast, 0, 0, 0),
|
||||
vec4(0, _contrast, 0, 0),
|
||||
vec4(0, 0, _contrast, 0),
|
||||
vec4(t, t, t, 1));
|
||||
}
|
||||
|
||||
mat4 brightnessMatrix( float _brightness )
|
||||
{
|
||||
return mat4( vec4(1, 0, 0, 0),
|
||||
vec4(0, 1, 0, 0),
|
||||
vec4(0, 0, 1, 0),
|
||||
vec4(_brightness, _brightness, _brightness, 1));
|
||||
}
|
||||
|
||||
mat4 saturationMatrix( float _saturation )
|
||||
{
|
||||
vec3 luminance = vec3( 0.3086, 0.6094, 0.0820 );
|
||||
float oneMinusSat = 1.0 - _saturation;
|
||||
|
||||
vec3 red = vec3( luminance.x * oneMinusSat );
|
||||
red+= vec3(_saturation, 0, 0) * red_value;
|
||||
vec3 green = vec3( luminance.y * oneMinusSat );
|
||||
green += vec3(0, _saturation, 0) * green_value;
|
||||
vec3 blue = vec3( luminance.z * oneMinusSat );
|
||||
blue += vec3(0, 0, _saturation ) * blue_value;
|
||||
|
||||
return mat4(vec4(red, 0), vec4(green, 0), vec4(blue, 0), vec4(0, 0, 0, 1));
|
||||
}
|
||||
|
||||
void fragment()
|
||||
{
|
||||
vec4 original_color = texture(TEXTURE, UV);
|
||||
vec4 selection_color = texture(selection, UV);
|
||||
vec4 c2 = original_color * tint_color;
|
||||
vec4 col = brightnessMatrix(brightness) * contrastMatrix(contrast) * saturationMatrix(saturation) * mix(original_color, c2, tint_effect_factor);
|
||||
vec3 output = mix(original_color.rgb, col.rgb, selection_color.a);
|
||||
COLOR = vec4(output.rgb, original_color.a);
|
||||
}
|
87
src/UI/Dialogs/ImageEffects/BrightnessContrastDialog.gd
Normal file
87
src/UI/Dialogs/ImageEffects/BrightnessContrastDialog.gd
Normal file
|
@ -0,0 +1,87 @@
|
|||
extends ImageEffect
|
||||
|
||||
enum Animate { BRIGHTNESS, CONTRAST, SATURATION, RED, GREEN, BLUE, TINT_EFFECT_FACTOR }
|
||||
|
||||
var shader := preload("res://src/Shaders/Effects/BrightnessContrast.gdshader")
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
var sm := ShaderMaterial.new()
|
||||
sm.shader = shader
|
||||
preview.set_material(sm)
|
||||
animate_panel.add_float_property("Brightness", $VBoxContainer/BrightnessSlider)
|
||||
animate_panel.add_float_property("Contrast", $VBoxContainer/ContrastSlider)
|
||||
animate_panel.add_float_property("Saturation", $VBoxContainer/SaturationSlider)
|
||||
animate_panel.add_float_property("Red", $VBoxContainer/RedSlider)
|
||||
animate_panel.add_float_property("Green", $VBoxContainer/GreenSlider)
|
||||
animate_panel.add_float_property("Blue", $VBoxContainer/BlueSlider)
|
||||
animate_panel.add_float_property("Tint effect factor", $VBoxContainer/TintSlider)
|
||||
|
||||
|
||||
func commit_action(cel: Image, project := Global.current_project) -> void:
|
||||
var brightness := animate_panel.get_animated_value(commit_idx, Animate.BRIGHTNESS) / 100.0
|
||||
var contrast := animate_panel.get_animated_value(commit_idx, Animate.CONTRAST) / 100.0
|
||||
var saturation := animate_panel.get_animated_value(commit_idx, Animate.SATURATION) / 100.0
|
||||
var red := animate_panel.get_animated_value(commit_idx, Animate.RED) / 100.0
|
||||
var green := animate_panel.get_animated_value(commit_idx, Animate.GREEN) / 100.0
|
||||
var blue := animate_panel.get_animated_value(commit_idx, Animate.BLUE) / 100.0
|
||||
var tint_color: Color = $VBoxContainer/TintColorContainer/TintColor.color
|
||||
var tint_effect_factor := (
|
||||
animate_panel.get_animated_value(commit_idx, Animate.TINT_EFFECT_FACTOR) / 100.0
|
||||
)
|
||||
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 := {
|
||||
"brightness": brightness,
|
||||
"contrast": contrast,
|
||||
"saturation": saturation,
|
||||
"red_value": red,
|
||||
"blue_value": blue,
|
||||
"green_value": green,
|
||||
"tint_color": tint_color,
|
||||
"tint_effect_factor": tint_effect_factor,
|
||||
"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_brightness_slider_value_changed(_value: float) -> void:
|
||||
update_preview()
|
||||
|
||||
|
||||
func _on_contrast_slider_value_changed(_value: float) -> void:
|
||||
update_preview()
|
||||
|
||||
|
||||
func _on_saturation_slider_value_changed(_value: float) -> void:
|
||||
update_preview()
|
||||
|
||||
|
||||
func _on_red_slider_value_changed(_value: float) -> void:
|
||||
update_preview()
|
||||
|
||||
|
||||
func _on_green_slider_value_changed(_value: float) -> void:
|
||||
update_preview()
|
||||
|
||||
|
||||
func _on_blue_slider_value_changed(_value: float) -> void:
|
||||
update_preview()
|
||||
|
||||
|
||||
func _on_tint_color_color_changed(_color: Color) -> void:
|
||||
update_preview()
|
||||
|
||||
|
||||
func _on_tint_slider_value_changed(_value: float) -> void:
|
||||
update_preview()
|
143
src/UI/Dialogs/ImageEffects/BrightnessContrastDialog.tscn
Normal file
143
src/UI/Dialogs/ImageEffects/BrightnessContrastDialog.tscn
Normal file
|
@ -0,0 +1,143 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://7hslmewq0w4a"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bybqhhayl5ay5" path="res://src/UI/Dialogs/ImageEffects/ImageEffectParent.tscn" id="1_5wfra"]
|
||||
[ext_resource type="Script" path="res://src/UI/Dialogs/ImageEffects/BrightnessContrastDialog.gd" id="2_msv0o"]
|
||||
[ext_resource type="Script" path="res://src/UI/Nodes/ValueSlider.gd" id="3_2epr4"]
|
||||
|
||||
[node name="BrightnessContrastDialog" instance=ExtResource("1_5wfra")]
|
||||
title = "Adjust Brightness/Contrast"
|
||||
size = Vector2i(362, 540)
|
||||
visible = true
|
||||
script = ExtResource("2_msv0o")
|
||||
|
||||
[node name="VBoxContainer" parent="." index="3"]
|
||||
offset_bottom = 491.0
|
||||
|
||||
[node name="BrightnessSlider" type="TextureProgressBar" parent="VBoxContainer" index="2"]
|
||||
custom_minimum_size = Vector2(32, 24)
|
||||
layout_mode = 2
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
theme_type_variation = &"ValueSlider"
|
||||
min_value = -100.0
|
||||
nine_patch_stretch = true
|
||||
stretch_margin_left = 3
|
||||
stretch_margin_top = 3
|
||||
stretch_margin_right = 3
|
||||
stretch_margin_bottom = 3
|
||||
script = ExtResource("3_2epr4")
|
||||
prefix = "Brightness:"
|
||||
|
||||
[node name="ContrastSlider" type="TextureProgressBar" parent="VBoxContainer" index="3"]
|
||||
custom_minimum_size = Vector2(32, 24)
|
||||
layout_mode = 2
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
theme_type_variation = &"ValueSlider"
|
||||
max_value = 300.0
|
||||
value = 100.0
|
||||
nine_patch_stretch = true
|
||||
stretch_margin_left = 3
|
||||
stretch_margin_top = 3
|
||||
stretch_margin_right = 3
|
||||
stretch_margin_bottom = 3
|
||||
script = ExtResource("3_2epr4")
|
||||
prefix = "Contrast:"
|
||||
|
||||
[node name="SaturationSlider" type="TextureProgressBar" parent="VBoxContainer" index="4"]
|
||||
custom_minimum_size = Vector2(32, 24)
|
||||
layout_mode = 2
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
theme_type_variation = &"ValueSlider"
|
||||
max_value = 300.0
|
||||
value = 100.0
|
||||
nine_patch_stretch = true
|
||||
stretch_margin_left = 3
|
||||
stretch_margin_top = 3
|
||||
stretch_margin_right = 3
|
||||
stretch_margin_bottom = 3
|
||||
script = ExtResource("3_2epr4")
|
||||
prefix = "Saturation:"
|
||||
|
||||
[node name="RedSlider" type="TextureProgressBar" parent="VBoxContainer" index="5"]
|
||||
custom_minimum_size = Vector2(32, 24)
|
||||
layout_mode = 2
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
theme_type_variation = &"ValueSlider"
|
||||
value = 100.0
|
||||
nine_patch_stretch = true
|
||||
stretch_margin_left = 3
|
||||
stretch_margin_top = 3
|
||||
stretch_margin_right = 3
|
||||
stretch_margin_bottom = 3
|
||||
script = ExtResource("3_2epr4")
|
||||
prefix = "Red value:"
|
||||
|
||||
[node name="GreenSlider" type="TextureProgressBar" parent="VBoxContainer" index="6"]
|
||||
custom_minimum_size = Vector2(32, 24)
|
||||
layout_mode = 2
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
theme_type_variation = &"ValueSlider"
|
||||
value = 100.0
|
||||
nine_patch_stretch = true
|
||||
stretch_margin_left = 3
|
||||
stretch_margin_top = 3
|
||||
stretch_margin_right = 3
|
||||
stretch_margin_bottom = 3
|
||||
script = ExtResource("3_2epr4")
|
||||
prefix = "Green value:"
|
||||
|
||||
[node name="BlueSlider" type="TextureProgressBar" parent="VBoxContainer" index="7"]
|
||||
custom_minimum_size = Vector2(32, 24)
|
||||
layout_mode = 2
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
theme_type_variation = &"ValueSlider"
|
||||
value = 100.0
|
||||
nine_patch_stretch = true
|
||||
stretch_margin_left = 3
|
||||
stretch_margin_top = 3
|
||||
stretch_margin_right = 3
|
||||
stretch_margin_bottom = 3
|
||||
script = ExtResource("3_2epr4")
|
||||
prefix = "Blue value:"
|
||||
|
||||
[node name="TintColorContainer" type="HBoxContainer" parent="VBoxContainer" index="8"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="Label" type="Label" parent="VBoxContainer/TintColorContainer" index="0"]
|
||||
layout_mode = 2
|
||||
text = "Tint color:"
|
||||
|
||||
[node name="TintColor" type="ColorPickerButton" parent="VBoxContainer/TintColorContainer" index="1"]
|
||||
custom_minimum_size = Vector2(32, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
color = Color(1, 1, 1, 1)
|
||||
|
||||
[node name="TintSlider" type="TextureProgressBar" parent="VBoxContainer" index="9"]
|
||||
custom_minimum_size = Vector2(32, 24)
|
||||
layout_mode = 2
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
theme_type_variation = &"ValueSlider"
|
||||
nine_patch_stretch = true
|
||||
stretch_margin_left = 3
|
||||
stretch_margin_top = 3
|
||||
stretch_margin_right = 3
|
||||
stretch_margin_bottom = 3
|
||||
script = ExtResource("3_2epr4")
|
||||
prefix = "Tint effect factor:"
|
||||
|
||||
[connection signal="value_changed" from="VBoxContainer/BrightnessSlider" to="." method="_on_brightness_slider_value_changed"]
|
||||
[connection signal="value_changed" from="VBoxContainer/ContrastSlider" to="." method="_on_contrast_slider_value_changed"]
|
||||
[connection signal="value_changed" from="VBoxContainer/SaturationSlider" to="." method="_on_saturation_slider_value_changed"]
|
||||
[connection signal="value_changed" from="VBoxContainer/RedSlider" to="." method="_on_red_slider_value_changed"]
|
||||
[connection signal="value_changed" from="VBoxContainer/GreenSlider" to="." method="_on_green_slider_value_changed"]
|
||||
[connection signal="value_changed" from="VBoxContainer/BlueSlider" to="." method="_on_blue_slider_value_changed"]
|
||||
[connection signal="color_changed" from="VBoxContainer/TintColorContainer/TintColor" to="." method="_on_tint_color_color_changed"]
|
||||
[connection signal="value_changed" from="VBoxContainer/TintSlider" to="." method="_on_tint_slider_value_changed"]
|
|
@ -92,6 +92,7 @@ layout_mode = 2
|
|||
size_flags_horizontal = 3
|
||||
mouse_default_cursor_shape = 2
|
||||
item_count = 4
|
||||
selected = 0
|
||||
popup/item_0/text = "Selected cels"
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "Current frame"
|
||||
|
|
|
@ -12,6 +12,10 @@ var effects: Array[LayerEffect] = [
|
|||
LayerEffect.new(
|
||||
"Adjust Hue/Saturation/Value", preload("res://src/Shaders/Effects/HSV.gdshader")
|
||||
),
|
||||
LayerEffect.new(
|
||||
"Adjust Brightness/Contrast",
|
||||
preload("res://src/Shaders/Effects/BrightnessContrast.gdshader")
|
||||
),
|
||||
LayerEffect.new("Palettize", preload("res://src/Shaders/Effects/Palettize.gdshader")),
|
||||
LayerEffect.new("Pixelize", preload("res://src/Shaders/Effects/Pixelize.gdshader")),
|
||||
LayerEffect.new("Posterize", preload("res://src/Shaders/Effects/Posterize.gdshader")),
|
||||
|
|
|
@ -27,6 +27,9 @@ var desaturate_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/Desaturat
|
|||
var outline_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/OutlineDialog.tscn")
|
||||
var drop_shadow_dialog := Dialog.new("res://src/UI/Dialogs/ImageEffects/DropShadowDialog.tscn")
|
||||
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 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")
|
||||
|
@ -398,6 +401,7 @@ func _setup_effects_menu() -> void:
|
|||
"Invert Colors": "invert_colors",
|
||||
"Desaturation": "desaturation",
|
||||
"Adjust Hue/Saturation/Value": "adjust_hsv",
|
||||
"Adjust Brightness/Saturation": "adjust_brightness_saturation",
|
||||
"Palettize": "palettize",
|
||||
"Pixelize": "pixelize",
|
||||
"Posterize": "posterize",
|
||||
|
@ -805,6 +809,8 @@ func effects_menu_id_pressed(id: int) -> void:
|
|||
drop_shadow_dialog.popup()
|
||||
Global.EffectsMenu.HSV:
|
||||
hsv_dialog.popup()
|
||||
Global.EffectsMenu.BRIGHTNESS_SATURATION:
|
||||
adjust_brightness_saturation_dialog.popup()
|
||||
Global.EffectsMenu.GRADIENT:
|
||||
gradient_dialog.popup()
|
||||
Global.EffectsMenu.GRADIENT_MAP:
|
||||
|
|
Loading…
Reference in a new issue