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

Experimental shader feature: Expose shader's float uniforms to the UI

If the loaded shader has uniforms, they will be exposed to the UI, so the users will be able to modify the shader parameters easily. Currently only works with float uniforms.
This commit is contained in:
OverloadedOrama 2020-07-28 04:11:06 +03:00
parent 86ee5d1abf
commit ec81950139
3 changed files with 86 additions and 22 deletions

View file

@ -226,6 +226,5 @@ func load_shader() -> void:
shader.code = file_data shader.code = file_data
var shader_effect_dialog = Global.control.get_node("Dialogs/ImageEffects/ShaderEffect") var shader_effect_dialog = Global.control.get_node("Dialogs/ImageEffects/ShaderEffect")
shader_effect_dialog.preview.material.shader = shader shader_effect_dialog.change_shader(shader, file_name.get_basename())
shader_effect_dialog.shader_loaded_label.text = tr("Shader loaded:") + " " + file_name.get_basename()

View file

@ -6,14 +6,15 @@ var current_cel : Image
onready var viewport : Viewport = $VBoxContainer/ViewportContainer/Viewport onready var viewport : Viewport = $VBoxContainer/ViewportContainer/Viewport
onready var preview : TextureRect = viewport.get_node("Preview") onready var preview : TextureRect = viewport.get_node("Preview")
onready var shader_loaded_label : Label = $VBoxContainer/ShaderLoadedLabel onready var shader_loaded_label : Label = $VBoxContainer/ShaderLoadedLabel
onready var shader_params : BoxContainer = $VBoxContainer/ShaderParams
func _on_ShaderEffect_about_to_show() -> void: func _on_ShaderEffect_about_to_show() -> void:
current_cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image current_cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image
current_cel.unlock() current_cel.unlock()
viewport.size = current_cel.get_size() viewport.size = Global.current_project.size
var viewport_texture = viewport.get_texture().get_data() # var viewport_texture = viewport.get_texture().get_data()
viewport_texture.convert(Image.FORMAT_RGBA8) # viewport_texture.convert(Image.FORMAT_RGBA8)
var preview_image := Image.new() var preview_image := Image.new()
preview_image.copy_from(current_cel) preview_image.copy_from(current_cel)
@ -23,7 +24,11 @@ func _on_ShaderEffect_about_to_show() -> void:
func _on_ShaderEffect_confirmed() -> void: func _on_ShaderEffect_confirmed() -> void:
var viewport_texture = viewport.get_texture().get_data() var viewport_texture := Image.new()
viewport_texture.copy_from(viewport.get_texture().get_data())
var viewport_texture_size = viewport_texture.get_size()
if viewport_texture_size == Vector2.ZERO:
return
viewport_texture.flip_y() viewport_texture.flip_y()
viewport_texture.convert(Image.FORMAT_RGBA8) viewport_texture.convert(Image.FORMAT_RGBA8)
print(viewport_texture.get_size()) print(viewport_texture.get_size())
@ -45,12 +50,68 @@ func _on_ChooseShader_pressed() -> void:
if OS.get_name() == "HTML5": if OS.get_name() == "HTML5":
Html5FileExchange.load_shader() Html5FileExchange.load_shader()
else: else:
$FileDialog.popup_centered(Vector2(200, 340)) $FileDialog.popup_centered(Vector2(300, 340))
func _on_FileDialog_file_selected(path : String) -> void: func _on_FileDialog_file_selected(path : String) -> void:
var shader = load(path) var shader = load(path)
if !shader is Shader: if !shader is Shader:
return return
change_shader(shader, path.get_file().get_basename())
func change_shader(shader : Shader, name : String) -> void:
preview.material.shader = shader preview.material.shader = shader
shader_loaded_label.text = tr("Shader loaded:") + " " + path.get_file().get_basename() shader_loaded_label.text = tr("Shader loaded:") + " " + name
for child in shader_params.get_children():
child.queue_free()
var code = shader.code.split("\n")
var uniforms := []
for line in code:
if line.begins_with("uniform"):
uniforms.append(line)
for uniform in uniforms:
# Example uniform:
# uniform float parameter_name : hint_range(0, 255) = 100.0;
var uniform_split = uniform.split("=")
var u_value := ""
if uniform_split.size() > 1:
u_value = uniform_split[1].replace(";", "").strip_edges()
var u_left_side = uniform_split[0].split(":")
var u_hint := ""
if u_left_side.size() > 1:
u_hint = u_left_side[1].strip_edges()
var u_init = u_left_side[0].split(" ")
var u_type = u_init[1]
var u_name = u_init[2]
if u_type == "float":
var label := Label.new()
label.text = u_name
var spinbox := SpinBox.new()
spinbox.min_value = 0.01
spinbox.max_value = 255
spinbox.step = 0.01
if u_value != "":
spinbox.value = float(u_value)
spinbox.connect("value_changed", self, "set_shader_param", [u_name])
var hbox := HBoxContainer.new()
hbox.add_child(label)
hbox.add_child(spinbox)
shader_params.add_child(hbox)
# print("---")
# print(uniform_split)
# print(u_type)
# print(u_name)
# print(u_hint)
# print(u_value)
# print("--")
func set_shader_param(value, param : String) -> void:
preview.material.set_shader_param(param, value)

