diff --git a/README.md b/README.md new file mode 100644 index 0000000..b38e167 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Balatro background + +Adapted to Godot and added uniforms for playing around + +Source: https://www.shadertoy.com/view/XXtBRr + + diff --git a/components/color_param.gd b/components/color_param.gd new file mode 100644 index 0000000..e402d19 --- /dev/null +++ b/components/color_param.gd @@ -0,0 +1,28 @@ +class_name ColorParam extends ParamField + +@onready var label: Label = $Label +@onready var popup_panel: PopupPanel = $PopupPanel +@onready var color_rect: ColorRect = $Button/ColorRect +@onready var color_picker: ColorPicker = $PopupPanel/ColorPicker + + +func setup( + dict: Dictionary, + key: String) -> void: + name = key + _d = dict + _k = key + label.text = key.capitalize() + + color_rect.color = _d[_k] + color_picker.color = _d[_k] + + +func _on_button_pressed() -> void: + popup_panel.position = get_viewport().get_mouse_position() + popup_panel.show() + + +func _on_color_picker_color_changed(color: Color) -> void: + color_rect.color = color + _d[_k] = color diff --git a/components/color_param.gd.uid b/components/color_param.gd.uid new file mode 100644 index 0000000..3f8f44d --- /dev/null +++ b/components/color_param.gd.uid @@ -0,0 +1 @@ +uid://bwensumb106vg diff --git a/components/color_param.tscn b/components/color_param.tscn new file mode 100644 index 0000000..43ca2fa --- /dev/null +++ b/components/color_param.tscn @@ -0,0 +1,48 @@ +[gd_scene load_steps=3 format=3 uid="uid://vynteayrjwyo"] + +[ext_resource type="Theme" uid="uid://t07qph6qe3g7" path="res://inspector_theme.tres" id="1_xmr10"] +[ext_resource type="Script" uid="uid://bwensumb106vg" path="res://components/color_param.gd" id="2_xmr10"] + +[node name="ColorParam" type="HBoxContainer"] +anchors_preset = 10 +anchor_right = 1.0 +grow_horizontal = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +theme = ExtResource("1_xmr10") +script = ExtResource("2_xmr10") + +[node name="Label" type="Label" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Label" + +[node name="Button" type="Button" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect" type="ColorRect" parent="Button"] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 3.0 +offset_top = 3.0 +offset_right = -3.0 +offset_bottom = -3.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 1 + +[node name="PopupPanel" type="PopupPanel" parent="."] +title = "Pick a Color" +size = Vector2i(318, 580) + +[node name="ColorPicker" type="ColorPicker" parent="PopupPanel"] +offset_left = 4.0 +offset_top = 4.0 +offset_right = 314.0 +offset_bottom = 576.0 + +[connection signal="pressed" from="Button" to="." method="_on_button_pressed"] +[connection signal="color_changed" from="PopupPanel/ColorPicker" to="." method="_on_color_picker_color_changed"] diff --git a/components/float_param.gd b/components/float_param.gd new file mode 100644 index 0000000..9804c8e --- /dev/null +++ b/components/float_param.gd @@ -0,0 +1,33 @@ +class_name FloatParam extends ParamField + + +@onready var label: Label = $Labels/Label +@onready var value_label: Label = $Labels/ValueLabel +@onready var h_slider: HSlider = $HSlider + +var decimal_places: int + +func setup( + dict: Dictionary, + key: String, + decimal_places: int = 2, + min: float = 0.0, + max: float = 1) -> void: + name = key + _d = dict + _k = key + label.text = key.capitalize() + decimal_places = decimal_places + + h_slider.min_value = min + h_slider.max_value = max + h_slider.step = 1.0 / pow(10, decimal_places) + h_slider.value = dict[key] + value_label.text = str(h_slider.value) + + h_slider.value_changed.connect(_on_h_slider_value_changed) + + +func _on_h_slider_value_changed(value: float) -> void: + value_label.text = str(value) + _d[_k] = value diff --git a/components/float_param.gd.uid b/components/float_param.gd.uid new file mode 100644 index 0000000..8a51b55 --- /dev/null +++ b/components/float_param.gd.uid @@ -0,0 +1 @@ +uid://cm12tjnh26d8q diff --git a/components/float_param.tscn b/components/float_param.tscn new file mode 100644 index 0000000..3dfba5e --- /dev/null +++ b/components/float_param.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=3 format=3 uid="uid://dpvn15tum5qq5"] + +[ext_resource type="Theme" uid="uid://t07qph6qe3g7" path="res://inspector_theme.tres" id="1_8buni"] +[ext_resource type="Script" uid="uid://cm12tjnh26d8q" path="res://components/float_param.gd" id="2_mbky6"] + +[node name="FloatControl" type="HBoxContainer"] +anchors_preset = 10 +anchor_right = 1.0 +grow_horizontal = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +theme = ExtResource("1_8buni") +script = ExtResource("2_mbky6") + +[node name="Labels" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="Labels"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Label" + +[node name="ValueLabel" type="Label" parent="Labels"] +layout_mode = 2 +text = "100" + +[node name="HSlider" type="HSlider" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 diff --git a/components/param_field.gd b/components/param_field.gd new file mode 100644 index 0000000..8255952 --- /dev/null +++ b/components/param_field.gd @@ -0,0 +1,4 @@ +class_name ParamField extends HBoxContainer + +var _d: Dictionary +var _k: String diff --git a/components/param_field.gd.uid b/components/param_field.gd.uid new file mode 100644 index 0000000..4e0cfc9 --- /dev/null +++ b/components/param_field.gd.uid @@ -0,0 +1 @@ +uid://dpbttno55qmoe diff --git a/components/vec2_param.gd b/components/vec2_param.gd new file mode 100644 index 0000000..060c03a --- /dev/null +++ b/components/vec2_param.gd @@ -0,0 +1,28 @@ +class_name Vec2Param extends ParamField + +@onready var label: Label = $Label + +@onready var spin_box_x: SpinBox = $HBoxContainer/SpinBox_X +@onready var spin_box_y: SpinBox = $HBoxContainer/SpinBox_Y + +var decimal_places: int + +func setup( + dict: Dictionary, + key: String) -> void: + name = key + _d = dict + _k = key + label.text = key.capitalize() + decimal_places = decimal_places + + var value: Vector2 = dict[key] + spin_box_x.set_value_no_signal(value.x) + spin_box_y.set_value_no_signal(value.y) + + +func _on_spin_box_x_value_changed(value: float) -> void: + _d[_k].x = value + +func _on_spin_box_y_value_changed(value: float) -> void: + _d[_k].y = value diff --git a/components/vec2_param.gd.uid b/components/vec2_param.gd.uid new file mode 100644 index 0000000..778a75d --- /dev/null +++ b/components/vec2_param.gd.uid @@ -0,0 +1 @@ +uid://ddh6dx1piks05 diff --git a/components/vec2_param.tscn b/components/vec2_param.tscn new file mode 100644 index 0000000..ee32599 --- /dev/null +++ b/components/vec2_param.tscn @@ -0,0 +1,62 @@ +[gd_scene load_steps=5 format=3 uid="uid://h7mgbxxwg86d"] + +[ext_resource type="Theme" uid="uid://t07qph6qe3g7" path="res://inspector_theme.tres" id="1_utjn2"] +[ext_resource type="Script" uid="uid://ddh6dx1piks05" path="res://components/vec2_param.gd" id="2_j6hhs"] + +[sub_resource type="LabelSettings" id="LabelSettings_v5o8a"] +font_size = 18 +font_color = Color(1, 0.0392157, 0.0392157, 1) + +[sub_resource type="LabelSettings" id="LabelSettings_cuurt"] +font_size = 18 +font_color = Color(0.0392157, 1, 0.0392157, 1) + +[node name="Vec2Control" type="HBoxContainer"] +anchors_preset = 10 +anchor_right = 1.0 +grow_horizontal = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +theme = ExtResource("1_utjn2") +script = ExtResource("2_j6hhs") + +[node name="Label" type="Label" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Label" + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 + +[node name="Label" type="Label" parent="HBoxContainer"] +layout_mode = 2 +text = "x" +label_settings = SubResource("LabelSettings_v5o8a") + +[node name="SpinBox_X" type="SpinBox" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +min_value = -10.0 +max_value = 10.0 +step = 0.01 +custom_arrow_step = 0.01 +select_all_on_focus = true + +[node name="Label2" type="Label" parent="HBoxContainer"] +layout_mode = 2 +text = "y" +label_settings = SubResource("LabelSettings_cuurt") + +[node name="SpinBox_Y" type="SpinBox" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +min_value = -10.0 +max_value = 10.0 +step = 0.01 +custom_arrow_step = 0.01 +select_all_on_focus = true + +[connection signal="value_changed" from="HBoxContainer/SpinBox_X" to="." method="_on_spin_box_x_value_changed"] +[connection signal="value_changed" from="HBoxContainer/SpinBox_Y" to="." method="_on_spin_box_y_value_changed"] diff --git a/inspector_theme.tres b/inspector_theme.tres new file mode 100644 index 0000000..ff225ba --- /dev/null +++ b/inspector_theme.tres @@ -0,0 +1,9 @@ +[gd_resource type="Theme" format=3 uid="uid://t07qph6qe3g7"] + +[resource] +HBoxContainer/constants/separation = 16 +MarginContainer/constants/margin_bottom = 8 +MarginContainer/constants/margin_left = 8 +MarginContainer/constants/margin_right = 8 +MarginContainer/constants/margin_top = 8 +VBoxContainer/constants/separation = 8 diff --git a/main.gd b/main.gd new file mode 100644 index 0000000..c0594de --- /dev/null +++ b/main.gd @@ -0,0 +1,81 @@ +extends Control + +@onready var settings_vbox: VBoxContainer = %SettingsContainer +var shader: ShaderMaterial + + +var _data: Dictionary = { + "SPIN_ROTATION": -2.0, + "SPIN_SPEED": 7.0, + "OFFSET": Vector2(0.0, 0.0), + "COLOUR_1": Color(0.871, 0.267, 0.231), + "COLOUR_2": Color(0.0, 0.42, 0.706), + "COLOUR_3": Color(0.086, 0.137, 0.145), + "CONTRAST": 3.5, + "LIGTHING": 0.4, + "SPIN_AMOUNT": 0.25, + "PIXEL_FILTER": 745.0, + "SPIN_EASE": 1.0, +} + +var _reset_data = _data.duplicate() + +const FLOAT_PARAM = preload("res://components/float_param.tscn") +const VEC_2_PARAM = preload("res://components/vec2_param.tscn") +const COLOR_PARAM = preload("res://components/color_param.tscn") + +var uniform_controls: Array[Control] = [] + +func _ready() -> void: + var balatro_shader: TextureRect = %BalatroShader + shader = balatro_shader.material + + setup_controls() + +func setup_controls() -> void: + var i + i = create_param(FLOAT_PARAM) as FloatParam + i.setup(_data, "SPIN_ROTATION", 1, -10, 10) + i = create_param(FLOAT_PARAM) as FloatParam + i.setup(_data, "SPIN_SPEED", 1, -10, 10) + i = create_param(VEC_2_PARAM) as Vec2Param + i.setup(_data, "OFFSET") + i = create_param(COLOR_PARAM) as ColorParam + i.setup(_data, "COLOUR_1") + i = create_param(COLOR_PARAM) as ColorParam + i.setup(_data, "COLOUR_2") + i = create_param(COLOR_PARAM) as ColorParam + i.setup(_data, "COLOUR_3") + i = create_param(FLOAT_PARAM) as FloatParam + i.setup(_data, "CONTRAST", 1, 0, 10.0) + i = create_param(FLOAT_PARAM) as FloatParam + i.setup(_data, "LIGTHING") + i = create_param(FLOAT_PARAM) as FloatParam + i.setup(_data, "SPIN_AMOUNT") + i = create_param(FLOAT_PARAM) as FloatParam + i.setup(_data, "PIXEL_FILTER", 0, 64, 4096.0) + i = create_param(FLOAT_PARAM) as FloatParam + i.setup(_data, "SPIN_EASE", 2, 0, 3.0) + +func _process(delta: float) -> void: + for key in _data.keys(): + shader.set_shader_parameter(key, _data[key]) + + +func create_param(template: PackedScene) -> Control: + var c = template.instantiate() + settings_vbox.add_child(c) + uniform_controls.append(c) + return c + +func _on_reset_button_pressed() -> void: + for key in _reset_data.keys(): + _data[key] = _reset_data[key] + + while settings_vbox.get_child_count() > 0: + var c = settings_vbox.get_child(0) + settings_vbox.remove_child(c) + c.queue_free() + + + setup_controls() diff --git a/main.gd.uid b/main.gd.uid new file mode 100644 index 0000000..f7f481e --- /dev/null +++ b/main.gd.uid @@ -0,0 +1 @@ +uid://crkipt37ukh8o diff --git a/main.gdshader b/main.gdshader index 4ca1453..86491dc 100644 --- a/main.gdshader +++ b/main.gdshader @@ -1,18 +1,19 @@ shader_type canvas_item; -#define SPIN_ROTATION -2.0 -#define SPIN_SPEED 7.0 -#define OFFSET vec2(0.0) -#define COLOUR_1 vec4(0.871, 0.267, 0.231, 1.0) -#define COLOUR_2 vec4(0.0, 0.42, 0.706, 1.0) -#define COLOUR_3 vec4(0.086, 0.137, 0.145, 1.0) -#define CONTRAST 3.5 -#define LIGTHING 0.4 -#define SPIN_AMOUNT 0.25 -#define PIXEL_FILTER 745.0 -#define SPIN_EASE 1.0 -#define PI 3.14159265359 -#define IS_ROTATE false +uniform vec2 screen_size = vec2(1920, 1080); + +uniform float SPIN_ROTATION = -2.0; +uniform float SPIN_SPEED = 7.0; +uniform vec2 OFFSET = vec2(0.0); +uniform vec4 COLOUR_1: source_color = vec4(0.871, 0.267, 0.231, 1.0); +uniform vec4 COLOUR_2: source_color = vec4(0.0, 0.42, 0.706, 1.0); +uniform vec4 COLOUR_3: source_color = vec4(0.086, 0.137, 0.145, 1.0); +uniform float CONTRAST = 3.5; +uniform float LIGTHING = 0.4; +uniform float SPIN_AMOUNT = 0.25; +uniform float PIXEL_FILTER = 745.0; +uniform float SPIN_EASE = 1.0; +uniform bool IS_ROTATE = false; vec4 effect(vec2 screenSize, vec2 screen_coords) { float pixel_size = length(screenSize.xy) / PIXEL_FILTER; @@ -49,5 +50,5 @@ vec4 effect(vec2 screenSize, vec2 screen_coords) { void fragment() { - COLOR = effect(vec2(1920, 1080), vec2(UV.x * 1920.0, UV.y * 1080.0)); + COLOR = effect(screen_size, UV * screen_size); } diff --git a/main.tscn b/main.tscn index 25c2126..2df3ee7 100644 --- a/main.tscn +++ b/main.tscn @@ -1,12 +1,26 @@ -[gd_scene load_steps=4 format=3 uid="uid://vkokd44wy82r"] +[gd_scene load_steps=6 format=3 uid="uid://vkokd44wy82r"] +[ext_resource type="Script" uid="uid://crkipt37ukh8o" path="res://main.gd" id="1_0xm2m"] [ext_resource type="Shader" uid="uid://c2bxvd7878rqy" path="res://main.gdshader" id="1_ig7tw"] +[ext_resource type="Theme" uid="uid://t07qph6qe3g7" path="res://inspector_theme.tres" id="3_h2yge"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_7dm0k"] shader = ExtResource("1_ig7tw") +shader_parameter/screen_size = Vector2(16, 9) +shader_parameter/SPIN_ROTATION = -2.0 +shader_parameter/SPIN_SPEED = 7.0 +shader_parameter/OFFSET = Vector2(0, 0) +shader_parameter/COLOUR_1 = Color(0.871, 0.267, 0.231, 1) +shader_parameter/COLOUR_2 = Color(0, 0.42, 0.706, 1) +shader_parameter/COLOUR_3 = Color(0.086, 0.137, 0.145, 1) +shader_parameter/CONTRAST = 3.5 +shader_parameter/LIGTHING = 0.4 +shader_parameter/SPIN_AMOUNT = 0.25 +shader_parameter/PIXEL_FILTER = 1920.0 +shader_parameter/SPIN_EASE = 1.0 +shader_parameter/IS_ROTATE = false [sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_ig7tw"] -size = Vector2(1920, 1080) [node name="Main" type="Control"] layout_mode = 3 @@ -15,8 +29,10 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +script = ExtResource("1_0xm2m") -[node name="TextureRect" type="TextureRect" parent="."] +[node name="BalatroShader" type="TextureRect" parent="."] +unique_name_in_owner = true material = SubResource("ShaderMaterial_7dm0k") layout_mode = 1 anchors_preset = 15 @@ -25,3 +41,36 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 texture = SubResource("PlaceholderTexture2D_ig7tw") + +[node name="PanelContainer" type="PanelContainer" parent="."] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 +theme = ExtResource("3_h2yge") + +[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"] +layout_mode = 2 + +[node name="Inspector" type="VBoxContainer" parent="PanelContainer/MarginContainer"] +custom_minimum_size = Vector2(400, 0) +layout_mode = 2 + +[node name="Label" type="Label" parent="PanelContainer/MarginContainer/Inspector"] +layout_mode = 2 +text = "Properties" + +[node name="HSeparator" type="HSeparator" parent="PanelContainer/MarginContainer/Inspector"] +layout_mode = 2 + +[node name="SettingsContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer/Inspector"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="HSeparator2" type="HSeparator" parent="PanelContainer/MarginContainer/Inspector"] +layout_mode = 2 + +[node name="ResetButton" type="Button" parent="PanelContainer/MarginContainer/Inspector"] +layout_mode = 2 +text = "Reset" + +[connection signal="pressed" from="PanelContainer/MarginContainer/Inspector/ResetButton" to="." method="_on_reset_button_pressed"] diff --git a/project.godot b/project.godot index 6bd32bc..384cfdb 100644 --- a/project.godot +++ b/project.godot @@ -11,6 +11,7 @@ config_version=5 [application] config/name="balatro-shader" +run/main_scene="uid://vkokd44wy82r" config/features=PackedStringArray("4.4", "Forward Plus") config/icon="res://icon.svg"