diff --git a/addons/material_maker/engine/gen_base.gd b/addons/material_maker/engine/gen_base.gd index e665262..72a5503 100644 --- a/addons/material_maker/engine/gen_base.gd +++ b/addons/material_maker/engine/gen_base.gd @@ -110,12 +110,19 @@ func get_parameter_def(param_name : String) -> Dictionary: return {} func get_parameter(n : String): - return parameters[n] + if parameters.has(n): + return parameters[n] + else: + return get_parameter_def(n).default func set_parameter(n : String, v) -> void: parameters[n] = v source_changed(0) emit_signal("parameter_changed", n, v) + if is_inside_tree(): + var parameter_def : Dictionary = get_parameter_def(n) + if parameter_def.has("type") and parameter_def.type == "float": + get_tree().call_group("preview", "on_float_parameter_changed", "p_o%s_%s" % [ str(get_instance_id()), n ], v) func notify_output_change(output_index : int) -> void: var targets = get_targets(output_index) @@ -159,7 +166,7 @@ func get_input_shader(input_index : int) -> Dictionary: func get_shader(output_index : int, context) -> Dictionary: return get_shader_code("UV", output_index, context) -func generate_preview_shader(src_code, type) -> String: +static func generate_preview_shader(src_code, type, main_fct = "void fragment() { COLOR = preview_2d(UV); }") -> String: var code code = "shader_type canvas_item;\n" code += "render_mode blend_disabled;\n" @@ -182,6 +189,7 @@ func generate_preview_shader(src_code, type) -> String: shader_code += preview_code #print("GENERATED SHADER:\n"+shader_code) code += shader_code + code += main_fct return code func render(output_index : int, size : int, preview : bool = false) -> Object: diff --git a/addons/material_maker/engine/gen_shader.gd b/addons/material_maker/engine/gen_shader.gd index 35c866b..a93e384 100644 --- a/addons/material_maker/engine/gen_shader.gd +++ b/addons/material_maker/engine/gen_shader.gd @@ -188,7 +188,7 @@ func subst(string : String, context : MMGenContext, uv : String = "") -> Diction var value = parameters[p.name] var value_string = null if p.type == "float": - value_string = "%.9f" % value + value_string = "p_%s_%s" % [ genname, p.name ] elif p.type == "size": value_string = "%.9f" % pow(2, value) elif p.type == "enum": @@ -247,7 +247,9 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) - if !context.has_variant(self): # Generate functions for gradients for p in shader_model.parameters: - if p.type == "gradient": + if p.type == "float": + rv.defs += "uniform float p_%s_%s = %.9f;\n" % [ genname, p.name, parameters[p.name] ] + elif p.type == "gradient": var g = parameters[p.name] if !(g is MMGradient): g = MMGradient.new() diff --git a/addons/material_maker/engine/gen_switch.gd b/addons/material_maker/engine/gen_switch.gd index d17e246..2dce86d 100644 --- a/addons/material_maker/engine/gen_switch.gd +++ b/addons/material_maker/engine/gen_switch.gd @@ -39,7 +39,7 @@ func get_input_defs() -> Array: func get_output_defs() -> Array: var rv : Array = [] - for o in range(parameters.outputs): + for o in range(get_parameter("outputs")): var n = PoolByteArray([65+o]).get_string_from_ascii() rv.push_back({ name=n, type="any" }) return rv diff --git a/addons/material_maker/nodes/preview_f.shader b/addons/material_maker/nodes/preview_f.shader index fc4f1d5..5f9a087 100644 --- a/addons/material_maker/nodes/preview_f.shader +++ b/addons/material_maker/nodes/preview_f.shader @@ -1,5 +1,4 @@ -void fragment() { - vec2 uv = UV; +vec4 preview_2d(vec2 uv) { $(code) - COLOR = vec4(vec3($(value)), 1.0); + return vec4(vec3($(value)), 1.0); } diff --git a/addons/material_maker/nodes/preview_rgb.shader b/addons/material_maker/nodes/preview_rgb.shader index 416d73e..7c08ec1 100644 --- a/addons/material_maker/nodes/preview_rgb.shader +++ b/addons/material_maker/nodes/preview_rgb.shader @@ -1,5 +1,4 @@ -void fragment() { - vec2 uv = UV; +vec4 preview_2d(vec2 uv) { $(code) - COLOR = vec4($(value), 1.0); + return vec4($(value), 1.0); } diff --git a/addons/material_maker/nodes/preview_rgba.shader b/addons/material_maker/nodes/preview_rgba.shader index be33b4b..f624707 100644 --- a/addons/material_maker/nodes/preview_rgba.shader +++ b/addons/material_maker/nodes/preview_rgba.shader @@ -1,5 +1,4 @@ -void fragment() { - vec2 uv = UV; +vec4 preview_2d(vec2 uv) { $(code) - COLOR = $(value); + return $(value); } diff --git a/addons/material_maker/nodes/preview_sdf2d.shader b/addons/material_maker/nodes/preview_sdf2d.shader index 33bbb32..9a3f852 100644 --- a/addons/material_maker/nodes/preview_sdf2d.shader +++ b/addons/material_maker/nodes/preview_sdf2d.shader @@ -1,10 +1,9 @@ -void fragment() { - vec2 uv = UV; +vec4 preview_2d(vec2 uv) { $(code) float d = $(value); vec3 col = vec3(cos(d*min(256, preview_size))); col *= clamp(1.0-d*d, 0.0, 1.0); col *= vec3(1.0, vec2(step(-0.015, d))); col *= vec3(vec2(step(d, 0.015)), 1.0); - COLOR = vec4(col, 1.0); + return vec4(col, 1.0); } diff --git a/addons/material_maker/nodes/preview_sdf3d.shader b/addons/material_maker/nodes/preview_sdf3d.shader index 25d87c6..ca95ab8 100644 --- a/addons/material_maker/nodes/preview_sdf3d.shader +++ b/addons/material_maker/nodes/preview_sdf3d.shader @@ -20,8 +20,8 @@ vec3 normal(vec3 p) { return normalize(n); } -void fragment() { - vec2 uv = UV-vec2(0.5); +vec4 preview_2d(vec2 uv) { + uv -= vec2(0.5); vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0))); vec3 n = normal(p); vec3 l = vec3(5.0, 5.0, 10.0); @@ -29,5 +29,5 @@ void fragment() { float o = step(p.z, 0.001); float shadow = 1.0-0.75*step(raymarch(l, -ld), length(l-p)-0.01); float light = 0.3+0.7*dot(n, ld)*shadow; - COLOR = vec4(vec3(0.8+0.2*o, 0.8+0.2*o, 1.0)*light, 1.0); + return vec4(vec3(0.8+0.2*o, 0.8+0.2*o, 1.0)*light, 1.0); } diff --git a/addons/material_maker/nodes/preview_sdf3dc.shader b/addons/material_maker/nodes/preview_sdf3dc.shader index 7c6ebbe..246d536 100644 --- a/addons/material_maker/nodes/preview_sdf3dc.shader +++ b/addons/material_maker/nodes/preview_sdf3dc.shader @@ -31,8 +31,8 @@ vec3 rm_color(float c) { return 1.0 * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), 1.0); } -void fragment() { - vec2 uv = UV-vec2(0.5); +vec4 preview_2d(vec2 uv) { + uv -= vec2(0.5); vec2 rm = raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0)); vec3 p = vec3(uv, 2.0-rm.x); vec3 n = normal(p); @@ -41,5 +41,5 @@ void fragment() { float o = step(p.z, 0.001); float shadow = 1.0-0.75*step(raymarch(l, -ld).x, length(l-p)-0.01); float light = 0.3+0.7*dot(n, ld)*shadow; - COLOR = vec4(mix(rm_color(fract(rm.y)), vec3(0.9), o)*light, 1.0); + return vec4(mix(rm_color(fract(rm.y)), vec3(0.9), o)*light, 1.0); } diff --git a/addons/material_maker/nodes/preview_tex3d.shader b/addons/material_maker/nodes/preview_tex3d.shader index 1151e89..552e505 100644 --- a/addons/material_maker/nodes/preview_tex3d.shader +++ b/addons/material_maker/nodes/preview_tex3d.shader @@ -24,8 +24,8 @@ vec3 normal(vec3 p) { return normalize(n); } -void fragment() { - vec2 uv = UV-vec2(0.5); +vec4 preview_2d(vec2 uv) { + vec2 uv -= vec2(0.5); vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0))); vec3 n = normal(p); vec3 l = vec3(5.0, 5.0, 10.0); @@ -33,5 +33,5 @@ void fragment() { float o = step(p.z, 0.001); float shadow = 1.0-0.75*step(raymarch(l, -ld), length(l-p)-0.01); float light = 0.3+0.7*dot(n, ld)*shadow; - COLOR = vec4(calcColor(vec4(p, 0.0))*light, 1.0); + return vec4(calcColor(vec4(p, 0.0))*light, 1.0); } diff --git a/material_maker/main_window.gd b/material_maker/main_window.gd index 7700f3e..48f236a 100644 --- a/material_maker/main_window.gd +++ b/material_maker/main_window.gd @@ -583,33 +583,33 @@ func update_preview_2d(node = null) -> void: node = n break if node != null: - var result = node.generator.render(0, 1024, true) - while result is GDScriptFunctionState: - result = yield(result, "completed") - var tex = ImageTexture.new() - result.copy_to_texture(tex) - result.release() - preview_2d.set_preview_texture(tex) - preview_2d_background.set_preview_texture(tex) + preview_2d.set_generator(node.generator) + preview_2d_background.set_generator(node.generator) else: - preview_2d.set_preview_texture(null) - preview_2d_background.set_preview_texture(null) + preview_2d.set_generator(null) + preview_2d_background.set_generator(null) func update_preview_3d(previews : Array) -> void: + var visible_previews = [] + for p in previews: + if p.is_visible_in_tree(): + visible_previews.push_back(p) + if visible_previews.empty(): + return var graph_edit : MMGraphEdit = get_current_graph_edit() if graph_edit != null and graph_edit.top_generator != null and graph_edit.top_generator.has_node("Material"): var gen_material = graph_edit.top_generator.get_node("Material") var status = gen_material.render_textures() while status is GDScriptFunctionState: status = yield(status, "completed") - for p in previews: + for p in visible_previews: gen_material.update_materials(p.get_materials()) var selected_node = null func on_selected_node_change(node) -> void: if node != selected_node: selected_node = node - preview_2d.setup_controls(node.generator if node != null else null) + preview_2d.set_generator(node.generator if node != null else null) update_preview_2d(node) func _on_Projects_tab_changed(tab) -> void: diff --git a/material_maker/preview/preview_2d.gd b/material_maker/preview/preview_2d.gd index bfcd9f3..46e29a3 100644 --- a/material_maker/preview/preview_2d.gd +++ b/material_maker/preview/preview_2d.gd @@ -1,24 +1,39 @@ extends ColorRect -var generator = null +export(String, MULTILINE) var shader : String = "" -func set_preview_texture(tex: Texture) -> void: - material.set_shader_param("tex", tex) +var generator : MMGenBase = null -func on_resized() -> void: - material.set_shader_param("size", rect_size) - setup_controls(generator) - -func setup_controls(g : MMGenBase) -> void: +func set_generator(g : MMGenBase) -> void: + if generator != null and is_instance_valid(generator): + generator.disconnect("float_param_changed", self, "on_float_param_changed") + var source = { defs="", code="", textures={}, type="f", f="1.0" } if is_instance_valid(g): generator = g var param_defs : Array = generator.get_parameter_defs() for c in get_children(): c.setup_control(generator, param_defs) + generator.connect("float_param_changed", self, "on_float_param_changed") + var gen_output_defs = generator.get_output_defs() + if ! gen_output_defs.empty(): + var context : MMGenContext = MMGenContext.new() + source = generator.get_shader_code("uv", 0, context) + while source is GDScriptFunctionState: + source = yield(source, "completed") + if source.empty(): + source = { defs="", code="", textures={}, type="f", f="1.0" } else: g = null for c in get_children(): c.setup_control(generator, []) + material.shader.code = MMGenBase.generate_preview_shader(source, source.type, shader) + +func on_float_parameter_changed(n : String, v : float) -> void: + material.set_shader_param(n, v) + +func on_resized() -> void: + material.set_shader_param("size", rect_size) + set_generator(generator) func value_to_pos(value : Vector2) -> Vector2: return rect_size*0.5+value*min(rect_size.x, rect_size.y)/1.2 diff --git a/material_maker/preview/preview_2d.tscn b/material_maker/preview/preview_2d.tscn index 4bcc1f4..6fb149a 100644 --- a/material_maker/preview/preview_2d.tscn +++ b/material_maker/preview/preview_2d.tscn @@ -3,28 +3,14 @@ [ext_resource path="res://material_maker/preview/preview_2d.gd" type="Script" id=1] [sub_resource type="Shader" id=1] -code = "shader_type canvas_item; - -uniform sampler2D tex; -uniform vec2 size; - -void fragment() { - float ms = max(size.x, size.y); - vec2 uv = fract(0.5+1.2*(UV-vec2(0.5))*ms/size.yx); - float is = min(size.x, size.y)/1.2; - vec2 m2 = min(fract(uv), 1.0-fract(uv)); - vec4 image = texture(tex, uv); - vec3 image_with_background = mix(vec3(mod(floor(uv.x*32.0)+floor(uv.y*32.0), 2.0)), image.xyz, image.a); - float lines_color = 0.5*(cos(5.0*TIME+100.0*(uv.x+uv.y))+1.0); - COLOR = vec4(mix(image_with_background, vec3(lines_color), step(is*min(m2.x, m2.y), 1.0)), 1.0); -}" [sub_resource type="ShaderMaterial" id=2] resource_local_to_scene = true shader = SubResource( 1 ) -shader_param/size = Vector2( 585, 492 ) -[node name="Preview2D" type="ColorRect"] +[node name="Preview2D" type="ColorRect" groups=[ +"preview", +]] material = SubResource( 2 ) anchor_right = 1.0 anchor_bottom = 1.0 @@ -39,4 +25,16 @@ script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } +shader = "uniform vec2 size; + +void fragment() { + float ms = max(size.x, size.y); + vec2 uv = fract(0.5+1.2*(UV-vec2(0.5))*ms/size.yx); + float is = min(size.x, size.y)/1.2; + vec2 m2 = min(fract(uv), 1.0-fract(uv)); + vec4 image = preview_2d(uv); + vec3 image_with_background = mix(vec3(mod(floor(uv.x*32.0)+floor(uv.y*32.0), 2.0)), image.xyz, image.a); + float lines_color = 0.5*(cos(5.0*TIME+100.0*(uv.x+uv.y))+1.0); + COLOR = vec4(mix(image_with_background, vec3(lines_color), step(is*min(m2.x, m2.y), 1.0)), 1.0); +}" [connection signal="resized" from="." to="." method="on_resized"]