View file

@ -7,7 +7,7 @@
[node name="ShaderEffect" type="ConfirmationDialog"] [node name="ShaderEffect" type="ConfirmationDialog"]
margin_right = 200.0 margin_right = 200.0
margin_bottom = 228.0 margin_bottom = 228.0
rect_min_size = Vector2( 0, 0 ) rect_min_size = Vector2( 400, 300 )
resizable = true resizable = true
script = ExtResource( 2 ) script = ExtResource( 2 )
__meta__ = { __meta__ = {
@ -26,15 +26,15 @@ __meta__ = {
} }
[node name="Label" type="Label" parent="VBoxContainer"] [node name="Label" type="Label" parent="VBoxContainer"]
margin_right = 255.0 margin_right = 384.0
margin_bottom = 48.0 margin_bottom = 31.0
text = "This is an experimental feature and may not be included in the stable version" text = "This is an experimental feature and may not be included in the stable version"
autowrap = true autowrap = true
[node name="ViewportContainer" type="ViewportContainer" parent="VBoxContainer"] [node name="ViewportContainer" type="ViewportContainer" parent="VBoxContainer"]
margin_top = 52.0 margin_top = 35.0
margin_right = 255.0 margin_right = 384.0
margin_bottom = 53.0 margin_bottom = 36.0
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
@ -54,24 +54,28 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
[node name="ChooseShader" type="Button" parent="VBoxContainer"] [node name="ChooseShader" type="Button" parent="VBoxContainer"]
margin_top = 57.0 margin_top = 40.0
margin_right = 255.0 margin_right = 384.0
margin_bottom = 77.0 margin_bottom = 60.0
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
text = "Choose Shader" text = "Choose Shader"
[node name="ShaderLoadedLabel" type="Label" parent="VBoxContainer"] [node name="ShaderLoadedLabel" type="Label" parent="VBoxContainer"]
margin_top = 81.0 margin_top = 64.0
margin_right = 255.0 margin_right = 384.0
margin_bottom = 95.0 margin_bottom = 78.0
text = "No shader loaded!" text = "No shader loaded!"
autowrap = true autowrap = true
[node name="ShaderParams" type="VBoxContainer" parent="VBoxContainer"]
margin_right = 40.0
margin_bottom = 40.0
[node name="FileDialog" type="FileDialog" parent="."] [node name="FileDialog" type="FileDialog" parent="."]
margin_left = 8.0 margin_left = 8.0
margin_top = 8.0 margin_top = 8.0
margin_right = 263.0 margin_right = 392.0
margin_bottom = 192.0 margin_bottom = 264.0
window_title = "Open a File" window_title = "Open a File"
resizable = true resizable = true
mode = 0 mode = 0