1
0
Fork 0
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:
Emmanouil Papadeas 2024-08-01 21:21:45 +03:00
parent 4d26a6dd55
commit 0ea0406233
9 changed files with 350 additions and 6 deletions

View file

@ -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 ""

View file

@ -677,6 +677,10 @@ adjust_hsv={
"deadzone": 0.5,
"events": []
}
adjust_brightness_saturation={
"deadzone": 0.5,
"events": []
}
gradient={
"deadzone": 0.5,
"events": []

View file

@ -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),

View 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);
}

View 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()

View 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"]

View file

@ -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"

View file

@ -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")),

View file

@ -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: