[EXPERIMENTAL] Added ability to load a shader as an image effect

This new feature allows users to load a .shader file (must be a GLES2 Godot shader) that will modify the image itself. This feature is experimental and possibly buggy, not all shaders are working properly and I'm not sure yet why. As such, this feature may not be included in v0.8 stable.
This commit is contained in:
OverloadedOrama 2020-07-25 16:26:57 +03:00
parent 59122f6a13
commit 186e2259ac
5 changed files with 209 additions and 6 deletions

View file

@ -69,6 +69,27 @@ func _define_js() -> void:
}
});
}
function upload_shader() {
canceled = true;
var input = document.createElement('INPUT');
input.setAttribute("type", "file");
input.setAttribute("accept", ".shader");
input.click();
input.addEventListener('change', event => {
if (event.target.files.length > 0){
canceled = false;}
var file = event.target.files[0];
var reader = new FileReader();
fileType = file.type;
fileName = file.name;
reader.readAsText(file);
reader.onloadend = function (evt) {
if (evt.target.readyState == FileReader.DONE) {
fileData = evt.target.result;
}
}
});
}
function download(fileName, byte, type) {
var buffer = Uint8Array.from(byte);
var blob = new Blob([buffer], { type: type});
@ -174,3 +195,37 @@ func save_image(image : Image, file_name : String = "export") -> void:
var png_data = Array(image.save_png_to_buffer())
JavaScript.eval("download('%s', %s, 'image/png');" % [file_name, str(png_data)], true)
func load_shader() -> void:
if OS.get_name() != "HTML5" or !OS.has_feature('JavaScript'):
return
# Execute JS function
JavaScript.eval("upload_shader();", true) # Opens prompt for choosing file
yield(self, "InFocus") # Wait until JS prompt is closed
yield(get_tree().create_timer(0.5), "timeout") # Give some time for async JS data load
if JavaScript.eval("canceled;", true): # If File Dialog closed w/o file
return
# Use data from png data
var file_data
while true:
file_data = JavaScript.eval("fileData;", true)
if file_data != null:
break
yield(get_tree().create_timer(1.0), "timeout") # Need more time to load data
# var file_type = JavaScript.eval("fileType;", true)
var file_name = JavaScript.eval("fileName;", true)
var shader = Shader.new()
shader.code = file_data
var shader_effect_dialog = Global.control.get_node("Dialogs/ImageEffects/ShaderEffect")
shader_effect_dialog.preview.material.shader = shader
shader_effect_dialog.shader_loaded_label.text = tr("Shader loaded:") + " " + file_name.get_basename()