diff --git a/addons/material_maker/engine/gen_base.gd b/addons/material_maker/engine/gen_base.gd index 17793a5..fbcc96e 100644 --- a/addons/material_maker/engine/gen_base.gd +++ b/addons/material_maker/engine/gen_base.gd @@ -6,8 +6,7 @@ class_name MMGenBase Base class for texture generators, that defines their API """ -signal parameter_changed -signal output_changed(index) +signal parameter_changed(n, v) class InputPort: var generator : MMGenBase = null @@ -93,8 +92,8 @@ func init_parameters() -> void: func set_position(p) -> void: position = p - if has_randomness() and !is_seed_locked(): - source_changed(0) + if has_randomness() and !is_seed_locked() and is_inside_tree(): + get_tree().call_group("preview", "on_float_parameters_changed", { "seed_o"+str(get_instance_id()): get_seed() }) func get_type() -> String: return "generic" @@ -113,21 +112,60 @@ 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 + +class CustomGradientSorter: + static func compare(a, b) -> bool: + return a.pos < b.pos func set_parameter(n : String, v) -> void: + var old_value = parameters[n] if parameters.has(n) else null 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"): + if parameter_def.type == "float": + var parameter_name = "p_o"+str(get_instance_id())+"_"+n + get_tree().call_group("preview", "on_float_parameters_changed", { parameter_name:v }) + return + elif parameter_def.type == "color": + var parameter_changes = {} + for f in [ "r", "g", "b", "a" ]: + var parameter_name = "p_o"+str(get_instance_id())+"_"+n+"_"+f + parameter_changes[parameter_name] = v[f] + get_tree().call_group("preview", "on_float_parameters_changed", parameter_changes) + return + elif parameter_def.type == "gradient": + if v.interpolation == old_value.interpolation && v.points.size() == old_value.points.size(): + # convert from old format + for i in range(old_value.points.size()): + if old_value.points[i].has("v"): + var old = old_value.points[i] + old_value.points[i] = { pos=old.v, r=old.c.r, g=old.c.g, b=old.c.b, a=old.c.a } + old_value.points.sort_custom(CustomGradientSorter, "compare") + v.points.sort_custom(CustomGradientSorter, "compare") + var parameter_changes = {} + for i in range(old_value.points.size()): + for f in [ "pos", "r", "g", "b", "a" ]: + if v.points[i][f] != old_value.points[i][f]: + var parameter_name = "p_o%s_%s_%d_%s" % [ str(get_instance_id()), n, i, f ] + parameter_changes[parameter_name] = v.points[i][f] + get_tree().call_group("preview", "on_float_parameters_changed", parameter_changes) + return + source_changed(0) func notify_output_change(output_index : int) -> void: var targets = get_targets(output_index) for target in targets: target.generator.source_changed(target.input_index) - emit_signal("output_changed", output_index) + emit_signal("parameter_changed", "__output_changed__", output_index) -func source_changed(__) -> void: - emit_signal("parameter_changed", "__input_changed__", 0) +func source_changed(input_index : int) -> void: + emit_signal("parameter_changed", "__input_changed__", input_index) for i in range(get_output_defs().size()): notify_output_change(i) @@ -162,7 +200,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" @@ -185,6 +223,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_buffer.gd b/addons/material_maker/engine/gen_buffer.gd index 5de59ee..04750f6 100644 --- a/addons/material_maker/engine/gen_buffer.gd +++ b/addons/material_maker/engine/gen_buffer.gd @@ -7,11 +7,16 @@ Texture generator buffers, that render their input in a specific resolution and This is useful when using generators that sample their inputs several times (such as convolutions) """ -var updated : bool = false +var material : ShaderMaterial = null +var updating : bool = false +var update_again : bool = false func _ready() -> void: + material = ShaderMaterial.new() + material.shader = Shader.new() if !parameters.has("size"): parameters.size = 9 + add_to_group("preview") func get_type() -> String: return "buffer" @@ -31,24 +36,56 @@ func get_input_defs() -> Array: func get_output_defs() -> Array: return [ { type="rgba" }, { type="rgba" } ] -func source_changed(input_port_index : int) -> void: - updated = false - .source_changed(input_port_index) +func source_changed(_input_port_index : int) -> void: + call_deferred("update_shader") -func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary: - var source = get_source(0) - if source != null and !updated: - var result = source.generator.render(source.output_index, pow(2, parameters.size)) - while result is GDScriptFunctionState: - result = yield(result, "completed") - result.copy_to_texture(texture) - result.release() - texture.flags = Texture.FLAG_MIPMAPS - updated = true - var rv = ._get_shader_code_lod(uv, output_index, context, 0 if output_index == 0 else parameters.lod) - while rv is GDScriptFunctionState: - rv = yield(rv, "completed") - return rv +func update_shader() -> void: + var context : MMGenContext = MMGenContext.new() + var source = {} + var source_output = get_source(0) + if source_output != null: + source = source_output.generator.get_shader_code("uv", source_output.output_index, context) + while source is GDScriptFunctionState: + source = yield(source, "completed") + if source.empty(): + source = { defs="", code="", textures={}, rgba="vec4(0.0)" } + material.shader.code = mm_renderer.generate_shader(source) + if source.has("textures"): + for k in source.textures.keys(): + material.set_shader_param(k, source.textures[k]) + update_buffer() + +func on_float_parameters_changed(parameter_changes : Dictionary) -> void: + var do_update : bool = false + for n in parameter_changes.keys(): + for p in VisualServer.shader_get_param_list(material.shader.get_rid()): + if p.name == n: + material.set_shader_param(n, parameter_changes[n]) + do_update = true + break + if do_update: + update_buffer() + +func on_texture_changed(n : String) -> void: + for p in VisualServer.shader_get_param_list(material.shader.get_rid()): + if p.name == n: + update_buffer() + return + +func update_buffer() -> void: + update_again = true + if !updating: + updating = true + while update_again: + update_again = false + var result = mm_renderer.render_material(material, pow(2, get_parameter("size"))) + while result is GDScriptFunctionState: + result = yield(result, "completed") + if !update_again: + result.copy_to_texture(texture) + result.release() + updating = false + get_tree().call_group("preview", "on_texture_changed", "o%s_tex" % str(get_instance_id())) func _serialize(data: Dictionary) -> Dictionary: data.type = "buffer" diff --git a/addons/material_maker/engine/gen_material.gd b/addons/material_maker/engine/gen_material.gd index 58f9c6a..7d57fd0 100644 --- a/addons/material_maker/engine/gen_material.gd +++ b/addons/material_maker/engine/gen_material.gd @@ -5,7 +5,12 @@ class_name MMGenMaterial var export_paths = {} var material : SpatialMaterial +var shader_materials = {} +var need_update = {} +var need_render = {} var generated_textures = {} +var updating : bool = false +var update_again : bool = false const TEXTURE_LIST = [ { port=0, texture="albedo", sources=[0] }, @@ -38,7 +43,12 @@ const TEXTURE_SIZE_DEFAULT = 10 # 1024x1024 func _ready() -> void: for t in TEXTURE_LIST: generated_textures[t.texture] = null + need_update[t.texture] = true + need_render[t.texture] = true + shader_materials[t.texture] = ShaderMaterial.new() + shader_materials[t.texture].shader = Shader.new() material = SpatialMaterial.new() + add_to_group("preview") func can_be_deleted() -> bool: return false @@ -74,34 +84,86 @@ func set_parameter(p, v) -> void: func source_changed(input_index : int) -> void: for t in TEXTURE_LIST: if t.has("sources") and t.sources.find(input_index) != -1: - generated_textures[t.texture] = null + need_update[t.texture] = true update_preview() func render_textures() -> void: for t in TEXTURE_LIST: - var texture = null var result if t.has("port"): - if generated_textures[t.texture] != null: + if !need_update[t.texture]: continue - result = render(t.port, get_image_size()) + var context : MMGenContext = MMGenContext.new() + var source = get_shader_code("uv", t.port, context) + while source is GDScriptFunctionState: + source = yield(source, "completed") + if source.empty(): + source = { defs="", code="", textures={}, rgba="vec4(0.0)" } + shader_materials[t.texture].shader.code = mm_renderer.generate_shader(source) + if source.has("textures"): + for k in source.textures.keys(): + shader_materials[t.texture].set_shader_param(k, source.textures[k]) + result = mm_renderer.render_material(shader_materials[t.texture], get_image_size(), false) else: generated_textures[t.texture] = null + need_update[t.texture] = false continue while result is GDScriptFunctionState: result = yield(result, "completed") - texture = ImageTexture.new() + if generated_textures[t.texture] == null: + generated_textures[t.texture] = ImageTexture.new() + var texture = generated_textures[t.texture] result.copy_to_texture(texture) result.release() # To work, this must be set after calling `copy_to_texture()` texture.flags |= ImageTexture.FLAG_ANISOTROPIC_FILTER - # Disable filtering for small textures, as they're considered to be used # for a pixel art style if texture.get_size().x <= 128: texture.flags ^= ImageTexture.FLAG_FILTER + need_update[t.texture] = false - generated_textures[t.texture] = texture +func on_float_parameters_changed(parameter_changes : Dictionary) -> void: + var do_update : bool = false + for t in TEXTURE_LIST: + if generated_textures[t.texture] != null: + for n in parameter_changes.keys(): + for p in VisualServer.shader_get_param_list(shader_materials[t.texture].shader.get_rid()): + if p.name == n: + shader_materials[t.texture].set_shader_param(n, parameter_changes[n]) + need_render[t.texture] = true + do_update = true + break + if do_update: + update_textures() + +func on_texture_changed(n : String) -> void: + var do_update : bool = false + for t in TEXTURE_LIST: + if generated_textures[t.texture] != null: + for p in VisualServer.shader_get_param_list(shader_materials[t.texture].shader.get_rid()): + if p.name == n: + need_render[t.texture] = true + do_update = true + break + if do_update: + update_textures() + +func update_textures() -> void: + update_again = true + if !updating: + var image_size = get_image_size() + updating = true + while update_again: + update_again = false + for t in TEXTURE_LIST: + if need_render[t.texture]: + var result = mm_renderer.render_material(shader_materials[t.texture], image_size, false) + while result is GDScriptFunctionState: + result = yield(result, "completed") + result.copy_to_texture(generated_textures[t.texture]) + result.release() + updating = false func update_materials(material_list) -> void: render_textures() diff --git a/addons/material_maker/engine/gen_shader.gd b/addons/material_maker/engine/gen_shader.gd index 35c866b..6728964 100644 --- a/addons/material_maker/engine/gen_shader.gd +++ b/addons/material_maker/engine/gen_shader.gd @@ -18,9 +18,11 @@ func toggle_editable() -> bool: func is_editable() -> bool: return editable + func has_randomness() -> bool: return uses_seed + func get_type() -> String: return "shader" @@ -70,6 +72,7 @@ func set_shader_model(data: Dictionary) -> void: if shader_model.has("instance"): if shader_model.instance.find("$seed") != -1 or shader_model.instance.find("$(seed)") != -1: uses_seed = true + source_changed(0) func find_keyword_call(string, keyword): var search_string = "$%s(" % keyword @@ -178,7 +181,7 @@ func subst(string : String, context : MMGenContext, uv : String = "") -> Diction if uv != "": var genname_uv = genname+"_"+str(context.get_variant(self, uv)) string = replace_variable(string, "name_uv", genname_uv) - var tmp_string = replace_variable(string, "seed", str(get_seed())) + var tmp_string = replace_variable(string, "seed", "seed_"+genname) if tmp_string != string: string = tmp_string if shader_model.has("parameters") and typeof(shader_model.parameters) == TYPE_ARRAY: @@ -188,7 +191,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": @@ -196,9 +199,9 @@ func subst(string : String, context : MMGenContext, uv : String = "") -> Diction value = 0 value_string = p.values[value].value elif p.type == "color": - value_string = "vec4(%.9f, %.9f, %.9f, %.9f)" % [ value.r, value.g, value.b, value.a ] + value_string = "vec4(p_%s_%s_r, p_%s_%s_g, p_%s_%s_b, p_%s_%s_a)" % [ genname, p.name, genname, p.name, genname, p.name, genname, p.name ] elif p.type == "gradient": - value_string = genname+"_p_"+p.name+"_gradient_fct" + value_string = genname+"_"+p.name+"_gradient_fct" elif p.type == "boolean": value_string = "true" if value else "false" else: @@ -246,13 +249,25 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) - var output = shader_model.outputs[output_index] if !context.has_variant(self): # Generate functions for gradients + if has_randomness(): + rv.defs += "uniform int seed_%s = %d;\n" % [ genname, get_seed() ] 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 == "color": + rv.defs += "uniform float p_%s_%s_r = %.9f;\n" % [ genname, p.name, parameters[p.name].r ] + rv.defs += "uniform float p_%s_%s_g = %.9f;\n" % [ genname, p.name, parameters[p.name].g ] + rv.defs += "uniform float p_%s_%s_b = %.9f;\n" % [ genname, p.name, parameters[p.name].b ] + rv.defs += "uniform float p_%s_%s_a = %.9f;\n" % [ genname, p.name, parameters[p.name].a ] + elif p.type == "gradient": var g = parameters[p.name] if !(g is MMGradient): g = MMGradient.new() g.deserialize(parameters[p.name]) - rv.defs += g.get_shader(genname+"_p_"+p.name+"_gradient_fct") + var params = g.get_shader_params(genname+"_"+p.name) + for sp in params.keys(): + rv.defs += "uniform float "+sp+" = "+str(params[sp])+";\n" + rv.defs += g.get_shader(genname+"_"+p.name) # Generate functions for inputs if shader_model.has("inputs"): for i in range(shader_model.inputs.size()): diff --git a/addons/material_maker/engine/gen_switch.gd b/addons/material_maker/engine/gen_switch.gd index d17e246..f680ca5 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 @@ -73,6 +73,9 @@ func set_parameter(p, v) -> void: parent.reconnect_outputs(self, outputs_changes) .set_parameter(p, v) emit_signal("parameter_changed", "__update_all__", null) + if p == "source": + for i in range(int(parameters.outputs)): + notify_output_change(i) # get the list of outputs that depend on the input whose index is passed as parameter func follow_input(input_index : int) -> Array: @@ -89,7 +92,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) - while rv is GDScriptFunctionState: rv = yield(rv, "completed") return rv - return { globals=[], defs="", code="", textures={} } + return { globals=[], defs="", code="", textures={}, type="f", f="0.0" } func _serialize(data: Dictionary) -> Dictionary: return data diff --git a/addons/material_maker/engine/renderer.gd b/addons/material_maker/engine/renderer.gd index 70c2980..7676244 100644 --- a/addons/material_maker/engine/renderer.gd +++ b/addons/material_maker/engine/renderer.gd @@ -5,19 +5,24 @@ class_name MMGenRenderer export(String) var debug_path = "" var debug_file_index : int = 0 +var common_shader : String + var rendering : bool = false + signal done + func _ready() -> void: $ColorRect.material = $ColorRect.material.duplicate(true) + var file = File.new() + file.open("res://addons/material_maker/common.shader", File.READ) + common_shader = file.get_as_text() -static func generate_shader(src_code) -> String: +func generate_shader(src_code) -> String: var code code = "shader_type canvas_item;\n" code += "render_mode blend_disabled;\n" - var file = File.new() - file.open("res://addons/material_maker/common.shader", File.READ) - code += file.get_as_text() + code += common_shader code += "\n" if src_code.has("textures"): for t in src_code.textures.keys(): @@ -38,52 +43,28 @@ static func generate_shader(src_code) -> String: code += shader_code return code -static func generate_combined_shader(red_code, green_code, blue_code) -> String: - var code - code = "shader_type canvas_item;\n" - code += "render_mode blend_disabled;\n" - var file = File.new() - file.open("res://addons/material_maker/common.shader", File.READ) - code += file.get_as_text() - code += "\n" - var globals = [] - var textures = {} - var output = [] - for c in [ red_code, green_code, blue_code ]: - if c.has("textures"): - for t in c.textures.keys(): - textures[t] = c.textures[t] - if c.has("globals"): - for g in c.globals: - if globals.find(g) == -1: - globals.push_back(g) - if c.has("f"): - output.push_back(c.f) - else: - output.push_back("1.0") - for t in textures.keys(): - code += "uniform sampler2D "+t+";\n" - for g in globals: - code += g - var shader_code = "" - shader_code += red_code.defs - shader_code += green_code.defs - shader_code += blue_code.defs - shader_code += "void fragment() {\n" - shader_code += red_code.code - shader_code += green_code.code - shader_code += blue_code.code - shader_code += "COLOR = vec4("+output[0]+", "+output[1]+", "+output[2]+", 1.0);\n" - shader_code += "}\n" - #print("GENERATED COMBINED SHADER:\n"+shader_code) - code += shader_code - return code - func setup_material(shader_material, textures, shader_code) -> void: for k in textures.keys(): shader_material.set_shader_param(k+"_tex", textures[k]) shader_material.shader.code = shader_code +func render_material(material, render_size, with_hdr = true) -> Object: + while rendering: + yield(self, "done") + rendering = true + var shader_material = $ColorRect.material + size = Vector2(render_size, render_size) + $ColorRect.rect_position = Vector2(0, 0) + $ColorRect.rect_size = size + $ColorRect.material = material + hdr = with_hdr + render_target_update_mode = Viewport.UPDATE_ONCE + update_worlds() + yield(get_tree(), "idle_frame") + yield(get_tree(), "idle_frame") + $ColorRect.material = shader_material + return self + func render_shader(shader, textures, render_size) -> Object: if debug_path != null and debug_path != "": var file_name = debug_path+str(debug_file_index)+".shader" @@ -126,4 +107,5 @@ func save_to_file(fn : String) -> void: func release() -> void: rendering = false + hdr = false emit_signal("done") diff --git a/addons/material_maker/engine/renderer.tscn b/addons/material_maker/engine/renderer.tscn index e87b3b7..d3c1f22 100644 --- a/addons/material_maker/engine/renderer.tscn +++ b/addons/material_maker/engine/renderer.tscn @@ -18,7 +18,6 @@ own_world = true transparent_bg = true hdr = false keep_3d_linear = true -usage = 0 render_target_v_flip = true render_target_update_mode = 1 gui_disable_input = true diff --git a/addons/material_maker/nodes/beehive.mmg b/addons/material_maker/nodes/beehive.mmg index 15f901f..9e9ca63 100644 --- a/addons/material_maker/nodes/beehive.mmg +++ b/addons/material_maker/nodes/beehive.mmg @@ -22,7 +22,7 @@ "type": "f" }, { - "rgb": "rand3(fract($(name_uv)_center.zw/vec2($sx, $sy))+vec2($seed))", + "rgb": "rand3(fract($(name_uv)_center.zw/vec2($sx, $sy))+vec2(float($seed)))", "type": "rgb" }, { diff --git a/addons/material_maker/nodes/bricks.mmg b/addons/material_maker/nodes/bricks.mmg index aba14ac..cc365bb 100644 --- a/addons/material_maker/nodes/bricks.mmg +++ b/addons/material_maker/nodes/bricks.mmg @@ -29,7 +29,7 @@ "type": "f" }, { - "rgb": "rand3(fract($(name_uv)_rect.xy)+rand2(vec2($seed)))", + "rgb": "rand3(fract($(name_uv)_rect.xy)+rand2(vec2(float($seed))))", "type": "rgb" }, { diff --git a/addons/material_maker/nodes/fbm.mmg b/addons/material_maker/nodes/fbm.mmg index c414cbe..cffeeb0 100644 --- a/addons/material_maker/nodes/fbm.mmg +++ b/addons/material_maker/nodes/fbm.mmg @@ -13,7 +13,7 @@ }, "shader_model": { "code": "", - "global": "float fbm_value(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat p00 = rand(mod(o, size));\n\tfloat p01 = rand(mod(o + vec2(0.0, 1.0), size));\n\tfloat p10 = rand(mod(o + vec2(1.0, 0.0), size));\n\tfloat p11 = rand(mod(o + vec2(1.0, 1.0), size));\n\tvec2 t = f * f * (3.0 - 2.0 * f);\n\treturn mix(mix(p00, p10, t.x), mix(p01, p11, t.x), t.y);\n}\n\nfloat fbm_perlin(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat a00 = rand(mod(o, size)) * 6.28318530718;\n\tfloat a01 = rand(mod(o + vec2(0.0, 1.0), size)) * 6.28318530718;\n\tfloat a10 = rand(mod(o + vec2(1.0, 0.0), size)) * 6.28318530718;\n\tfloat a11 = rand(mod(o + vec2(1.0, 1.0), size)) * 6.28318530718;\n\tvec2 v00 = vec2(cos(a00), sin(a00));\n\tvec2 v01 = vec2(cos(a01), sin(a01));\n\tvec2 v10 = vec2(cos(a10), sin(a10));\n\tvec2 v11 = vec2(cos(a11), sin(a11));\n\tfloat p00 = dot(v00, f);\n\tfloat p01 = dot(v01, f - vec2(0.0, 1.0));\n\tfloat p10 = dot(v10, f - vec2(1.0, 0.0));\n\tfloat p11 = dot(v11, f - vec2(1.0, 1.0));\n\tvec2 t = f * f * (3.0 - 2.0 * f);\n\treturn 0.5 + mix(mix(p00, p10, t.x), mix(p01, p11, t.x), t.y);\n}\n\nfloat fbm_cellular(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat min_dist = 2.0;\n\tfor(float x = -1.0; x <= 1.0; x++) {\n\t\tfor(float y = -1.0; y <= 1.0; y++) {\n\t\t\tvec2 node = rand2(mod(o + vec2(x, y), size)) + vec2(x, y);\n\t\t\tfloat dist = sqrt((f - node).x * (f - node).x + (f - node).y * (f - node).y);\n\t\t\tmin_dist = min(min_dist, dist);\n\t\t}\n\t}\n\treturn min_dist;\n}\n", + "global": "float fbm_value(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat p00 = rand(mod(o, size));\n\tfloat p01 = rand(mod(o + vec2(0.0, 1.0), size));\n\tfloat p10 = rand(mod(o + vec2(1.0, 0.0), size));\n\tfloat p11 = rand(mod(o + vec2(1.0, 1.0), size));\n\tvec2 t = f * f * (3.0 - 2.0 * f);\n\treturn mix(mix(p00, p10, t.x), mix(p01, p11, t.x), t.y);\n}\n\nfloat fbm_perlin(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat a00 = rand(mod(o, size)) * 6.28318530718;\n\tfloat a01 = rand(mod(o + vec2(0.0, 1.0), size)) * 6.28318530718;\n\tfloat a10 = rand(mod(o + vec2(1.0, 0.0), size)) * 6.28318530718;\n\tfloat a11 = rand(mod(o + vec2(1.0, 1.0), size)) * 6.28318530718;\n\tvec2 v00 = vec2(cos(a00), sin(a00));\n\tvec2 v01 = vec2(cos(a01), sin(a01));\n\tvec2 v10 = vec2(cos(a10), sin(a10));\n\tvec2 v11 = vec2(cos(a11), sin(a11));\n\tfloat p00 = dot(v00, f);\n\tfloat p01 = dot(v01, f - vec2(0.0, 1.0));\n\tfloat p10 = dot(v10, f - vec2(1.0, 0.0));\n\tfloat p11 = dot(v11, f - vec2(1.0, 1.0));\n\tvec2 t = f * f * (3.0 - 2.0 * f);\n\treturn 0.5 + mix(mix(p00, p10, t.x), mix(p01, p11, t.x), t.y);\n}\n\nfloat fbm_cellular(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat min_dist = 2.0;\n\tfor(float x = -1.0; x <= 1.0; x++) {\n\t\tfor(float y = -1.0; y <= 1.0; y++) {\n\t\t\tvec2 node = rand2(mod(o + vec2(x, y), size)) + vec2(x, y);\n\t\t\tfloat dist = sqrt((f - node).x * (f - node).x + (f - node).y * (f - node).y);\n\t\t\tmin_dist = min(min_dist, dist);\n\t\t}\n\t}\n\treturn min_dist;\n}\n\nfloat fbm_cellular2(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat min_dist1 = 2.0;\n\tfloat min_dist2 = 2.0;\n\tfor(float x = -1.0; x <= 1.0; x++) {\n\t\tfor(float y = -1.0; y <= 1.0; y++) {\n\t\t\tvec2 node = rand2(mod(o + vec2(x, y), size)) + vec2(x, y);\n\t\t\tfloat dist = sqrt((f - node).x * (f - node).x + (f - node).y * (f - node).y);\n\t\t\tif (min_dist1 > dist) {\n\t\t\t\tmin_dist2 = min_dist1;\n\t\t\t\tmin_dist1 = dist;\n\t\t\t} else if (min_dist2 > dist) {\n\t\t\t\tmin_dist2 = dist;\n\t\t\t}\n\t\t}\n\t}\n\treturn min_dist2-min_dist1;\n}\n\nfloat fbm_cellular3(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat min_dist = 2.0;\n\tfor(float x = -1.0; x <= 1.0; x++) {\n\t\tfor(float y = -1.0; y <= 1.0; y++) {\n\t\t\tvec2 node = rand2(mod(o + vec2(x, y), size))*0.5 + vec2(x, y);\n\t\t\tfloat dist = abs((f - node).x) + abs((f - node).y);\n\t\t\tmin_dist = min(min_dist, dist);\n\t\t}\n\t}\n\treturn min_dist;\n}\n\nfloat fbm_cellular4(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat min_dist1 = 2.0;\n\tfloat min_dist2 = 2.0;\n\tfor(float x = -1.0; x <= 1.0; x++) {\n\t\tfor(float y = -1.0; y <= 1.0; y++) {\n\t\t\tvec2 node = rand2(mod(o + vec2(x, y), size))*0.5 + vec2(x, y);\n\t\t\tfloat dist = abs((f - node).x) + abs((f - node).y);\n\t\t\tif (min_dist1 > dist) {\n\t\t\t\tmin_dist2 = min_dist1;\n\t\t\t\tmin_dist1 = dist;\n\t\t\t} else if (min_dist2 > dist) {\n\t\t\t\tmin_dist2 = dist;\n\t\t\t}\n\t\t}\n\t}\n\treturn min_dist2-min_dist1;\n}\n\nfloat fbm_cellular5(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat min_dist = 2.0;\n\tfor(float x = -1.0; x <= 1.0; x++) {\n\t\tfor(float y = -1.0; y <= 1.0; y++) {\n\t\t\tvec2 node = rand2(mod(o + vec2(x, y), size)) + vec2(x, y);\n\t\t\tfloat dist = max(abs((f - node).x), abs((f - node).y));\n\t\t\tmin_dist = min(min_dist, dist);\n\t\t}\n\t}\n\treturn min_dist;\n}\n\nfloat fbm_cellular6(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat min_dist1 = 2.0;\n\tfloat min_dist2 = 2.0;\n\tfor(float x = -1.0; x <= 1.0; x++) {\n\t\tfor(float y = -1.0; y <= 1.0; y++) {\n\t\t\tvec2 node = rand2(mod(o + vec2(x, y), size)) + vec2(x, y);\n\t\t\tfloat dist = max(abs((f - node).x), abs((f - node).y));\n\t\t\tif (min_dist1 > dist) {\n\t\t\t\tmin_dist2 = min_dist1;\n\t\t\t\tmin_dist1 = dist;\n\t\t\t} else if (min_dist2 > dist) {\n\t\t\t\tmin_dist2 = dist;\n\t\t\t}\n\t\t}\n\t}\n\treturn min_dist2-min_dist1;\n}\n", "inputs": [ ], @@ -21,13 +21,13 @@ "name": "FBM", "outputs": [ { - "f": "$(name)_fbm($(uv), vec2($(scale_x), $(scale_y)), int($(iterations)), $(persistence), $(seed))", + "f": "$(name)_fbm($(uv), vec2($(scale_x), $(scale_y)), int($(iterations)), $(persistence), float($(seed)))", "type": "f" } ], "parameters": [ { - "default": 2, + "default": 7, "label": "Noise", "name": "noise", "type": "enum", @@ -43,6 +43,26 @@ { "name": "Cellular", "value": "cellular" + }, + { + "name": "Cellular2", + "value": "cellular2" + }, + { + "name": "Cellular3", + "value": "cellular3" + }, + { + "name": "Cellular4", + "value": "cellular4" + }, + { + "name": "Cellular5", + "value": "cellular5" + }, + { + "name": "Cellular6", + "value": "cellular6" } ] }, 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..67e8504 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) { + 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/addons/material_maker/nodes/scratches.mmg b/addons/material_maker/nodes/scratches.mmg index 643526a..ac80c26 100644 --- a/addons/material_maker/nodes/scratches.mmg +++ b/addons/material_maker/nodes/scratches.mmg @@ -5,7 +5,6 @@ "y": 0 }, "parameters": { - "Randomness": 0.5, "angle": -1, "layers": 5, "length": 0.25, @@ -23,12 +22,13 @@ "name": "Scratches", "outputs": [ { - "f": "scratches($uv, int($layers), vec2($length, $width), $waviness, $angle, $randomness, vec2($seed, 0.0))", + "f": "scratches($uv, int($layers), vec2($length, $width), $waviness, $angle, $randomness, vec2(float($seed), 0.0))", "type": "f" } ], "parameters": [ { + "control": "None", "default": 0.25, "label": "Length", "max": 1, @@ -38,6 +38,7 @@ "type": "float" }, { + "control": "None", "default": 0.5, "label": "Width", "max": 1, @@ -47,6 +48,7 @@ "type": "float" }, { + "control": "None", "default": 4, "label": "Layers", "max": 10, @@ -56,6 +58,7 @@ "type": "float" }, { + "control": "None", "default": 0.5, "label": "Waviness", "max": 1, @@ -65,6 +68,7 @@ "type": "float" }, { + "control": "None", "default": 0, "label": "Angle", "max": 180, @@ -74,6 +78,7 @@ "type": "float" }, { + "control": "None", "default": 0.5, "label": "Randomness", "max": 1, diff --git a/addons/material_maker/nodes/sdf3d_repeat.mmg b/addons/material_maker/nodes/sdf3d_repeat.mmg index de3daed..a4fb6b0 100644 --- a/addons/material_maker/nodes/sdf3d_repeat.mmg +++ b/addons/material_maker/nodes/sdf3d_repeat.mmg @@ -5,14 +5,9 @@ "y": 0 }, "parameters": { - "a": 0, "r": 0.3, "rx": 3, - "ry": 3, - "s": 0.3, - "x": 0.35, - "y": 0, - "z": 0 + "ry": 3 }, "shader_model": { "code": "", @@ -29,7 +24,7 @@ "name": "Repeat", "outputs": [ { - "sdf3dc": "$in(repeat($uv, vec3(1.0/$rx, 1.0/$ry, 0.0), $seed, $r))", + "sdf3dc": "$in(repeat($uv, vec3(1.0/$rx, 1.0/$ry, 0.0), float($seed), $r))", "type": "sdf3dc" } ], diff --git a/addons/material_maker/nodes/splatter.mmg b/addons/material_maker/nodes/splatter.mmg index 921f71c..1362b70 100644 --- a/addons/material_maker/nodes/splatter.mmg +++ b/addons/material_maker/nodes/splatter.mmg @@ -33,7 +33,7 @@ "name": "Splatter", "outputs": [ { - "f": "splatter_$(name)($uv, int($count), vec2($seed))", + "f": "splatter_$(name)($uv, int($count), vec2(float($seed)))", "type": "f" } ], diff --git a/addons/material_maker/nodes/splatter_color.mmg b/addons/material_maker/nodes/splatter_color.mmg index 4158172..32ae9d7 100644 --- a/addons/material_maker/nodes/splatter_color.mmg +++ b/addons/material_maker/nodes/splatter_color.mmg @@ -33,7 +33,7 @@ "name": "Color Splatter", "outputs": [ { - "rgba": "splatter_$(name)($uv, int($count), vec2($seed))", + "rgba": "splatter_$(name)($uv, int($count), vec2(float($seed)))", "type": "rgba" } ], diff --git a/addons/material_maker/nodes/tex3d_fbm.mmg b/addons/material_maker/nodes/tex3d_fbm.mmg index b11471d..5df582f 100644 --- a/addons/material_maker/nodes/tex3d_fbm.mmg +++ b/addons/material_maker/nodes/tex3d_fbm.mmg @@ -22,7 +22,7 @@ "name": "TEX3D FBM", "outputs": [ { - "tex3d": "vec3($(name)_fbm($(uv).xyz, vec3($(scale_x), $(scale_y), $(scale_z)), int($(iterations)), $(persistence), $(seed)))", + "tex3d": "vec3($(name)_fbm($(uv).xyz, vec3($(scale_x), $(scale_y), $(scale_z)), int($(iterations)), $(persistence), float($(seed))))", "type": "tex3d" } ], diff --git a/addons/material_maker/nodes/tex3d_pattern.mmg b/addons/material_maker/nodes/tex3d_pattern.mmg index 9fcfc74..fca7b9c 100644 --- a/addons/material_maker/nodes/tex3d_pattern.mmg +++ b/addons/material_maker/nodes/tex3d_pattern.mmg @@ -15,7 +15,7 @@ }, "shader_model": { "code": "", - "global": "float wave3d_constant(float x) {\n\treturn 1.0;\n}\n\nfloat wave3d_sine(float x) {\n\treturn 0.5-0.5*cos(3.14159265359*2.0*x);\n}\n\nfloat wave3d_triangle(float x) {\n\tx = fract(x);\n\treturn min(2.0*x, 2.0-2.0*x);\n}\n\nfloat wave3d_sawtooth(float x) {\n\treturn fract(x);\n}\n\nfloat wave3d_square(float x) {\n\treturn (fract(x) < 0.5) ? 0.0 : 1.0;\n}\n\nfloat wave3d_bounce(float x) {\n\tx = 2.0*(fract(x)-0.5);\n\treturn sqrt(1.0-x*x);\n}\n\nfloat mix3d_mul(float x, float y, float z) {\n\treturn x*y*z;\n}\n\nfloat mix3d_add(float x, float y, float z) {\n\treturn min(x+y+z, 1.0);\n}\n\nfloat mix3d_max(float x, float y, float z) {\n\treturn max(max(x, y), z);\n}\n\nfloat mix_min(float x, float y, float z) {\n\treturn min(min(x, y), z);\n}\n\nfloat mix3d_xor(float x, float y, float z) {\n\tfloat xy = min(x+y, 2.0-x-y);\n\treturn min(xy+z, 2.0-xy-z);\n}\n\nfloat mix3d_pow(float x, float y, float z) {\n\treturn pow(pow(x, y), z);\n}", + "global": "float wave3d_constant(float x) {\n\treturn 1.0;\n}\n\nfloat wave3d_sine(float x) {\n\treturn 0.5-0.5*cos(3.14159265359*2.0*x);\n}\n\nfloat wave3d_triangle(float x) {\n\tx = fract(x);\n\treturn min(2.0*x, 2.0-2.0*x);\n}\n\nfloat wave3d_sawtooth(float x) {\n\treturn fract(x);\n}\n\nfloat wave3d_square(float x) {\n\treturn (fract(x) < 0.5) ? 0.0 : 1.0;\n}\n\nfloat wave3d_bounce(float x) {\n\tx = 2.0*(fract(x)-0.5);\n\treturn sqrt(1.0-x*x);\n}\n\nfloat mix3d_mul(float x, float y, float z) {\n\treturn x*y*z;\n}\n\nfloat mix3d_add(float x, float y, float z) {\n\treturn min(x+y+z, 1.0);\n}\n\nfloat mix3d_max(float x, float y, float z) {\n\treturn max(max(x, y), z);\n}\n\nfloat mix3d_min(float x, float y, float z) {\n\treturn min(min(x, y), z);\n}\n\nfloat mix3d_xor(float x, float y, float z) {\n\tfloat xy = min(x+y, 2.0-x-y);\n\treturn min(xy+z, 2.0-xy-z);\n}\n\nfloat mix3d_pow(float x, float y, float z) {\n\treturn pow(pow(x, y), z);\n}", "inputs": [ ], diff --git a/addons/material_maker/nodes/tiler.mmg b/addons/material_maker/nodes/tiler.mmg index 7469b84..672c963 100644 --- a/addons/material_maker/nodes/tiler.mmg +++ b/addons/material_maker/nodes/tiler.mmg @@ -36,7 +36,7 @@ "name": "Tiler", "outputs": [ { - "f": "tiler_$(name)($uv, vec2($tx, $ty), int($overlap), vec2($seed))", + "f": "tiler_$(name)($uv, vec2($tx, $ty), int($overlap), vec2(float($seed)))", "type": "f" } ], diff --git a/addons/material_maker/nodes/tiler_color.mmg b/addons/material_maker/nodes/tiler_color.mmg index ecc07d9..3164a1c 100644 --- a/addons/material_maker/nodes/tiler_color.mmg +++ b/addons/material_maker/nodes/tiler_color.mmg @@ -36,7 +36,7 @@ "name": "Color Tiler", "outputs": [ { - "rgba": "tiler_$(name)($uv, vec2($tx, $ty), int($overlap), vec2($seed))", + "rgba": "tiler_$(name)($uv, vec2($tx, $ty), int($overlap), vec2(float($seed)))", "type": "rgba" } ], diff --git a/addons/material_maker/types/gradient.gd b/addons/material_maker/types/gradient.gd index b5e0832..97892fe 100644 --- a/addons/material_maker/types/gradient.gd +++ b/addons/material_maker/types/gradient.gd @@ -33,6 +33,9 @@ func add_point(v, c) -> void: func sort() -> void: if !sorted: points.sort_custom(CustomSorter, "compare") + for i in range(points.size()-1): + if points[i].v+0.0000005 >= points[i+1].v: + points[i+1].v = points[i].v+0.000001 sorted = true func get_color(x) -> Color: @@ -52,69 +55,81 @@ func get_color(x) -> Color: else: return Color(0.0, 0.0, 0.0, 1.0) +func get_shader_params(name) -> Dictionary: + sort() + var rv = {} + for i in range(points.size()): + rv["p_"+name+"_"+str(i)+"_pos"] = points[i].v + rv["p_"+name+"_"+str(i)+"_r"] = points[i].c.r + rv["p_"+name+"_"+str(i)+"_g"] = points[i].c.g + rv["p_"+name+"_"+str(i)+"_b"] = points[i].c.b + rv["p_"+name+"_"+str(i)+"_a"] = points[i].c.a + return rv + # get_color_in_shader func gcis(color) -> String: return "vec4(%.9f,%.9f,%.9f,%.9f)" % [color.r, color.g, color.b, color.a] +func pv(name : String, i : int) -> String: + return "p_"+name+"_"+str(i)+"_pos" + +func pc(name : String, i : int) -> String: + return "vec4(p_"+name+"_"+str(i)+"_r,p_"+name+"_"+str(i)+"_g,p_"+name+"_"+str(i)+"_b,p_"+name+"_"+str(i)+"_a)" + func get_shader(name) -> String: sort() var shader - shader = "vec4 "+name+"(float x) {\n" + shader = "vec4 "+name+"_gradient_fct(float x) {\n" match interpolation: 0: if points.size() > 0: - shader += " if (x < %.9f) {\n" % (0.5*(points[0].v + points[1].v)) - shader += " return "+gcis(points[0].c)+";\n" + shader += " if (x < 0.5*(%s+%s)) {\n" % [ pv(name, 0), pv(name, 1) ] + shader += " return "+pc(name, 0)+";\n" var s = points.size()-1 - for i in range(s): - if points[i+1].v-points[i].v > 0: - shader += " } else if (x < %.9f) {\n" % (0.5*(points[i].v + points[i+1].v)) - shader += " return "+gcis(points[i].c)+";\n" + for i in range(1, s): + shader += " } else if (x < 0.5*(%s+%s)) {\n" % [ pv(name, i), pv(name, i+1) ] + shader += " return "+pc(name, i)+";\n" shader += " }\n" - shader += " return "+gcis(points[s].c)+";\n" + shader += " return "+pc(name, s)+";\n" else: shader += " return vec4(0.0, 0.0, 0.0, 1.0);\n" 1, 2: if points.size() > 0: - shader += " if (x < %.9f) {\n" % points[0].v - shader += " return "+gcis(points[0].c)+";\n" + shader += " if (x < %s) {\n" % pv(name, 0) + shader += " return "+pc(name, 0)+";\n" var s = points.size()-1 for i in range(s): - var p1mp0 = points[i+1].v-points[i].v - if p1mp0 > 0: - shader += " } else if (x < %.9f) {\n" % points[i+1].v - var function = "(" if interpolation == 1 else "0.5-0.5*cos(3.14159265359*" - shader += " return mix(%s, %s, %s(x-%.9f)/%.9f));\n" % [ gcis(points[i].c), gcis(points[i+1].c), function, points[i].v, p1mp0 ] + shader += " } else if (x < %s) {\n" % pv(name, i+1) + var function = "(" if interpolation == 1 else "0.5-0.5*cos(3.14159265359*" + shader += " return mix(%s, %s, %s(x-%s)/(%s-%s)));\n" % [ pc(name, i), pc(name, i+1), function, pv(name, i), pv(name, i+1), pv(name, i) ] shader += " }\n" - shader += " return "+gcis(points[s].c)+";\n" + shader += " return "+pc(name, s)+";\n" else: shader += " return vec4(0.0, 0.0, 0.0, 1.0);\n" 3: if points.size() > 0: - shader += " if (x < %.9f) {\n" % points[0].v - shader += " return "+gcis(points[0].c)+";\n" + shader += " if (x < %s) {\n" % pv(name, 0) + shader += " return "+pc(name, 0)+";\n" var s = points.size()-1 for i in range(s): - var p1mp0 = points[i+1].v-points[i].v - if p1mp0 > 0: - shader += " } else if (x < %.9f) {\n" % points[i+1].v - var dx : String = "(x-%.9f)/%.9f" % [ points[i].v, p1mp0 ] - var b : String = "mix(%s, %s, %s)" % [ gcis(points[i].c), gcis(points[i+1].c), dx ] - if i > 0 and points[i-1].v < points[i].v: - var a : String = "mix(%s, %s, (x-%.9f)/%.9f)" % [ gcis(points[i-1].c), gcis(points[i].c), points[i-1].v, points[i].v-points[i-1].v ] - if i < s-1 and points[i+1].v < points[i+2].v: - var c : String = "mix(%s, %s, (x-%.9f)/%.9f)" % [ gcis(points[i+1].c), gcis(points[i+2].c), points[i+1].v, points[i+2].v-points[i+1].v ] - var ac : String = "mix("+a+", "+c+", 0.5-0.5*cos(3.14159265359*"+dx+"))" - shader += " return 0.5*("+b+" + "+ac+");\n" - else: - shader += " return mix("+a+", "+b+", 0.5+0.5*"+dx+");\n" - elif i < s-1 and points[i+1].v < points[i+2].v: - var c : String = "mix(%s, %s, (x-%.9f)/%.9f)" % [ gcis(points[i+1].c), gcis(points[i+2].c), points[i+1].v, points[i+2].v-points[i+1].v ] - shader += " return mix("+c+", "+b+", 1.0-0.5*"+dx+");\n" + shader += " } else if (x < %s) {\n" % pv(name, i+1) + var dx : String = "(x-%s)/(%s-%s)" % [ pv(name, i), pv(name, i+1), pv(name, i) ] + var b : String = "mix(%s, %s, %s)" % [ pc(name, i), pc(name, i+1), dx ] + if i > 0: + var a : String = "mix(%s, %s, (x-%s)/(%s-%s))" % [ pc(name, i-1), pc(name, i), pv(name, i-1), pv(name, i), pv(name, i-1) ] + if i < s-1: + var c : String = "mix(%s, %s, (x-%s)/(%s-%s))" % [ pc(name, i+1), pc(name, i+2), pv(name, i+1), pv(name, i+2), pv(name, i+1) ] + var ac : String = "mix("+a+", "+c+", 0.5-0.5*cos(3.14159265359*"+dx+"))" + shader += " return 0.5*("+b+" + "+ac+");\n" else: - shader += " return "+b+";\n" + shader += " return mix("+a+", "+b+", 0.5+0.5*"+dx+");\n" + elif i < s-1: + var c : String = "mix(%s, %s, (x-%s)/(%s-%s))" % [ pc(name, i+1), pc(name, i+2), pv(name, i+1), pv(name, i+2), pv(name, i+1) ] + shader += " return mix("+c+", "+b+", 1.0-0.5*"+dx+");\n" + else: + shader += " return "+b+";\n" shader += " }\n" - shader += " return "+gcis(points[s].c)+";\n" + shader += " return "+pc(name, s)+";\n" else: shader += " return vec4(0.0, 0.0, 0.0, 1.0);\n" _: diff --git a/material_maker/examples/beehive.ptex b/material_maker/examples/beehive.ptex index da4fb9b..f0f0efb 100644 --- a/material_maker/examples/beehive.ptex +++ b/material_maker/examples/beehive.ptex @@ -1,34 +1,82 @@ { "connections": [ { - "from": "graph", + "from": "colorize_2", + "from_port": 0, + "to": "blend", + "to_port": 0 + }, + { + "from": "colorize", + "from_port": 0, + "to": "blend", + "to_port": 1 + }, + { + "from": "beehive_2", + "from_port": 0, + "to": "colorize_2", + "to_port": 0 + }, + { + "from": "beehive_2", + "from_port": 1, + "to": "colorize", + "to_port": 0 + }, + { + "from": "blend", + "from_port": 0, + "to": "colorize_5", + "to_port": 0 + }, + { + "from": "blend", + "from_port": 0, + "to": "colorize_4", + "to_port": 0 + }, + { + "from": "blend", + "from_port": 0, + "to": "normal_map", + "to_port": 0 + }, + { + "from": "blend", + "from_port": 0, + "to": "colorize_3", + "to_port": 0 + }, + { + "from": "colorize_5", + "from_port": 0, + "to": "Material", + "to_port": 0 + }, + { + "from": "uniform_greyscale", + "from_port": 0, + "to": "Material", + "to_port": 1 + }, + { + "from": "colorize_4", + "from_port": 0, + "to": "Material", + "to_port": 2 + }, + { + "from": "normal_map", "from_port": 0, "to": "Material", "to_port": 4 }, { - "from": "graph", - "from_port": 1, + "from": "colorize_3", + "from_port": 0, "to": "Material", "to_port": 6 - }, - { - "from": "graph", - "from_port": 2, - "to": "Material", - "to_port": 1 - }, - { - "from": "graph", - "from_port": 3, - "to": "Material", - "to_port": 2 - }, - { - "from": "graph", - "from_port": 4, - "to": "Material", - "to_port": 0 } ], "label": "Graph", @@ -39,6 +87,9 @@ }, "nodes": [ { + "export_paths": { + + }, "name": "Material", "node_position": { "x": -28, @@ -52,477 +103,237 @@ "r": 1, "type": "Color" }, - "ao_light_affect": 1, + "ao": 1, "depth_scale": 0.2, "emission_energy": 1, "metallic": 1, - "normal_scale": 1, + "normal": 1, "roughness": 1, "size": 11, - "subsurf_scatter_strength": 0 + "sss": 0 }, "type": "material" }, { - "connections": [ - { - "from": "normal_map", - "from_port": 0, - "to": "gen_outputs", - "to_port": 0 - }, - { - "from": "graph", - "from_port": 0, - "to": "normal_map", - "to_port": 0 - }, - { - "from": "graph", - "from_port": 0, - "to": "colorize_3", - "to_port": 0 - }, - { - "from": "colorize_3", - "from_port": 0, - "to": "gen_outputs", - "to_port": 1 - }, - { - "from": "uniform_greyscale", - "from_port": 0, - "to": "gen_outputs", - "to_port": 2 - }, - { - "from": "colorize_4", - "from_port": 0, - "to": "gen_outputs", - "to_port": 3 - }, - { - "from": "colorize_5", - "from_port": 0, - "to": "gen_outputs", - "to_port": 4 - }, - { - "from": "graph", - "from_port": 0, - "to": "colorize_5", - "to_port": 0 - }, - { - "from": "graph", - "from_port": 0, - "to": "colorize_4", - "to_port": 0 - } - ], - "label": "Graph", - "name": "graph", + "name": "colorize", "node_position": { - "x": -353.865601, - "y": 6.860606 + "x": -591.193665, + "y": 41.163864 }, - "nodes": [ - { - "name": "colorize_5", - "node_position": { - "x": -240.009644, - "y": -136 - }, - "parameters": { - "gradient": { - "interpolation": 1, - "points": [ - { - "a": 1, - "b": 0, - "g": 0.068034, - "pos": 0, - "r": 0.098958 - }, - { - "a": 1, - "b": 0, - "g": 0.6875, - "pos": 0.881818, - "r": 1 - } - ], - "type": "Gradient" - } - }, - "type": "colorize" - }, - { - "name": "colorize_4", - "node_position": { - "x": -245.009644, - "y": 15 - }, - "parameters": { - "gradient": { - "interpolation": 1, - "points": [ - { - "a": 1, - "b": 0.65625, - "g": 0.65625, - "pos": 0.518182, - "r": 0.65625 - }, - { - "a": 1, - "b": 0, - "g": 0, - "pos": 0.890909, - "r": 0 - } - ], - "type": "Gradient" - } - }, - "type": "colorize" - }, - { - "name": "uniform_greyscale", - "node_position": { - "x": -246.009644, - "y": -55.5 - }, - "parameters": { - "color": 0.16 - }, - "type": "uniform_greyscale" - }, - { - "name": "colorize_3", - "node_position": { - "x": -244.009644, - "y": 233.5 - }, - "parameters": { - "gradient": { - "interpolation": 1, - "points": [ - { - "a": 1, - "b": 1, - "g": 1, - "pos": 0, - "r": 1 - }, - { - "a": 1, - "b": 0, - "g": 0, - "pos": 1, - "r": 0 - } - ], - "type": "Gradient" - } - }, - "type": "colorize" - }, - { - "name": "normal_map", - "node_position": { - "x": -235.009644, - "y": 96 - }, - "parameters": { - "param0": 11, - "param1": 1.02, - "param2": 0, - "param4": 1 - }, - "type": "normal_map" - }, - { - "name": "gen_inputs", - "node_position": { - "x": -802.009644, - "y": 6.860606 - }, - "parameters": { - - }, - "ports": [ - - ], - "type": "ios" - }, - { - "name": "gen_outputs", - "node_position": { - "x": 64.990356, - "y": 6.860606 - }, - "parameters": { - - }, - "ports": [ - { - "name": "port0", - "type": "rgba" - }, - { - "name": "port1", - "type": "rgba" - }, - { - "name": "port2", - "type": "f" - }, - { - "name": "port3", - "type": "rgba" - }, - { - "name": "port4", - "type": "rgba" - } - ], - "type": "ios" - }, - { - "name": "gen_parameters", - "node_position": { - "x": -553.865601, - "y": -452.254547 - }, - "parameters": { - - }, - "type": "remote", - "widgets": [ - - ] - }, - { - "connections": [ - { - "from": "colorize_2", - "from_port": 0, - "to": "blend", - "to_port": 0 - }, - { - "from": "colorize", - "from_port": 0, - "to": "blend", - "to_port": 1 - }, - { - "from": "blend", - "from_port": 0, - "to": "gen_outputs", - "to_port": 0 - }, - { - "from": "blend", - "from_port": 0, - "to": "gen_outputs", - "to_port": 0 - }, - { - "from": "blend", - "from_port": 0, - "to": "gen_outputs", - "to_port": 0 - }, - { - "from": "blend", - "from_port": 0, - "to": "gen_outputs", - "to_port": 0 - }, - { - "from": "beehive_2", - "from_port": 0, - "to": "colorize_2", - "to_port": 0 - }, - { - "from": "beehive_2", - "from_port": 1, - "to": "colorize", - "to_port": 0 - } - ], - "label": "Graph", - "name": "graph", - "node_position": { - "x": -514.685547, - "y": 2.186363 - }, - "nodes": [ - { - "name": "colorize", - "node_position": { - "x": -510.5, - "y": 45 - }, - "parameters": { - "gradient": { - "interpolation": 1, - "points": [ - { - "a": 1, - "b": 0, - "g": 0, - "pos": 0, - "r": 0 - }, - { - "a": 1, - "b": 0.225431, - "g": 0.225431, - "pos": 0.583818, - "r": 0.225431 - }, - { - "a": 1, - "b": 0.96875, - "g": 0.96875, - "pos": 0.672727, - "r": 0.96875 - } - ], - "type": "Gradient" - } - }, - "type": "colorize" - }, - { - "name": "colorize_2", - "node_position": { - "x": -510.5, - "y": -26 - }, - "parameters": { - "gradient": { - "interpolation": 1, - "points": [ - { - "a": 1, - "b": 1, - "g": 1, - "pos": 0, - "r": 1 - }, - { - "a": 1, - "b": 0.947917, - "g": 0.947917, - "pos": 0.049912, - "r": 0.947917 - }, - { - "a": 1, - "b": 0.115584, - "g": 0.115584, - "pos": 0.106977, - "r": 0.115584 - }, - { - "a": 1, - "b": 0, - "g": 0, - "pos": 0.290909, - "r": 0 - } - ], - "type": "Gradient" - } - }, - "type": "colorize" - }, - { - "name": "blend", - "node_position": { - "x": -523.009644, - "y": 117 - }, - "parameters": { - "amount": 1, - "blend_type": 9 - }, - "seed_value": -12215, - "type": "blend" - }, - { - "name": "beehive_2", - "node_position": { - "x": -514.732483, - "y": -127.254547 - }, - "parameters": { - "sx": 20, - "sy": 12 - }, - "type": "beehive" - }, - { - "name": "gen_inputs", - "node_position": { - "x": -823.009644, - "y": 2.186363 - }, - "parameters": { - - }, - "ports": [ - - ], - "type": "ios" - }, - { - "name": "gen_outputs", - "node_position": { - "x": -210.5, - "y": 2.186363 - }, - "parameters": { - - }, - "ports": [ - { - "name": "port0", - "type": "rgba" - } - ], - "type": "ios" - }, - { - "name": "gen_parameters", - "node_position": { - "x": -714.685547, - "y": -427.254547 - }, - "parameters": { - - }, - "type": "remote", - "widgets": [ - - ] - } - ], - "parameters": { - - }, - "type": "graph" - } - ], "parameters": { - + "gradient": { + "interpolation": 1, + "points": [ + { + "a": 1, + "b": 0, + "g": 0, + "pos": 0, + "r": 0 + }, + { + "a": 1, + "b": 0.225431, + "g": 0.225431, + "pos": 0.583818, + "r": 0.225431 + }, + { + "a": 1, + "b": 0.96875, + "g": 0.96875, + "pos": 0.672727, + "r": 0.96875 + } + ], + "type": "Gradient" + } }, - "type": "graph" + "type": "colorize" + }, + { + "name": "colorize_2", + "node_position": { + "x": -591.193665, + "y": -29.836136 + }, + "parameters": { + "gradient": { + "interpolation": 1, + "points": [ + { + "a": 1, + "b": 1, + "g": 1, + "pos": 0, + "r": 1 + }, + { + "a": 1, + "b": 0.947917, + "g": 0.947917, + "pos": 0.049912, + "r": 0.947917 + }, + { + "a": 1, + "b": 0.115584, + "g": 0.115584, + "pos": 0.106977, + "r": 0.115584 + }, + { + "a": 1, + "b": 0, + "g": 0, + "pos": 0.290909, + "r": 0 + } + ], + "type": "Gradient" + } + }, + "type": "colorize" + }, + { + "name": "blend", + "node_position": { + "x": -603.703308, + "y": 113.163872 + }, + "parameters": { + "amount": 1, + "blend_type": 9 + }, + "seed_value": -12215, + "type": "blend" + }, + { + "name": "normal_map", + "node_position": { + "x": -270.375671, + "y": 88.194351 + }, + "parameters": { + "param0": 11, + "param1": 1.02, + "param2": 0, + "param4": 1 + }, + "type": "normal_map" + }, + { + "name": "colorize_3", + "node_position": { + "x": -279.375671, + "y": 225.694351 + }, + "parameters": { + "gradient": { + "interpolation": 1, + "points": [ + { + "a": 1, + "b": 1, + "g": 1, + "pos": 0, + "r": 1 + }, + { + "a": 1, + "b": 0, + "g": 0, + "pos": 1, + "r": 0 + } + ], + "type": "Gradient" + } + }, + "type": "colorize" + }, + { + "name": "uniform_greyscale", + "node_position": { + "x": -281.375671, + "y": -63.305649 + }, + "parameters": { + "color": 0.16 + }, + "type": "uniform_greyscale" + }, + { + "name": "colorize_4", + "node_position": { + "x": -280.375671, + "y": 7.194351 + }, + "parameters": { + "gradient": { + "interpolation": 1, + "points": [ + { + "a": 1, + "b": 0.65625, + "g": 0.65625, + "pos": 0.518182, + "r": 0.65625 + }, + { + "a": 1, + "b": 0, + "g": 0, + "pos": 0.890909, + "r": 0 + } + ], + "type": "Gradient" + } + }, + "type": "colorize" + }, + { + "name": "colorize_5", + "node_position": { + "x": -275.375671, + "y": -143.805649 + }, + "parameters": { + "gradient": { + "interpolation": 1, + "points": [ + { + "a": 1, + "b": 0, + "g": 0.068034, + "pos": 0, + "r": 0.098958 + }, + { + "a": 1, + "b": 0, + "g": 0.6875, + "pos": 0.881818, + "r": 1 + } + ], + "type": "Gradient" + } + }, + "type": "colorize" + }, + { + "name": "beehive_2", + "node_position": { + "x": -595.426147, + "y": -131.090683 + }, + "parameters": { + "sx": 20, + "sy": 12 + }, + "type": "beehive" } ], "parameters": { diff --git a/material_maker/examples/brick_rotated.ptex b/material_maker/examples/brick_rotated.ptex index bce9a5e..dc2faa1 100644 --- a/material_maker/examples/brick_rotated.ptex +++ b/material_maker/examples/brick_rotated.ptex @@ -1,23 +1,5 @@ { "connections": [ - { - "from": "bricks", - "from_port": 2, - "to": "transform", - "to_port": 1 - }, - { - "from": "bricks", - "from_port": 3, - "to": "transform", - "to_port": 2 - }, - { - "from": "bricks", - "from_port": 0, - "to": "blend", - "to_port": 1 - }, { "from": "transform", "from_port": 0, @@ -30,12 +12,6 @@ "to": "transform", "to_port": 0 }, - { - "from": "bricks", - "from_port": 1, - "to": "transform", - "to_port": 3 - }, { "from": "blend", "from_port": 0, @@ -59,6 +35,30 @@ "from_port": 0, "to": "Material", "to_port": 4 + }, + { + "from": "bricks_2", + "from_port": 2, + "to": "transform", + "to_port": 1 + }, + { + "from": "bricks_2", + "from_port": 3, + "to": "transform", + "to_port": 2 + }, + { + "from": "bricks_2", + "from_port": 0, + "to": "blend", + "to_port": 1 + }, + { + "from": "bricks_2", + "from_port": 1, + "to": "transform", + "to_port": 3 } ], "label": "Graph", @@ -69,6 +69,9 @@ }, "nodes": [ { + "export_paths": { + + }, "name": "Material", "node_position": { "x": 70, @@ -82,148 +85,17 @@ "r": 1, "type": "Color" }, - "ao_light_affect": 1, + "ao": 1, "depth_scale": 1, "emission_energy": 1, "metallic": 1, - "normal_scale": 1, + "normal": 1, "roughness": 1, "size": 11, - "subsurf_scatter_strength": 0 + "sss": 0 }, "type": "material" }, - { - "name": "bricks", - "node_position": { - "x": -549.5, - "y": -120.5 - }, - "parameters": { - "bevel": 0.1, - "columns": 3, - "mortar": 0.1, - "pattern": 0, - "repeat": 1, - "row_offset": 0.5, - "rows": 6 - }, - "shader_model": { - "code": "vec4 $(name_uv) = $(name)_xyzw($(uv));\n", - "global": "vec4 brick(vec2 uv, vec2 bmin, vec2 bmax, float mortar, float bevel) {\n\tfloat color;\n\tvec2 c1 = (uv-bmin-vec2(mortar))/bevel;\n\tvec2 c2 = (bmax-uv-vec2(mortar))/bevel;\n\tvec2 c = min(c1, c2);\n\tcolor = clamp(min(c.x, c.y), 0.0, 1.0);\n\tvec2 tiled_brick_pos = mod(bmin, vec2(1.0, 1.0));\n\treturn vec4(color, 0.5*(bmin+bmax), tiled_brick_pos.x+7.0*tiled_brick_pos.y);\n}\n\nvec4 bricks_rb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {\n\tcount *= repeat;\n\tmortar /= max(count.x, count.y);\n\tbevel /= max(count.x, count.y);\n\tfloat x_offset = offset*step(0.5, fract(uv.y*count.y*0.5));\n\tvec2 bmin = floor(vec2(uv.x*count.x-x_offset, uv.y*count.y));\n\tbmin.x += x_offset;\n\tbmin /= count;\n\treturn brick(uv, bmin, bmin+vec2(1.0)/count, mortar, bevel);\n}\n\nvec4 bricks_rb2(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {\n\tcount *= repeat;\n\tmortar /= max(2.0*count.x, count.y);\n\tbevel /= max(2.0*count.x, count.y);\n\tfloat x_offset = offset*step(0.5, fract(uv.y*count.y*0.5));\n\tcount.x = count.x*(1.0+step(0.5, fract(uv.y*count.y*0.5)));\n\tvec2 bmin = floor(vec2(uv.x*count.x-x_offset, uv.y*count.y));\n\tbmin.x += x_offset;\n\tbmin /= count;\n\treturn brick(uv, bmin, bmin+vec2(1.0)/count, mortar, bevel);\n}\n\nvec4 bricks_hb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {\n\tfloat pc = count.x+count.y;\n\tfloat c = pc*repeat;\n\tmortar /= c;\n\tbevel /= c;\n\tvec2 corner = floor(uv*c);\n\tfloat cdiff = mod(corner.x-corner.y, pc);\n\tif (cdiff < count.x) {\n\t\treturn brick(uv, (corner-vec2(cdiff, 0.0))/c, (corner-vec2(cdiff, 0.0)+vec2(count.x, 1.0))/c, mortar, bevel);\n\t} else {\n\t\treturn brick(uv, (corner-vec2(0.0, pc-cdiff-1.0))/c, (corner-vec2(0.0, pc-cdiff-1.0)+vec2(1.0, count.y))/c, mortar, bevel);\n\t}\n}\n\nvec4 bricks_bw(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {\n\tvec2 c = 2.0*count*repeat;\n\tfloat mc = max(c.x, c.y);\n\tmortar /= mc;\n\tbevel /= mc;\n\tvec2 corner1 = floor(uv*c);\n\tvec2 corner2 = count*floor(repeat*2.0*uv);\n\tfloat cdiff = mod(dot(floor(repeat*2.0*uv), vec2(1.0)), 2.0);\n\tvec2 corner;\n\tvec2 size;\n\tif (cdiff == 0.0) {\n\t\tcorner = vec2(corner1.x, corner2.y);\n\t\tsize = vec2(1.0, count.y);\n\t} else {\n\t\tcorner = vec2(corner2.x, corner1.y);\n\t\tsize = vec2(count.x, 1.0);\n\t}\n\treturn brick(uv, corner/c, (corner+size)/c, mortar, bevel);\n}\n\nvec4 bricks_sb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {\n\tvec2 c = (count+vec2(1.0))*repeat;\n\tfloat mc = max(c.x, c.y);\n\tmortar /= mc;\n\tbevel /= mc;\n\tvec2 corner1 = floor(uv*c);\n\tvec2 corner2 = (count+vec2(1.0))*floor(repeat*uv);\n\tvec2 rcorner = corner1 - corner2;\n\tvec2 corner;\n\tvec2 size;\n\tif (rcorner.x == 0.0 && rcorner.y < count.y) {\n\t\tcorner = corner2;\n\t\tsize = vec2(1.0, count.y);\n\t} else if (rcorner.y == 0.0) {\n\t\tcorner = corner2+vec2(1.0, 0.0);\n\t\tsize = vec2(count.x, 1.0);\n\t} else if (rcorner.x == count.x) {\n\t\tcorner = corner2+vec2(count.x, 1.0);\n\t\tsize = vec2(1.0, count.y);\n\t} else if (rcorner.y == count.y) {\n\t\tcorner = corner2+vec2(0.0, count.y);\n\t\tsize = vec2(count.x, 1.0);\n\t} else {\n\t\tcorner = corner2+vec2(1.0);\n\t\tsize = vec2(count.x-1.0, count.y-1.0);\n\t}\n\treturn brick(uv, corner/c, (corner+size)/c, mortar, bevel);\n}", - "inputs": [ - - ], - "instance": "vec4 $(name)_xyzw(vec2 uv) {\n return bricks_$(pattern)(uv, vec2($(columns), $(rows)), $(repeat), $(row_offset), $(mortar), max(0.001, $(bevel)));\n}", - "name": "Bricks", - "outputs": [ - { - "f": "$(name_uv).x", - "type": "f" - }, - { - "rgb": "rand3(vec2($(name_uv).w, $(seed)))", - "type": "rgb" - }, - { - "f": "$(name_uv).y", - "type": "f" - }, - { - "f": "$(name_uv).z", - "type": "f" - } - ], - "parameters": [ - { - "default": 0, - "label": "", - "name": "pattern", - "type": "enum", - "values": [ - { - "name": "Running bond", - "value": "rb" - }, - { - "name": "Running bond (2)", - "value": "rb2" - }, - { - "name": "HerringBone", - "value": "hb" - }, - { - "name": "Basket weave", - "value": "bw" - }, - { - "name": "Spanish bond", - "value": "sb" - } - ] - }, - { - "default": 1, - "label": "Repeat:", - "max": 8, - "min": 1, - "name": "repeat", - "step": 1, - "type": "float", - "widget": "spinbox" - }, - { - "default": 6, - "label": "Rows:", - "max": 64, - "min": 1, - "name": "rows", - "step": 1, - "type": "float", - "widget": "spinbox" - }, - { - "default": 3, - "label": "Columns:", - "max": 64, - "min": 1, - "name": "columns", - "step": 1, - "type": "float", - "widget": "spinbox" - }, - { - "default": 0.5, - "label": "Offset:", - "max": 1, - "min": 0, - "name": "row_offset", - "step": 0, - "type": "float" - }, - { - "default": 0.1, - "label": "Mortar:", - "max": 0.5, - "min": 0, - "name": "mortar", - "step": 0, - "type": "float" - }, - { - "default": 0.1, - "label": "Bevel:", - "max": 0.5, - "min": 0, - "name": "bevel", - "step": 0, - "type": "float" - } - ] - }, - "type": "shader" - }, { "name": "blend", "node_position": { @@ -311,7 +183,7 @@ "y": 165.542206 }, "parameters": { - "size": 4 + }, "size": { "x": 280, @@ -328,15 +200,31 @@ "y": -40.645294 }, "parameters": { - "amount": 0.5, "param0": 11, "param1": 0.995, "param2": 0, - "param3": 0, - "param4": 1, - "size": 4 + "param4": 1 }, "type": "normal_map" + }, + { + "name": "bricks_2", + "node_position": { + "x": -528.086548, + "y": -114.154938 + }, + "parameters": { + "bevel": 0.1, + "columns": 3, + "corner": 0, + "mortar": 0.1, + "pattern": 0, + "repeat": 1, + "round": 0, + "row_offset": 0.5, + "rows": 6 + }, + "type": "bricks" } ], "parameters": { diff --git a/material_maker/examples/marble.ptex b/material_maker/examples/marble.ptex index 97a613e..16047b6 100644 --- a/material_maker/examples/marble.ptex +++ b/material_maker/examples/marble.ptex @@ -255,6 +255,9 @@ }, "nodes": [ { + "export_paths": { + + }, "name": "Material", "node_position": { "x": 424, @@ -268,14 +271,14 @@ "r": 1, "type": "Color" }, - "ao_light_affect": 0.95, + "ao": 1, "depth_scale": 0, "emission_energy": 1, "metallic": 1, - "normal_scale": 1, + "normal": 1, "roughness": 1, "size": 11, - "subsurf_scatter_strength": 0 + "sss": 0 }, "type": "material" }, @@ -286,7 +289,7 @@ "y": 34.016663 }, "parameters": { - "steps": 6 + }, "type": "invert" }, @@ -328,21 +331,21 @@ "to_port": 0 }, { - "from": "_2_2_2_2", + "from": "blend", "from_port": 0, - "to": "gen_outputs", + "to": "mwf_create_map", "to_port": 0 }, { "from": "bricks", "from_port": 1, - "to": "_2_2_2_2", + "to": "mwf_create_map", "to_port": 1 }, { - "from": "blend", + "from": "mwf_create_map", "from_port": 0, - "to": "_2_2_2_2", + "to": "gen_outputs", "to_port": 0 } ], @@ -371,7 +374,7 @@ "y": -369.233337 }, "parameters": { - "steps": 6 + }, "type": "invert" }, @@ -484,67 +487,6 @@ } ] }, - { - "name": "_2_2_2_2", - "node_position": { - "x": -467.634766, - "y": -373.905029 - }, - "parameters": { - "angle": 0, - "height": 1 - }, - "seed_value": -41854, - "shader_model": { - "code": "", - "global": "", - "inputs": [ - { - "default": "0.0", - "label": "", - "name": "in", - "type": "f" - }, - { - "default": "0.0", - "label": "", - "name": "rand", - "type": "f" - } - ], - "instance": "", - "name": "Create Map", - "outputs": [ - { - "rgb": "vec3($height*$in($uv), $angle*0.01745329251, rand(vec2($seed.0+$rand($uv))))", - "type": "rgb" - } - ], - "parameters": [ - { - "control": "None", - "default": 1, - "label": "Height", - "max": 1, - "min": 0, - "name": "height", - "step": 0.01, - "type": "float" - }, - { - "control": "None", - "default": 0, - "label": "Angle", - "max": 180, - "min": -180, - "name": "angle", - "step": 0.1, - "type": "float" - } - ] - }, - "type": "shader" - }, { "name": "uniform_greyscale_2", "node_position": { @@ -555,6 +497,18 @@ "color": 1 }, "type": "uniform_greyscale" + }, + { + "name": "mwf_create_map", + "node_position": { + "x": -497.801086, + "y": -339.560547 + }, + "parameters": { + "angle": 0, + "height": 1 + }, + "type": "mwf_create_map" } ], "parameters": { @@ -609,14 +563,7 @@ "y": -230.983337 }, "parameters": { - "color": { - "a": 1, - "b": 1, - "g": 1, - "r": 1, - "type": "Color" - }, - "name": 0 + }, "type": "combine" }, @@ -1108,14 +1055,7 @@ "y": 39.197388 }, "parameters": { - "color": { - "a": 1, - "b": 1, - "g": 1, - "r": 1, - "type": "Color" - }, - "name": 0 + }, "type": "combine" }, @@ -1137,13 +1077,10 @@ "y": 186.780701 }, "parameters": { - "amount": 0.5, "param0": 11, "param1": 2, "param2": 0, - "param3": 0, - "param4": 0, - "size": 4 + "param4": 0 }, "type": "normal_map" }, @@ -1171,7 +1108,6 @@ "y": 149.637848 }, "parameters": { - "Randomness": 0.5, "angle": -1, "layers": 10, "length": 0.05, @@ -1784,14 +1720,7 @@ "y": 39.197388 }, "parameters": { - "color": { - "a": 1, - "b": 1, - "g": 1, - "r": 1, - "type": "Color" - }, - "name": 0 + }, "type": "combine" }, @@ -1813,13 +1742,10 @@ "y": 186.780701 }, "parameters": { - "amount": 0.5, "param0": 11, "param1": 2, "param2": 0, - "param3": 0, - "param4": 0, - "size": 4 + "param4": 0 }, "type": "normal_map" }, @@ -1847,7 +1773,6 @@ "y": 149.637848 }, "parameters": { - "Randomness": 0.5, "angle": -1, "layers": 10, "length": 0.05, @@ -2129,7 +2054,6 @@ }, "parameters": { "param0": 1, - "param1": 10, "param2": 1 }, "type": "mwf_output" diff --git a/material_maker/examples/materials.ptex b/material_maker/examples/materials.ptex index ea6ec45..81cde31 100644 --- a/material_maker/examples/materials.ptex +++ b/material_maker/examples/materials.ptex @@ -153,6 +153,9 @@ }, "nodes": [ { + "export_paths": { + + }, "name": "Material", "node_position": { "x": 12, @@ -166,14 +169,14 @@ "r": 1, "type": "Color" }, - "ao_light_affect": 1, + "ao": 1, "depth_scale": 1, "emission_energy": 1, "metallic": 1, - "normal_scale": 1, + "normal": 1, "roughness": 1, "size": 11, - "subsurf_scatter_strength": 0 + "sss": 0 }, "type": "material" }, @@ -2187,7 +2190,7 @@ "parameters": { "choices": 3, "outputs": 4, - "source": 0 + "source": 2 }, "type": "switch" }, diff --git a/material_maker/examples/mmm_donuts.ptex b/material_maker/examples/mmm_donuts.ptex index dc30143..c146b0d 100644 --- a/material_maker/examples/mmm_donuts.ptex +++ b/material_maker/examples/mmm_donuts.ptex @@ -6,30 +6,6 @@ "to": "sdf3d_scale_2", "to_port": 0 }, - { - "from": "sdf3d_scale_2", - "from_port": 0, - "to": "sdf3d_repeat", - "to_port": 0 - }, - { - "from": "sdf3d_scale_2", - "from_port": 0, - "to": "sdf3d_repeat_2", - "to_port": 0 - }, - { - "from": "sdf3d_repeat_2", - "from_port": 0, - "to": "sdf3d_translate_3_2_2", - "to_port": 0 - }, - { - "from": "sdf3d_repeat", - "from_port": 0, - "to": "sdf3d_boolean", - "to_port": 0 - }, { "from": "sdf3d_translate_3_2_2", "from_port": 0, @@ -401,6 +377,30 @@ "from_port": 2, "to": "mul_detect_2_2", "to_port": 1 + }, + { + "from": "sdf3d_scale_2", + "from_port": 0, + "to": "sdf3d_repeat_3", + "to_port": 0 + }, + { + "from": "sdf3d_repeat_3", + "from_port": 0, + "to": "sdf3d_boolean", + "to_port": 0 + }, + { + "from": "sdf3d_scale_2", + "from_port": 0, + "to": "sdf3d_repeat_3_2", + "to_port": 0 + }, + { + "from": "sdf3d_repeat_3_2", + "from_port": 0, + "to": "sdf3d_translate_3_2_2", + "to_port": 0 } ], "label": "Graph", @@ -411,6 +411,9 @@ }, "nodes": [ { + "export_paths": { + + }, "name": "Material", "node_position": { "x": 1596.135986, @@ -424,14 +427,14 @@ "r": 1, "type": "Color" }, - "ao_light_affect": 1, + "ao": 1, "depth_scale": 0.3, "emission_energy": 1, "metallic": 1, - "normal_scale": 1, + "normal": 1, "roughness": 1, "size": 11, - "subsurf_scatter_strength": 0 + "sss": 0 }, "type": "material" }, @@ -562,8 +565,8 @@ "label": "Donut", "name": "graph", "node_position": { - "x": -664.759155, - "y": -18.094296 + "x": -660.759155, + "y": 14.905704 }, "nodes": [ { @@ -573,15 +576,7 @@ "y": 249.420105 }, "parameters": { - "bevel": 0, - "c": 0.31, - "cx": 0, - "cy": 0, - "h": 0.08, - "k": 0.15, - "op": 0, - "r": 0.15, - "w": 0.28 + "c": 0.31 }, "shader_model": { "code": "", @@ -624,13 +619,7 @@ "y": 320.541656 }, "parameters": { - "bevel": 0, - "cx": 0, - "cy": 0, - "h": 0.08, - "op": 2, - "r": 0.3, - "w": 0.28 + "op": 2 }, "shader_model": { "code": "", @@ -699,18 +688,13 @@ "name": "sdf3d_repeat", "node_position": { "x": -768.854126, - "y": 276.291656 + "y": 281.291656 }, "parameters": { - "a": 0, "r": 0.51, "rx": 16, "ry": 16, - "rz": 16, - "s": 0.3, - "x": 0.35, - "y": 0, - "z": 0 + "rz": 16 }, "shader_model": { "code": "", @@ -727,7 +711,7 @@ "name": "Repeat", "outputs": [ { - "sdf3dc": "$in(sdf3d_repeat($uv, vec3(1.0/$rx, 1.0/$ry, 1.0/$rz), $seed, $r))", + "sdf3dc": "$in(sdf3d_repeat($uv, vec3(1.0/$rx, 1.0/$ry, 1.0/$rz), float($seed), $r))", "type": "sdf3dc" } ], @@ -784,10 +768,7 @@ }, "parameters": { "l": 0.02, - "r": 0.01, - "sx": 0.25, - "sy": 0.25, - "sz": 0.5 + "r": 0.01 }, "type": "sdf3d_capsule" }, @@ -799,10 +780,7 @@ }, "parameters": { "R": 0.3, - "r": 0.14, - "sx": 0.1, - "sy": 0.1, - "sz": 0.02 + "r": 0.14 }, "type": "sdf3d_torus" }, @@ -814,10 +792,7 @@ }, "parameters": { "R": 0.3, - "r": 0.15, - "sx": 0.1, - "sy": 0.1, - "sz": 0.02 + "r": 0.15 }, "type": "sdf3d_torus" }, @@ -828,13 +803,7 @@ "y": -3.083344 }, "parameters": { - "bevel": 0, - "cx": 0, - "cy": 0, - "h": 0.08, - "op": 0, - "r": 0.3, - "w": 0.28 + "op": 0 }, "shader_model": { "code": "", @@ -893,15 +862,7 @@ "y": -156.583344 }, "parameters": { - "bevel": 0, - "c": 0.08, - "cx": 0, - "cy": 0, - "h": 0.08, - "k": 0.15, - "op": 0, - "r": 0.15, - "w": 0.28 + "c": 0.08 }, "shader_model": { "code": "", @@ -957,15 +918,7 @@ "y": 130.166656 }, "parameters": { - "bevel": 0, - "c": 0.87, - "cx": 0, - "cy": 0, - "h": 0.08, - "k": 0.15, - "op": 0, - "r": 0.15, - "w": 0.28 + "c": 0.87 }, "shader_model": { "code": "", @@ -1008,13 +961,7 @@ "y": 127.920105 }, "parameters": { - "bevel": 0, - "cx": 0, - "cy": 0, - "h": 0.08, - "op": 0, - "r": 0.3, - "w": 0.28 + "op": 0 }, "shader_model": { "code": "", @@ -1117,76 +1064,6 @@ }, "type": "graph" }, - { - "name": "sdf3d_repeat", - "node_position": { - "x": -482.202179, - "y": -14.881774 - }, - "parameters": { - "a": 0, - "r": 0.2, - "rx": 3, - "ry": 3, - "s": 0.3, - "x": 0.35, - "y": 0, - "z": 0 - }, - "shader_model": { - "code": "", - "global": "vec3 repeat(vec3 p, vec3 r, float seed, float randomness) {\n\tvec3 a = (rand3(floor(mod((p.xy+0.5*r.xy)/r.xy, 1.0/r.xy)+vec2(seed)))-0.5)*6.28*randomness;\n\tp = mod(p+0.5*r,r)-0.5*r;\n\tvec3 rv;\n\tfloat c;\n\tfloat s;\n\tc = cos(a.x);\n\ts = sin(a.x);\n\trv.x = p.x;\n\trv.y = p.y*c+p.z*s;\n\trv.z = -p.y*s+p.z*c;\n\tc = cos(a.y);\n\ts = sin(a.y);\n\tp.x = rv.x*c+rv.z*s;\n\tp.y = rv.y;\n\tp.z = -rv.x*s+rv.z*c;\n\tc = cos(a.z);\n\ts = sin(a.z);\n\trv.x = p.x*c+p.y*s;\n\trv.y = -p.x*s+p.y*c;\n\trv.z = p.z;\n\treturn rv;\n}\n", - "inputs": [ - { - "default": "0.0", - "label": "", - "name": "in", - "type": "sdf3dc" - } - ], - "instance": "", - "name": "Repeat", - "outputs": [ - { - "sdf3dc": "$in(repeat($uv, vec3(1.0/$rx, 1.0/$ry, 0.0), $seed, $r))", - "type": "sdf3dc" - } - ], - "parameters": [ - { - "control": "None", - "default": 4, - "label": "X", - "max": 32, - "min": 1, - "name": "rx", - "step": 1, - "type": "float" - }, - { - "control": "None", - "default": 4, - "label": "Y", - "max": 32, - "min": 1, - "name": "ry", - "step": 1, - "type": "float" - }, - { - "control": "None", - "default": 0.5, - "label": "R", - "max": 1, - "min": 0, - "name": "r", - "step": 0.01, - "type": "float" - } - ] - }, - "type": "shader" - }, { "name": "sdf3d_scale_2", "node_position": { @@ -1194,11 +1071,7 @@ "y": 66.030228 }, "parameters": { - "a": 0, - "s": 0.37, - "x": 0.35, - "y": 0, - "z": 0 + "s": 0.37 }, "shader_model": { "code": "vec2 $(name_uv)_in = $in(($uv)/$s);", @@ -1234,86 +1107,16 @@ }, "type": "shader" }, - { - "name": "sdf3d_repeat_2", - "node_position": { - "x": -480.202179, - "y": 110.618225 - }, - "parameters": { - "a": 0, - "r": 0.21, - "rx": 3, - "ry": 3, - "s": 0.3, - "x": 0.35, - "y": 0, - "z": 0 - }, - "shader_model": { - "code": "", - "global": "vec3 repeat(vec3 p, vec3 r, float seed, float randomness) {\n\tvec3 a = (rand3(floor(mod((p.xy+0.5*r.xy)/r.xy, 1.0/r.xy)+vec2(seed)))-0.5)*6.28*randomness;\n\tp = mod(p+0.5*r,r)-0.5*r;\n\tvec3 rv;\n\tfloat c;\n\tfloat s;\n\tc = cos(a.x);\n\ts = sin(a.x);\n\trv.x = p.x;\n\trv.y = p.y*c+p.z*s;\n\trv.z = -p.y*s+p.z*c;\n\tc = cos(a.y);\n\ts = sin(a.y);\n\tp.x = rv.x*c+rv.z*s;\n\tp.y = rv.y;\n\tp.z = -rv.x*s+rv.z*c;\n\tc = cos(a.z);\n\ts = sin(a.z);\n\trv.x = p.x*c+p.y*s;\n\trv.y = -p.x*s+p.y*c;\n\trv.z = p.z;\n\treturn rv;\n}\n", - "inputs": [ - { - "default": "0.0", - "label": "", - "name": "in", - "type": "sdf3dc" - } - ], - "instance": "", - "name": "Repeat", - "outputs": [ - { - "sdf3dc": "$in(repeat($uv, vec3(1.0/$rx, 1.0/$ry, 0.0), $seed, $r))", - "type": "sdf3dc" - } - ], - "parameters": [ - { - "control": "None", - "default": 4, - "label": "X", - "max": 32, - "min": 1, - "name": "rx", - "step": 1, - "type": "float" - }, - { - "control": "None", - "default": 4, - "label": "Y", - "max": 32, - "min": 1, - "name": "ry", - "step": 1, - "type": "float" - }, - { - "control": "None", - "default": 0.5, - "label": "R", - "max": 1, - "min": 0, - "name": "r", - "step": 0.01, - "type": "float" - } - ] - }, - "type": "shader" - }, { "name": "sdf3d_translate_3_2_2", "node_position": { - "x": -479.952209, - "y": 213.034912 + "x": -478.952209, + "y": 207.034912 }, "parameters": { - "x": 0.14, + "x": 0.18, "y": 0.11, - "z": 0.2 + "z": 0.14 }, "shader_model": { "code": "", @@ -1372,17 +1175,11 @@ { "name": "sdf3d_boolean", "node_position": { - "x": -252.248795, + "x": -265.248779, "y": 76.092621 }, "parameters": { - "bevel": 0, - "cx": 0, - "cy": 0, - "h": 0.08, - "op": 0, - "r": 0.3, - "w": 0.28 + "op": 0 }, "shader_model": { "code": "", @@ -1443,7 +1240,7 @@ "parameters": { "x": 0, "y": 0, - "z": 0.1 + "z": 0.07 }, "shader_model": { "code": "", @@ -1513,7 +1310,7 @@ "y": -50.802036 }, "parameters": { - "size": 4 + }, "size": { "x": 757.167969, @@ -1907,7 +1704,6 @@ }, "parameters": { "param0": 10, - "param1": 50, "param2": 4.9 }, "type": "remote", @@ -2069,7 +1865,6 @@ ], "parameters": { "param0": 10, - "param1": 50, "param2": 4.9 }, "type": "graph" @@ -2179,7 +1974,6 @@ }, "parameters": { "param0": 0, - "param1": 10, "param2": 4.9 }, "type": "remote", @@ -2216,8 +2010,7 @@ }, "parameters": { "brightness": 0, - "contrast": 1, - "steps": 6 + "contrast": 1 }, "type": "brightness_contrast" }, @@ -2228,20 +2021,16 @@ "y": 544.75 }, "parameters": { - "amount": 0.5, "param0": 10, "param1": 1.02, "param2": 0, - "param3": 0, - "param4": 1, - "size": 4 + "param4": 1 }, "type": "normal_map" } ], "parameters": { "param0": 0, - "param1": 10, "param2": 4.9 }, "type": "graph" @@ -2428,7 +2217,7 @@ "y": -50.148132 }, "parameters": { - "size": 4 + }, "size": { "x": 255.271576, @@ -2452,7 +2241,7 @@ "y": -373.398132 }, "parameters": { - "size": 4 + }, "size": { "x": 464, @@ -2476,7 +2265,7 @@ "y": -289.750183 }, "parameters": { - "size": 4 + }, "size": { "x": 743.688171, @@ -2521,6 +2310,32 @@ "v": 0.08 }, "type": "mul_detect" + }, + { + "name": "sdf3d_repeat_3", + "node_position": { + "x": -479.340515, + "y": 4.22731 + }, + "parameters": { + "r": 0.2, + "rx": 3, + "ry": 3 + }, + "type": "sdf3d_repeat" + }, + { + "name": "sdf3d_repeat_3_2", + "node_position": { + "x": -479.107727, + "y": 105.348923 + }, + "parameters": { + "r": 0.2, + "rx": 3, + "ry": 3 + }, + "type": "sdf3d_repeat" } ], "parameters": { diff --git a/material_maker/examples/skulls.ptex b/material_maker/examples/skulls.ptex index 21fd35c..8748a22 100644 --- a/material_maker/examples/skulls.ptex +++ b/material_maker/examples/skulls.ptex @@ -165,6 +165,9 @@ }, "nodes": [ { + "export_paths": { + + }, "name": "Material", "node_position": { "x": 356, @@ -178,14 +181,14 @@ "r": 1, "type": "Color" }, - "ao_light_affect": 1, + "ao": 1, "depth_scale": 1, "emission_energy": 1, "metallic": 1, - "normal_scale": 1, + "normal": 1, "roughness": 1, "size": 11, - "subsurf_scatter_strength": 0 + "sss": 0 }, "type": "material" }, @@ -492,18 +495,6 @@ }, { "connections": [ - { - "from": "sdf3d_scale", - "from_port": 0, - "to": "sdf3d_scale_2", - "to_port": 0 - }, - { - "from": "sdf3d_scale_2", - "from_port": 0, - "to": "sdf3d_boolean_2", - "to_port": 0 - }, { "from": "sdf3d_translate_4", "from_port": 0, @@ -533,6 +524,18 @@ "from_port": 0, "to": "sdf3d_scale", "to_port": 0 + }, + { + "from": "sdf3d_scale", + "from_port": 0, + "to": "sdf3d_repeat_2", + "to_port": 0 + }, + { + "from": "sdf3d_repeat_2", + "from_port": 0, + "to": "sdf3d_boolean_2", + "to_port": 0 } ], "label": "Skulls", @@ -1319,68 +1322,6 @@ }, "type": "sdf3d_boolean" }, - { - "name": "sdf3d_scale_2", - "node_position": { - "x": -985.183411, - "y": 1271.851807 - }, - "parameters": { - "r": 0.25, - "rx": 4, - "ry": 4 - }, - "shader_model": { - "code": "", - "global": "vec3 repeat(vec3 p, vec3 r, float seed, float randomness) {\n\tvec3 a = (rand3(floor(mod((p.xy+0.5*r.xy)/r.xy, 1.0/r.xy)+vec2(seed)))-0.5)*6.28*randomness;\n\tp = mod(p+0.5*r,r)-0.5*r;\n\tvec3 rv;\n\tfloat c;\n\tfloat s;\n\tc = cos(a.x);\n\ts = sin(a.x);\n\trv.x = p.x;\n\trv.y = p.y*c+p.z*s;\n\trv.z = -p.y*s+p.z*c;\n\tc = cos(a.y);\n\ts = sin(a.y);\n\tp.x = rv.x*c+rv.z*s;\n\tp.y = rv.y;\n\tp.z = -rv.x*s+rv.z*c;\n\tc = cos(a.z);\n\ts = sin(a.z);\n\trv.x = p.x*c+p.y*s;\n\trv.y = -p.x*s+p.y*c;\n\trv.z = p.z;\n\treturn rv;\n}\n", - "inputs": [ - { - "default": "0.0", - "label": "", - "name": "in", - "type": "sdf3d" - } - ], - "instance": "", - "name": "Repeat", - "outputs": [ - { - "sdf3d": "$in(repeat($uv, vec3(1.0/$rx, 1.0/$ry, 0.0), $seed, $r))", - "type": "sdf3d" - } - ], - "parameters": [ - { - "default": 4, - "label": "X", - "max": 32, - "min": 1, - "name": "rx", - "step": 1, - "type": "float" - }, - { - "default": 4, - "label": "Y", - "max": 32, - "min": 1, - "name": "ry", - "step": 1, - "type": "float" - }, - { - "default": 0.5, - "label": "R", - "max": 1, - "min": 0, - "name": "r", - "step": 0.01, - "type": "float" - } - ] - }, - "type": "shader" - }, { "name": "sdf3d_repeat", "node_position": { @@ -1438,6 +1379,19 @@ "widgets": [ ] + }, + { + "name": "sdf3d_repeat_2", + "node_position": { + "x": -986.70166, + "y": 1268.091553 + }, + "parameters": { + "r": 0.25, + "rx": 4, + "ry": 4 + }, + "type": "sdf3d_repeat" } ], "parameters": { diff --git a/material_maker/graph_edit.gd b/material_maker/graph_edit.gd index ba166a1..8f778ab 100644 --- a/material_maker/graph_edit.gd +++ b/material_maker/graph_edit.gd @@ -103,7 +103,7 @@ func update_tab_title() -> void: if get_parent().has_method("set_tab_title"): get_parent().set_tab_title(get_index(), title) -func set_need_save(ns) -> void: +func set_need_save(ns = true) -> void: if ns != need_save: need_save = ns update_tab_title() diff --git a/material_maker/library/base.json b/material_maker/library/base.json index b792392..58ddf83 100644 --- a/material_maker/library/base.json +++ b/material_maker/library/base.json @@ -4898,6 +4898,9 @@ { "collapsed": true, "icon": "miscellaneous_buffer", + "parameters": { + "size": 9 + }, "tree_item": "Miscellaneous/Buffer", "type": "buffer" }, diff --git a/material_maker/main_window.gd b/material_maker/main_window.gd index be7af06..31d630e 100644 --- a/material_maker/main_window.gd +++ b/material_maker/main_window.gd @@ -15,6 +15,7 @@ onready var projects = $VBoxContainer/Layout/SplitRight/ProjectsPane/Projects onready var layout = $VBoxContainer/Layout var library var preview_2d +var histogram var preview_3d var hierarchy @@ -131,6 +132,7 @@ func _ready() -> void: layout.load_panes(config_cache) library = layout.get_pane("Library") preview_2d = layout.get_pane("Preview2D") + histogram = layout.get_pane("Histogram") preview_3d = layout.get_pane("Preview3D") preview_3d.connect("need_update", self, "update_preview_3d") hierarchy = layout.get_pane("Hierarchy") @@ -584,17 +586,13 @@ 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) + histogram.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) + histogram.set_generator(null) + preview_2d_background.set_generator(null) func update_preview_3d(previews : Array) -> void: var graph_edit : MMGraphEdit = get_current_graph_edit() @@ -610,7 +608,7 @@ 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/main_window.tscn b/material_maker/main_window.tscn index edf0e12..83a4c5d 100644 --- a/material_maker/main_window.tscn +++ b/material_maker/main_window.tscn @@ -2,6 +2,7 @@ [ext_resource path="res://material_maker/main_window.gd" type="Script" id=1] [ext_resource path="res://material_maker/main_window_layout.gd" type="Script" id=2] +[ext_resource path="res://material_maker/preview/preview_2d.tscn" type="PackedScene" id=3] [ext_resource path="res://material_maker/preview/preview_3d.tscn" type="PackedScene" id=4] [ext_resource path="res://material_maker/preview/preview_3d_ui.tscn" type="PackedScene" id=5] [ext_resource path="res://material_maker/widgets/tabs.gd" type="Script" id=6] @@ -9,27 +10,13 @@ [ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=8] [ext_resource path="res://material_maker/node_factory.gd" type="Script" id=9] [ext_resource path="res://material_maker/theme/default.tres" type="Theme" id=10] -[ext_resource path="res://material_maker/preview/preview_2d.gd" type="Script" id=11] [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); - 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(min(m2.x*size.x, m2.y*size.y), 1.0)), 1.0); -}" +resource_local_to_scene = true [sub_resource type="ShaderMaterial" id=2] +resource_local_to_scene = true shader = SubResource( 1 ) -shader_param/size = Vector2( 947, 682 ) [sub_resource type="AtlasTexture" id=3] flags = 4 @@ -127,20 +114,11 @@ size_flags_horizontal = 3 size_flags_vertical = 3 size_flags_stretch_ratio = 3.0 -[node name="Preview2D" type="ColorRect" parent="VBoxContainer/Layout/SplitRight/ProjectsPane"] +[node name="Preview2D" parent="VBoxContainer/Layout/SplitRight/ProjectsPane" instance=ExtResource( 3 )] visible = false material = SubResource( 2 ) -anchor_right = 1.0 -anchor_bottom = 1.0 -rect_min_size = Vector2( 64, 64 ) -rect_clip_content = true -mouse_filter = 1 -size_flags_horizontal = 0 -size_flags_vertical = 8 -script = ExtResource( 11 ) -__meta__ = { -"_edit_use_anchors_": false -} +margin_right = 0.0 +margin_bottom = 0.0 [node name="Preview3D" parent="VBoxContainer/Layout/SplitRight/ProjectsPane" instance=ExtResource( 4 )] margin_left = 0.0 @@ -269,7 +247,6 @@ script = ExtResource( 9 ) [connection signal="tab_changed" from="VBoxContainer/Layout/Left/Top" to="VBoxContainer/Layout" method="_on_tab_changed"] [connection signal="tab_changed" from="VBoxContainer/Layout/Left/Bottom" to="VBoxContainer/Layout" method="_on_tab_changed"] [connection signal="dragged" from="VBoxContainer/Layout/SplitRight" to="VBoxContainer/Layout" method="_on_Right_dragged"] -[connection signal="resized" from="VBoxContainer/Layout/SplitRight/ProjectsPane/Preview2D" to="VBoxContainer/Layout/SplitRight/ProjectsPane/Preview2D" method="on_resized"] [connection signal="need_update" from="VBoxContainer/Layout/SplitRight/ProjectsPane/Preview3D" to="." method="update_preview_3d"] [connection signal="no_more_tabs" from="VBoxContainer/Layout/SplitRight/ProjectsPane/Projects" to="." method="new_material"] [connection signal="resized" from="VBoxContainer/Layout/SplitRight/ProjectsPane/Projects" to="VBoxContainer/Layout/SplitRight/ProjectsPane/Projects" method="_on_Projects_resized"] diff --git a/material_maker/main_window_layout.gd b/material_maker/main_window_layout.gd index 30b268c..60391cc 100644 --- a/material_maker/main_window_layout.gd +++ b/material_maker/main_window_layout.gd @@ -10,6 +10,7 @@ const PANES = [ { name="Library", scene=preload("res://material_maker/library.tscn"), position="TopLeft" }, { name="Preview2D", scene=preload("res://material_maker/preview/preview_2d_panel.tscn"), position="BottomLeft" }, { name="Preview3D", scene=preload("res://material_maker/preview/preview_3d_panel.tscn"), position="BottomLeft" }, + { name="Histogram", scene=preload("res://material_maker/widgets/histogram/histogram.tscn"), position="BottomLeft" }, { name="Hierarchy", scene=preload("res://material_maker/widgets/graph_tree/hierarchy_pane.tscn"), position="TopRight" } ] diff --git a/material_maker/nodes/generic.gd b/material_maker/nodes/generic.gd index fdadf55..51c82ef 100644 --- a/material_maker/nodes/generic.gd +++ b/material_maker/nodes/generic.gd @@ -5,7 +5,8 @@ var controls = {} var ignore_parameter_change = "" var output_count = 0 -var preview : TextureRect +var preview : ColorRect +#var preview : TextureRect var preview_index : int = -1 var preview_position : int var preview_size : int @@ -52,7 +53,7 @@ func on_parameter_changed(p, v) -> void: o.value = gradient else: print("unsupported widget "+str(o)) - update_shaders() + get_parent().set_need_save() func initialize_properties() -> void: var parameter_names = [] @@ -81,33 +82,29 @@ func initialize_properties() -> void: else: print("unsupported widget "+str(o)) -func update_shaders() -> void: - get_parent().send_changed_signal() - update_preview() - func _on_text_changed(new_text, variable) -> void: ignore_parameter_change = variable generator.set_parameter(variable, new_text) ignore_parameter_change = "" - update_shaders() + get_parent().set_need_save() func _on_value_changed(new_value, variable) -> void: ignore_parameter_change = variable generator.set_parameter(variable, new_value) ignore_parameter_change = "" - update_shaders() + get_parent().set_need_save() func _on_color_changed(new_color, variable) -> void: ignore_parameter_change = variable generator.set_parameter(variable, new_color) ignore_parameter_change = "" - update_shaders() + get_parent().set_need_save() func _on_gradient_changed(new_gradient, variable) -> void: ignore_parameter_change = variable generator.set_parameter(variable, MMType.serialize_value(new_gradient)) ignore_parameter_change = "" - update_shaders() + get_parent().set_need_save() func create_parameter_control(p : Dictionary) -> Control: var control = null @@ -150,7 +147,8 @@ func save_preview_widget() -> void: func restore_preview_widget() -> void: if preview == null: - preview = TextureRect.new() + preview = preload("res://material_maker/preview/preview_2d.tscn").instance() + preview.shader = "uniform vec2 size;void fragment() {COLOR = preview_2d(UV);}" preview.visible = false preview_position = get_child_count() if preview.visible: @@ -295,7 +293,7 @@ func edit_generator() -> void: func update_generator(shader_model) -> void: generator.set_shader_model(shader_model) update_node() - update_shaders() + get_parent().set_need_save() func load_generator() -> void: var dialog = FileDialog.new() @@ -371,14 +369,9 @@ func update_preview(size : int = 0) -> void: preview_timer.start(0.2) func do_update_preview() -> void: - var result = generator.render(preview_index, preview_size, true) - while result is GDScriptFunctionState: - result = yield(result, "completed") - if preview.texture == null: - preview.texture = ImageTexture.new() - result.copy_to_texture(preview.texture) - result.release() if !preview.visible: add_child(preview) move_child(preview, preview_position) preview.visible = true + preview.set_generator(generator, preview_index) + preview.rect_min_size = Vector2(preview_size, preview_size) diff --git a/material_maker/nodes/generic.tscn b/material_maker/nodes/generic.tscn index 4b1dc50..e260792 100644 --- a/material_maker/nodes/generic.tscn +++ b/material_maker/nodes/generic.tscn @@ -8,3 +8,6 @@ margin_bottom = 29.0 title = "Generic" show_close = true script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/material_maker/nodes/switch.gd b/material_maker/nodes/switch.gd index 33d2d70..7e2ddf5 100644 --- a/material_maker/nodes/switch.gd +++ b/material_maker/nodes/switch.gd @@ -5,12 +5,6 @@ var fixed_lines : int = 0 func _ready() -> void: update_node() -func update_preview_buttons(index : int) -> void: - for i in range(generator.parameters.outputs): - if i != index: - var line = get_child(i) - line.get_child(2).pressed = false - func update_node() -> void: if generator == null or !generator.parameters.has("outputs") or !generator.parameters.has("choices"): return @@ -48,7 +42,6 @@ func update_node() -> void: sizer.add_child(control) control.connect("value_changed", self, "_on_value_changed", [ l.name ]) controls[l.name] = control - sizer.add_child(preload("res://material_maker/widgets/preview_button.tscn").instance()) add_child(sizer) else: # Keep lines with controls @@ -64,22 +57,12 @@ func update_node() -> void: var sizer = HBoxContainer.new() var input_label = Label.new() sizer.add_child(input_label) - if get_child_count() < 5: - var space = Control.new() - space.size_flags_horizontal = SIZE_EXPAND | SIZE_FILL - sizer.add_child(space) - var button = preload("res://material_maker/widgets/preview_button.tscn").instance() - sizer.add_child(button) - button.connect("toggled", self, "on_preview_button", [ get_child_count()-1 ]) add_child(sizer) rect_size = Vector2(0, 0) for i in range(get_child_count()): var sizer = get_child(i) var has_input = true - var has_output = false - if i < 5: - has_output = i < output_count - sizer.get_child(sizer.get_child_count()-1).visible = has_output + var has_output = i < output_count if i >= input_count: sizer.get_child(0).text = "" has_input = false diff --git a/material_maker/nodes/switch.tscn b/material_maker/nodes/switch.tscn index c6e7ee6..f332a05 100644 --- a/material_maker/nodes/switch.tscn +++ b/material_maker/nodes/switch.tscn @@ -3,8 +3,6 @@ [ext_resource path="res://material_maker/nodes/switch.gd" type="Script" id=1] [ext_resource path="res://material_maker/widgets/preview_button.tscn" type="PackedScene" id=2] - - [sub_resource type="Theme" id=1] [node name="Switch" type="GraphNode"] @@ -36,6 +34,9 @@ slot/2/right_enabled = false slot/2/right_type = 0 slot/2/right_color = Color( 1, 1, 1, 1 ) script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} [node name="HBox1" type="HBoxContainer" parent="."] margin_left = 16.0 @@ -69,9 +70,9 @@ margin_bottom = 16.0 [node name="HBox2" type="HBoxContainer" parent="."] margin_left = 16.0 -margin_top = 40.0 +margin_top = 41.0 margin_right = 135.0 -margin_bottom = 56.0 +margin_bottom = 57.0 [node name="Label" type="Label" parent="HBox2"] margin_top = 1.0 @@ -99,9 +100,9 @@ margin_bottom = 16.0 [node name="HBox3" type="HBoxContainer" parent="."] margin_left = 16.0 -margin_top = 57.0 +margin_top = 58.0 margin_right = 135.0 -margin_bottom = 73.0 +margin_bottom = 74.0 [node name="Label" type="Label" parent="HBox3"] margin_top = 1.0 diff --git a/material_maker/nodes/tones.gd b/material_maker/nodes/tones.gd index aff0e33..a3036dc 100644 --- a/material_maker/nodes/tones.gd +++ b/material_maker/nodes/tones.gd @@ -1,4 +1,4 @@ -extends MMGraphNodeBase +extends MMGraphNodeGeneric class Cursor: extends Control @@ -69,19 +69,19 @@ func _ready() -> void: cursor_out_max = Cursor.new(Color(1.0, 1.0, 1.0), 1.0, false) $Histogram.add_child(cursor_out_max) -func set_generator(g) -> void: - .set_generator(g) - generator.connect("parameter_changed", self, "on_parameter_changed") +func update_node() -> void: _on_Mode_item_selected(0) + on_parameter_changed("__input_changed__", 0) + # Preview + restore_preview_widget() func on_parameter_changed(p, v) -> void: if p == "__input_changed__": var source = generator.get_source(0) - var result = source.generator.render(source.output_index, 128, true) - while result is GDScriptFunctionState: - result = yield(result, "completed") - result.copy_to_texture($Histogram.get_image_texture()) - result.release() + if source != null: + $Histogram.set_generator(source.generator, source.output_index) + else: + $Histogram.set_generator(null, 0) func get_parameter(n : String) -> float: var value = generator.get_parameter(n) diff --git a/material_maker/preview/preview_2d.gd b/material_maker/preview/preview_2d.gd index bfcd9f3..ab0f98d 100644 --- a/material_maker/preview/preview_2d.gd +++ b/material_maker/preview/preview_2d.gd @@ -1,24 +1,66 @@ 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 +var output : int = 0 -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, o : int = 0) -> void: + if is_instance_valid(generator): + generator.disconnect("parameter_changed", self, "on_parameter_changed") + var source = { defs="", code="", textures={}, type="f", f="1.0" } if is_instance_valid(g): generator = g + output = o + generator.connect("parameter_changed", self, "on_parameter_changed") var param_defs : Array = generator.get_parameter_defs() for c in get_children(): c.setup_control(generator, param_defs) + var gen_output_defs = generator.get_output_defs() + if ! gen_output_defs.empty(): + var context : MMGenContext = MMGenContext.new() + source = generator.get_shader_code("uv", output, 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, []) + # Update shader + material.shader.code = MMGenBase.generate_preview_shader(source, source.type, shader) + # Get parameter values from the shader code + var regex = RegEx.new() + regex.compile("uniform\\s+(\\w+)\\s+([\\w_\\d]+)\\s*=\\s*([^;]+);") + for p in regex.search_all(material.shader.code): + material.set_shader_param(p.strings[2], float(p.strings[3])) + # Set texture params + if source.has("textures"): + for k in source.textures.keys(): + material.set_shader_param(k, source.textures[k]) + +func on_parameter_changed(n : String, v) -> void: + if n == "__output_changed__" and output == v: + set_generator(generator, output) + var p = generator.get_parameter_def(n) + if p.has("type"): + match p.type: + "float", "color", "gradient": + pass + _: + set_generator(generator, output) + +func on_float_parameters_changed(parameter_changes : Dictionary) -> void: + for n in parameter_changes.keys(): + for p in VisualServer.shader_get_param_list(material.shader.get_rid()): + if p.name == n: + material.set_shader_param(n, parameter_changes[n]) + break + +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..dca101b 100644 --- a/material_maker/preview/preview_2d.tscn +++ b/material_maker/preview/preview_2d.tscn @@ -3,28 +3,15 @@ [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); -}" +resource_local_to_scene = true [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 +26,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"] diff --git a/material_maker/preview/preview_3d.gd b/material_maker/preview/preview_3d.gd index f765f60..7068aa8 100644 --- a/material_maker/preview/preview_3d.gd +++ b/material_maker/preview/preview_3d.gd @@ -1,9 +1,5 @@ extends ViewportContainer -const ENVIRONMENTS = [ - "experiment", "lobby", "night", "park", "schelde" -] - const CAMERA_DISTANCE_MIN = 1.0 const CAMERA_DISTANCE_MAX = 10.0 diff --git a/material_maker/preview/preview_3d.tscn b/material_maker/preview/preview_3d.tscn index 27d1643..cc646e8 100644 --- a/material_maker/preview/preview_3d.tscn +++ b/material_maker/preview/preview_3d.tscn @@ -3,10 +3,11 @@ [ext_resource path="res://material_maker/preview/preview_3d.gd" type="Script" id=1] [ext_resource path="res://material_maker/preview/preview_3d_scene.tscn" type="PackedScene" id=2] - [sub_resource type="World" id=1] -[node name="Preview3D" type="ViewportContainer"] +[node name="Preview3D" type="ViewportContainer" groups=[ +"preview", +]] visible = false anchor_right = 1.0 anchor_bottom = 1.0 diff --git a/material_maker/widgets/float_edit.gd b/material_maker/widgets/float_edit.gd index a946365..767f995 100644 --- a/material_maker/widgets/float_edit.gd +++ b/material_maker/widgets/float_edit.gd @@ -8,7 +8,9 @@ export var step : float = 0.0 setget set_step var sliding : bool = false var start_position : float +var last_position : float var start_value : float +var modifiers : int var from_lower_bound : bool = false var from_upper_bound : bool = false @@ -45,28 +47,60 @@ func do_update(update_text : bool = true) -> void: else: cursor.rect_position.x = 0 +func get_modifiers(event): + var modifiers = 0 + if event.shift: + modifiers |= 1 + if event.control: + modifiers |= 2 + if event.alt: + modifiers |= 4 + return modifiers + func _on_LineEdit_gui_input(event : InputEvent) -> void: if event is InputEventMouseButton and event.button_index == BUTTON_LEFT: if event.is_pressed(): - start_position = event.position.x + last_position = event.position.x + start_position = last_position start_value = value sliding = true from_lower_bound = value <= min_value from_upper_bound = value >= max_value + modifiers = get_modifiers(event) else: sliding = false elif sliding and event is InputEventMouseMotion and event.button_mask == BUTTON_MASK_LEFT: - var delta : float = event.position.x-start_position - var v : float = start_value+sign(delta)*pow(abs(delta)*0.005, 2)*abs(max_value - min_value) - if step != 0: - v = min_value+floor((v - min_value)/step)*step - if !from_lower_bound and v < min_value: - v = min_value - if !from_upper_bound and v > max_value: - v = max_value - set_value(v) - select(0, 0) - emit_signal("value_changed", value) + var new_modifiers = get_modifiers(event) + if new_modifiers != modifiers: + start_position = last_position + start_value = value + modifiers = new_modifiers + else: + last_position = event.position.x + var delta : float = last_position-start_position + var current_step = step + if event.control: + delta *= 0.2 + elif event.shift: + delta *= 5.0 + if event.alt: + current_step *= 0.01 + var v : float = start_value+sign(delta)*pow(abs(delta)*0.005, 2)*abs(max_value - min_value) + if current_step != 0: + v = min_value+floor((v - min_value)/current_step)*current_step + if !from_lower_bound and v < min_value: + v = min_value + if !from_upper_bound and v > max_value: + v = max_value + set_value(v) + select(0, 0) + emit_signal("value_changed", value) + elif event is InputEventKey and !event.echo: + match event.scancode: + KEY_SHIFT, KEY_CONTROL, KEY_ALT: + start_position = last_position + start_value = value + modifiers = get_modifiers(event) func _on_LineEdit_text_changed(new_text : String) -> void: if new_text.is_valid_float(): diff --git a/material_maker/widgets/float_edit.tscn b/material_maker/widgets/float_edit.tscn index d5a0b4f..a60fe9a 100644 --- a/material_maker/widgets/float_edit.tscn +++ b/material_maker/widgets/float_edit.tscn @@ -14,6 +14,9 @@ max_length = 20 context_menu_enabled = false caret_blink = true script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} [node name="Slider" type="ColorRect" parent="."] anchor_top = 1.0 diff --git a/material_maker/widgets/gradient_editor.gd b/material_maker/widgets/gradient_editor.gd index 839fc08..cd21446 100644 --- a/material_maker/widgets/gradient_editor.gd +++ b/material_maker/widgets/gradient_editor.gd @@ -147,8 +147,11 @@ func get_gradient_color(x) -> Color: func update_shader() -> void: var shader shader = "shader_type canvas_item;\n" - shader += value.get_shader("gradient") - shader += "void fragment() { COLOR = gradient(UV.x); }" + var params = value.get_shader_params("") + for sp in params.keys(): + shader += "uniform float "+sp+" = "+str(params[sp])+";\n" + shader += value.get_shader("") + shader += "void fragment() { COLOR = _gradient_fct(UV.x); }" $Gradient.material.shader.set_code(shader) emit_signal("updated", value) diff --git a/material_maker/widgets/graph_tree/hierarchy_pane.gd b/material_maker/widgets/graph_tree/hierarchy_pane.gd index fba032c..8b31dd4 100644 --- a/material_maker/widgets/graph_tree/hierarchy_pane.gd +++ b/material_maker/widgets/graph_tree/hierarchy_pane.gd @@ -25,7 +25,7 @@ func update_from_graph_edit(graph_edit) -> void: update_index += 1 for g in item_from_gen.keys(): if is_instance_valid(g): - g.disconnect("output_changed", self, "on_gen_output_changed") + g.disconnect("parameter_changed", self, "on_gen_parameter_changed") item_from_gen = {} set_column_expand(0, true) columns = preview+1 @@ -74,7 +74,7 @@ func fill_item(item : TreeItem, generator : MMGenGraph, selected : MMGenGraph, n item.set_custom_color(0, Color(1, 1, 1)) item.set_metadata(0, generator) item_from_gen[generator] = item - generator.connect("output_changed", self, "on_gen_output_changed", [ generator ]) + generator.connect("parameter_changed", self, "on_gen_parameter_changed", [ generator ]) if preview > 0 and generator.get_output_defs().size() > 0: for i in range(min(preview, generator.get_output_defs().size())): item.set_icon(i+1, default_texture) @@ -97,7 +97,11 @@ func on_view_updated(generator) -> void: if item_from_gen.has(current_generator): item_from_gen[current_generator].set_custom_color(0, Color(0.5, 0.5, 1)) -func on_gen_output_changed(index, generator) -> void: +func on_gen_parameter_changed(param_name : String, index : int, generator) -> void: + if param_name == "__output_changed__": + on_gen_output_changed(index, generator) + +func on_gen_output_changed(index : int, generator) -> void: if item_from_gen.has(generator) and index < preview: if !pending_updates.has(generator): pending_updates[generator] = [index] diff --git a/material_maker/widgets/histogram/histogram.gd b/material_maker/widgets/histogram/histogram.gd index d2ae909..4b6b867 100644 --- a/material_maker/widgets/histogram/histogram.gd +++ b/material_maker/widgets/histogram/histogram.gd @@ -1,10 +1,89 @@ extends Control -func update_histogram() -> void: - pass +var generator : MMGenBase = null +var output : int = 0 + +var updating : bool = false +var update_again : bool = false func get_image_texture() -> ImageTexture: return $ViewportImage/ColorRect.material.get_shader_param("tex") func get_histogram_texture() -> ImageTexture: return $Control.material.get_shader_param("tex") + +func set_generator(g : MMGenBase, o : int = 0) -> void: + if is_instance_valid(generator): + generator.disconnect("parameter_changed", self, "on_parameter_changed") + var source = { defs="", code="", textures={}, type="f", f="1.0" } + if is_instance_valid(g): + generator = g + output = o + generator.connect("parameter_changed", self, "on_parameter_changed") + var param_defs : Array = generator.get_parameter_defs() + var gen_output_defs = generator.get_output_defs() + if ! gen_output_defs.empty(): + var context : MMGenContext = MMGenContext.new() + source = generator.get_shader_code("uv", output, context) + while source is GDScriptFunctionState: + source = yield(source, "completed") + if source.empty(): + source = { defs="", code="", textures={}, type="f", f="1.0" } + # Update shader + $ViewportImage/ColorRect.material.shader.code = MMGenBase.generate_preview_shader(source, source.type, "uniform vec2 size;void fragment() {COLOR = preview_2d(UV);}") + # Get parameter values from the shader code + var regex = RegEx.new() + regex.compile("uniform\\s+(\\w+)\\s+([\\w_\\d]+)\\s*=\\s*([^;]+);") + for p in regex.search_all($ViewportImage/ColorRect.material.shader.code): + $ViewportImage/ColorRect.material.set_shader_param(p.strings[2], float(p.strings[3])) + # Set texture params + if source.has("textures"): + for k in source.textures.keys(): + $ViewportImage/ColorRect.material.set_shader_param(k, source.textures[k]) + update_histogram() + +func on_parameter_changed(n : String, v) -> void: + if n == "__input_changed__": + set_generator(generator, output) + var p = generator.get_parameter_def(n) + if p.has("type"): + match p.type: + "float", "color", "gradient": + pass + _: + set_generator(generator, output) + +func on_float_parameters_changed(parameter_changes : Dictionary) -> void: + var need_update : bool = false + for n in parameter_changes.keys(): + for p in VisualServer.shader_get_param_list($ViewportImage/ColorRect.material.shader.get_rid()): + if p.name == n: + $ViewportImage/ColorRect.material.set_shader_param(n, parameter_changes[n]) + need_update = true + break + if need_update: + update_histogram() + +func update_histogram() -> void: + update_again = true + if !updating && is_visible_in_tree(): + updating = true + while update_again: + update_again = false + $ViewportImage.render_target_update_mode = Viewport.UPDATE_ONCE + $ViewportImage.update_worlds() + yield(get_tree(), "idle_frame") + yield(get_tree(), "idle_frame") + $ViewportHistogram1.render_target_update_mode = Viewport.UPDATE_ONCE + $ViewportHistogram1.update_worlds() + yield(get_tree(), "idle_frame") + yield(get_tree(), "idle_frame") + $ViewportHistogram2.render_target_update_mode = Viewport.UPDATE_ONCE + $ViewportHistogram2.update_worlds() + yield(get_tree(), "idle_frame") + yield(get_tree(), "idle_frame") + updating = false + +func _on_Histogram_visibility_changed(): + if is_visible_in_tree(): + update_histogram() diff --git a/material_maker/widgets/histogram/histogram.tscn b/material_maker/widgets/histogram/histogram.tscn index 02670ed..8dc5569 100644 --- a/material_maker/widgets/histogram/histogram.tscn +++ b/material_maker/widgets/histogram/histogram.tscn @@ -96,7 +96,9 @@ resource_local_to_scene = true shader = SubResource( 10 ) shader_param/tex = SubResource( 11 ) -[node name="Histogram" type="Control"] +[node name="Histogram" type="Control" groups=[ +"preview", +]] margin_right = 64.0 margin_bottom = 64.0 script = ExtResource( 1 ) @@ -110,7 +112,7 @@ transparent_bg = true hdr = false usage = 0 render_target_v_flip = true -render_target_update_mode = 3 +render_target_update_mode = 1 [node name="ColorRect" type="ColorRect" parent="ViewportImage"] material = SubResource( 3 ) @@ -122,10 +124,10 @@ rect_min_size = Vector2( 256, 256 ) size = Vector2( 128, 128 ) own_world = true transparent_bg = true -hdr = false -usage = 0 +disable_3d = true +keep_3d_linear = true render_target_v_flip = true -render_target_update_mode = 3 +render_target_update_mode = 1 [node name="ColorRect" type="ColorRect" parent="ViewportHistogram1"] material = SubResource( 6 ) @@ -138,7 +140,6 @@ size = Vector2( 128, 2 ) transparent_bg = true disable_3d = true keep_3d_linear = true -usage = 0 render_target_v_flip = true render_target_update_mode = 3 @@ -155,3 +156,4 @@ anchor_bottom = 1.0 __meta__ = { "_edit_use_anchors_": false } +[connection signal="visibility_changed" from="." to="." method="_on_Histogram_visibility_changed"]