From 29dbd5020db4e72a8fb7e277513a0fbffad47a66 Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sat, 24 Jan 2026 09:20:30 +0100 Subject: [PATCH 01/11] Started adding controlled variations --- .../material_maker/engine/multi_renderer.gd | 1 + .../engine/nodes/buffer_compute.tres | 1 + .../material_maker/engine/nodes/gen_base.gd | 16 ++++++++++++++++ .../material_maker/engine/nodes/gen_shader.gd | 19 +++++++++++++------ .../engine/nodes/iterate_buffer_compute.tres | 1 + .../material_maker/nodes/material_dynamic.mmg | 12 +++++++++--- .../nodes/material_raymarching.mmg | 12 ++++++++++++ .../material_maker/nodes/material_unlit.mmg | 10 +++++++++- .../material_maker/nodes/preview_f.gdshader | 1 + .../nodes/preview_fill.gdshader | 1 + .../material_maker/nodes/preview_rgb.gdshader | 1 + .../nodes/preview_rgba.gdshader | 1 + .../nodes/preview_sdf2d.gdshader | 1 + .../nodes/preview_sdf3d.gdshader | 1 + .../nodes/preview_sdf3dc.gdshader | 1 + .../nodes/preview_tex3d.gdshader | 1 + .../nodes/preview_tex3d_gs.gdshader | 1 + .../nodes/preview_v4v4.gdshader | 5 +++-- material_maker/nodes/debug/debug_popup.gd | 3 +++ .../panels/preview_2d/preview_2d.gd | 2 +- material_maker/tools/painter/painter.gd | 2 ++ .../shaders/paint_shader_template.tres | 1 + .../export_taa/accumulate_compute.tres | 1 + .../windows/sdf_builder/preview_2d.gdshader | 7 ++++--- .../windows/sdf_builder/preview_3d.gdshader | 1 + 25 files changed, 87 insertions(+), 16 deletions(-) diff --git a/addons/material_maker/engine/multi_renderer.gd b/addons/material_maker/engine/multi_renderer.gd index ca4c33ac6..1a49067d8 100644 --- a/addons/material_maker/engine/multi_renderer.gd +++ b/addons/material_maker/engine/multi_renderer.gd @@ -72,6 +72,7 @@ func generate_shader(src_code : MMGenBase.ShaderCode) -> String: shader_code += "\nuniform float variation = 0.0;\n" shader_code += "\nvoid fragment() {\n" shader_code += "float _seed_variation_ = variation;\n" + shader_code += "vec4 _controlled_variation_ = vec4(0.0);\n" shader_code += "vec2 uv = mm_chunk_offset+mm_chunk_size*UV;\n" if src_code.code != "": shader_code += src_code.code diff --git a/addons/material_maker/engine/nodes/buffer_compute.tres b/addons/material_maker/engine/nodes/buffer_compute.tres index d2e46ca20..ffeae39c6 100644 --- a/addons/material_maker/engine/nodes/buffer_compute.tres +++ b/addons/material_maker/engine/nodes/buffer_compute.tres @@ -27,6 +27,7 @@ const float seed_variation = 0.0; void main() { float _seed_variation_ = seed_variation; + vec4 _controlled_variation_ = vec4(0.0); vec2 pixel = gl_GlobalInvocationID.xy+vec2(0.5, 0.5+mm_chunk_y); vec2 image_size = imageSize(OUTPUT_TEXTURE); vec2 uv = pixel/image_size; diff --git a/addons/material_maker/engine/nodes/gen_base.gd b/addons/material_maker/engine/nodes/gen_base.gd index 8c0c3ba96..11bef5add 100644 --- a/addons/material_maker/engine/nodes/gen_base.gd +++ b/addons/material_maker/engine/nodes/gen_base.gd @@ -630,6 +630,22 @@ static func find_matching_parenthesis(string : String, i : int, op : String = '( i = max_p if min_p < 0 else min_p return i +static func split_parameters(string : String) -> Array[String]: + if string[0] != "(" or find_matching_parenthesis(string, 0) != string.length()-1: + print("bad") + return [] + string = string.substr(1, string.length()-2) + var parameters : Array[String] = [] + var p : String = "" + for s in string.split(","): + if p != "": + p += "," + p += s + if p.count("(") == p.count(")") and p.count("[") == p.count("]"): + parameters.append(p.strip_edges()) + p = "" + return parameters + static var re_line_comment : RegEx = RegEx.create_from_string("//.*") static func remove_comments(s : String) -> String: diff --git a/addons/material_maker/engine/nodes/gen_shader.gd b/addons/material_maker/engine/nodes/gen_shader.gd index 2d0761c5a..9874a9cd1 100644 --- a/addons/material_maker/engine/nodes/gen_shader.gd +++ b/addons/material_maker/engine/nodes/gen_shader.gd @@ -105,11 +105,11 @@ func find_instance_functions(code : String): for r in result: if not r.strings[1] in [ "return" ]: functions.push_back(r.strings[2]); - code = code.replace(r.strings[0], "%s %s(%s, float _seed_variation_) {" % [ r.strings[1], r.strings[2], r.strings[3] ]) + code = code.replace(r.strings[0], "%s %s(%s, float _seed_variation_, vec4 _controlled_variation_) {" % [ r.strings[1], r.strings[2], r.strings[3] ]) return { code=code, functions=functions } func fix_instance_functions(code : String, instance_functions : Array): - var variation_parameter = ", _seed_variation_" + var variation_parameter = ", _seed_variation_, _controlled_variation_" var variation_parameter_length = variation_parameter.length() for f in instance_functions: var location : int = 0 @@ -411,7 +411,7 @@ func find_keyword_call(string : String, keyword : String): print(string) return "#error" -func replace_input_with_function_call(string : String, input : String, seed_parameter : String = ", _seed_variation_", input_suffix : String = "") -> String: +func replace_input_with_function_call(string : String, input : String, seed_parameter : String = ", _seed_variation_, _controlled_variation_", input_suffix : String = "") -> String: var genname = "o"+str(get_instance_id()) while true: var uv : String = find_keyword_call(string, input+input_suffix) @@ -493,7 +493,7 @@ func generate_input_function(index : int, input: Dictionary, rv : ShaderCode, co rv.add_uniforms(source_rv.uniforms) rv.defs += source_rv.defs rv.add_globals(source_rv.globals) - rv.defs += "%s %s_input_%s(%s, float _seed_variation_) {\n" % [ mm_io_types.types[input.type].type, genname, input.name, mm_io_types.types[input.type].paramdefs ] + rv.defs += "%s %s_input_%s(%s, float _seed_variation_, vec4 _controlled_variation_) {\n" % [ mm_io_types.types[input.type].type, genname, input.name, mm_io_types.types[input.type].paramdefs ] rv.defs += "%s\n" % source_rv.code rv.defs += "return %s;\n}\n" % source_rv.output_values[input.type] @@ -611,9 +611,16 @@ func replace_input(input_name : String, suffix : String, parameters : String, va if input_def.has("function") and input_def.function: var function_name : String = "o%s_input_%s" % [ str(get_instance_id()), input_def.name ] if suffix == "variation": - return function_name+parameters + var parameter_list : Array[String] = split_parameters(parameters) + var parameters_suffix : String = ")" + match parameter_list.size(): + 1: + parameters_suffix = ", _seed_variation_, _controlled_variation_)" + 2: + parameters_suffix = ", _controlled_variation_)" + return function_name+"("+", ".join(split_parameters(parameters))+parameters_suffix else: - return function_name+"("+parameters+", _seed_variation_)" + return function_name+"("+parameters+", _seed_variation_, _controlled_variation_)" var source_rv : ShaderCode = source.generator.get_shader_code(parameters, source.output_index, context) rv.add_uniforms(source_rv.uniforms) rv.defs += source_rv.defs diff --git a/addons/material_maker/engine/nodes/iterate_buffer_compute.tres b/addons/material_maker/engine/nodes/iterate_buffer_compute.tres index d09c8a195..f7cb6a6fe 100644 --- a/addons/material_maker/engine/nodes/iterate_buffer_compute.tres +++ b/addons/material_maker/engine/nodes/iterate_buffer_compute.tres @@ -27,6 +27,7 @@ const float seed_variation = 0.0; void main() { float _seed_variation_ = seed_variation; + vec4 _controlled_variation_ = vec4(0.0); vec2 pixel = gl_GlobalInvocationID.xy+vec2(0.5, 0.5+mm_chunk_y); vec2 image_size = imageSize(OUTPUT_TEXTURE); vec2 uv = pixel/image_size; diff --git a/addons/material_maker/nodes/material_dynamic.mmg b/addons/material_maker/nodes/material_dynamic.mmg index 4c75d3a1a..e1cde3e47 100644 --- a/addons/material_maker/nodes/material_dynamic.mmg +++ b/addons/material_maker/nodes/material_dynamic.mmg @@ -75,6 +75,7 @@ "$definitions float_uniform_to_const,rename_buffers", "void fragment() {", "\tfloat _seed_variation_ = variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec2 uv = fract(UV);", "$if $(connected:depth_tex)", "\t{", @@ -177,6 +178,7 @@ "$definitions float_uniform_to_const,rename_buffers", "void fragment() {", "\tfloat _seed_variation_ = variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec2 uv = fract(UV);", "$if $(connected:depth_tex)", "\t{", @@ -266,7 +268,8 @@ "$definitions hlsl,rename_buffers,unity", "\t\t", "\t\tvoid surf (Input IN, inout SurfaceOutputStandard o) {", - "\t \t\tfloat _seed_variation_ = 0.0;", + "\t\t\tfloat _seed_variation_ = 0.0;", + "\t\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "\t\t\tfloat2 uv = IN.uv_MainTex;", "$begin_generate hlsl,rename_buffers,unity", "\t\t\to.Albedo = $albedo_tex(uv).rgb*$albedo_color.rgb;", @@ -468,7 +471,8 @@ "struct Functions {", "$definitions hlsl,rename_buffers,unreal", "\tfixed4 generated_shader(float2 uv, out float metallic, out float roughness, out float3 normal) {", - "\t \tfloat _seed_variation_ = 0.0;", + "\t\tfloat _seed_variation_ = 0.0;", + "\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "$begin_generate hlsl,rename_buffers,unreal", "\t\t// sample the generated texture", "\t\tfixed4 rv = tofloat4($albedo_tex(uv), 1.0)*$albedo_color;", @@ -558,7 +562,8 @@ "\t\t\t\t\t\t\tTexture2D _texture_$(buffer_index), SamplerState _texture_$(buffer_index)Sampler,", "$end_buffers", "\t\t\t\t\t\t\tout float metallic, out float roughness, out float3 normal, out float3 emission) {", - "\t \tfloat _seed_variation_ = 0.0;", + "\t\tfloat _seed_variation_ = 0.0;", + "\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "\t\tTime = _time;", "$begin_buffers", "\t\ttexture_$(buffer_index) = _texture_$(buffer_index);", @@ -766,6 +771,7 @@ "", "void fragment() {", "\tfloat _seed_variation_ = variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec2 uv = fract(UV);", "", "$if $(connected:depth_tex)", diff --git a/addons/material_maker/nodes/material_raymarching.mmg b/addons/material_maker/nodes/material_raymarching.mmg index 173dc9a20..3a1027032 100644 --- a/addons/material_maker/nodes/material_raymarching.mmg +++ b/addons/material_maker/nodes/material_raymarching.mmg @@ -52,6 +52,7 @@ "$definitions float_uniform_to_const,rename_buffers", "vec2 GetDist(vec3 p) {", "\tfloat _seed_variation_ = seed_variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "$begin_generate", "\tif ($flip_y) {", "\t\tp *= vec3(1.0, -1.0, 1.0);", @@ -98,6 +99,7 @@ "}", "void fragment() {", "\tfloat _seed_variation_ = seed_variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec3 ro = world_camera;", "\tvec3 rd = normalize(world_position - ro);", "\t", @@ -168,6 +170,7 @@ "$definitions float_uniform_to_const,rename_buffers", "vec2 GetDist(vec3 p) {", "\tfloat _seed_variation_ = seed_variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "$begin_generate", "\tif ($flip_y) {", "\t\tp *= vec3(1.0, -1.0, 1.0);", @@ -214,6 +217,7 @@ "}", "void fragment() {", "\tfloat _seed_variation_ = seed_variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec3 ro = world_camera;", "\tvec3 rd = normalize(world_position - ro);", "\t", @@ -283,6 +287,7 @@ "$definitions hlsl,rename_buffers,unity", "\t\tfloat2 sceneSDF(float3 p) {", "\t\t\tfloat _seed_variation_ = 0.0;", + "\t\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "$begin_generate hlsl,rename_buffers,unity", "\t\t\treturn $distance(p);", "$end_generate", @@ -320,6 +325,7 @@ "\t\t}", "\t\tvoid surf (Input IN, inout SurfaceOutputStandard o) {", "\t\t\tfloat _seed_variation_ = 0.0;", + "\t\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "\t\t\tfloat3 ro = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1.0));", "\t\t\tfloat3 rd = normalize(mul(unity_WorldToObject, float4(IN.worldPos, 1.0))-ro);", "\t\t\tfloat2 dist = RayMarch(ro, rd);", @@ -526,6 +532,7 @@ "$definitions hlsl,rename_buffers,unreal", "\tfloat2 sceneSDF(float3 p) {", "\t\tfloat _seed_variation_ = 0.0;", + "\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "\t\tp = p.xzy/Scale;", "$begin_generate hlsl,rename_buffers,unreal", "\t\tfloat2 d = $distance(p);", @@ -565,6 +572,7 @@ "\t}", "\tfloat4 generated_shader(float3 CameraPosition, float3 RayDirection, out float metallic, out float roughness, out float3 normal) {", "\t\tfloat _seed_variation_ = 0.0;", + "\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "\t\tfloat3 ro = CameraPosition;", "\t\tfloat3 rd = RayDirection;", "\t\tfloat2 dist = RayMarch(ro, rd);", @@ -671,6 +679,7 @@ "$definitions hlsl_base,rename_buffers,unreal5", "\tfloat2 sceneSDF(float3 p) {", "\t\tfloat _seed_variation_ = 0.0;", + "\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "\t\tp = p.xzy/Scale;", "$begin_generate hlsl_base,rename_buffers,unreal5", "\t\tfloat2 d = $distance(p);", @@ -714,6 +723,7 @@ "$end_buffers", "\t\t\t\t\t\t\tout float metallic, out float roughness, out float3 normal) {", "\t\tfloat _seed_variation_ = 0.0;", + "\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "\t\tTime = _time;", "\t\tScale = _scale;", "$begin_buffers", @@ -823,6 +833,7 @@ "", "vec2 GetDist(vec3 p) {", "\tfloat _seed_variation_ = 0.0;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\t", "$begin_generate", "\t\tif ($flip_y) {", @@ -876,6 +887,7 @@ "", "void fragment() {", "\tfloat _seed_variation_ = 0.0;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec3 ro = world_camera;", "\tvec3 rd = normalize(world_position - ro);", "\t", diff --git a/addons/material_maker/nodes/material_unlit.mmg b/addons/material_maker/nodes/material_unlit.mmg index fcc3fe3d5..4e21c74c7 100644 --- a/addons/material_maker/nodes/material_unlit.mmg +++ b/addons/material_maker/nodes/material_unlit.mmg @@ -55,6 +55,7 @@ "$definitions float_uniform_to_const,rename_buffers", "void fragment() {", "\tfloat _seed_variation_ = variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec2 uv = fract(UV);", "$begin_generate rename_buffers", "\tvec4 color_tex = $color_tex(uv);", @@ -110,6 +111,7 @@ "$definitions float_uniform_to_const,rename_buffers", "void fragment() {", "\tfloat _seed_variation_ = variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec2 uv = fract(UV);", "$begin_generate rename_buffers", "\tvec4 color_tex = $color_tex(uv);", @@ -166,6 +168,7 @@ "$definitions float_uniform_to_const,rename_buffers", "void fragment() {", "\tfloat _seed_variation_ = variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec2 uv = fract(UV);", "$begin_generate rename_buffers", "\tvec4 color_tex = $color_tex(uv);", @@ -221,6 +224,7 @@ "$definitions float_uniform_to_const,rename_buffers", "void fragment() {", "\tfloat _seed_variation_ = variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec2 uv = fract(UV);", "$begin_generate rename_buffers", "\tvec4 color_tex = $color_tex(uv);", @@ -285,6 +289,7 @@ "\t\t\t}", "\t\t\tfixed4 frag (v2f i) : SV_Target {", "\t\t\t\tfloat _seed_variation_ = 0.0;", + "\t\t\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "\t\t\t\tfloat2 uv = i.uv;", "$begin_generate hlsl,rename_buffers,unity", "\t\t\t\t// sample the generated texture", @@ -486,6 +491,7 @@ "$definitions hlsl,rename_buffers,unreal", "\tfixed4 generated_shader(float2 uv) {", "\t\tfloat _seed_variation_ = 0.0;", + "\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "$begin_generate hlsl,rename_buffers,unreal", "\t\t// sample the generated texture", "\t\treturn $color_tex(uv);", @@ -565,7 +571,8 @@ "\t\t\t\t\t\t , Texture2D _texture_$(buffer_index), SamplerState _texture_$(buffer_index)Sampler", "$end_buffers", "\t\t\t\t\t\t\t) {", - "\t \tfloat _seed_variation_ = 0.0;", + "\t\tfloat _seed_variation_ = 0.0;", + "\t\tfloat4 _controlled_variation_ = float4(0.0, 0.0, 0.0, 0.0);", "\t\tTime = _time;", "$begin_buffers", "\t\ttexture_$(buffer_index) = _texture_$(buffer_index);", @@ -662,6 +669,7 @@ "", "void fragment() {", "\tfloat _seed_variation_ = variation;", + "\tvec4 _controlled_variation_ = vec4(0.0);", "\tvec2 uv = fract(UV);", "$begin_generate", "\tvec4 color_tex = $color_tex(uv);", diff --git a/addons/material_maker/nodes/preview_f.gdshader b/addons/material_maker/nodes/preview_f.gdshader index b12aa2bd4..d92c2e1c8 100644 --- a/addons/material_maker/nodes/preview_f.gdshader +++ b/addons/material_maker/nodes/preview_f.gdshader @@ -2,6 +2,7 @@ uniform float variation = 0.0; vec4 preview_2d(vec2 uv) { float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) return vec4(vec3($(value)), 1.0); } diff --git a/addons/material_maker/nodes/preview_fill.gdshader b/addons/material_maker/nodes/preview_fill.gdshader index 384bb1eb3..b5a62b9e5 100644 --- a/addons/material_maker/nodes/preview_fill.gdshader +++ b/addons/material_maker/nodes/preview_fill.gdshader @@ -2,6 +2,7 @@ uniform float variation = 0.0; vec4 preview_2d(vec2 uv) { float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) return vec4(sign(dot($(value),vec4(1.0)))*(vec3(0.1)+0.9*fract(vec3(3456.765, 6523.12, 2373.987)*$(value).rgb+2341.876*$(value).aaa)), 1.0); } diff --git a/addons/material_maker/nodes/preview_rgb.gdshader b/addons/material_maker/nodes/preview_rgb.gdshader index ae1de0194..5b2a0b97c 100644 --- a/addons/material_maker/nodes/preview_rgb.gdshader +++ b/addons/material_maker/nodes/preview_rgb.gdshader @@ -2,6 +2,7 @@ uniform float variation = 0.0; vec4 preview_2d(vec2 uv) { float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) return vec4($(value), 1.0); } diff --git a/addons/material_maker/nodes/preview_rgba.gdshader b/addons/material_maker/nodes/preview_rgba.gdshader index 85ce62894..566b8d9ce 100644 --- a/addons/material_maker/nodes/preview_rgba.gdshader +++ b/addons/material_maker/nodes/preview_rgba.gdshader @@ -2,6 +2,7 @@ uniform float variation = 0.0; vec4 preview_2d(vec2 uv) { float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) return $(value); } diff --git a/addons/material_maker/nodes/preview_sdf2d.gdshader b/addons/material_maker/nodes/preview_sdf2d.gdshader index 3b744df79..19d33d354 100644 --- a/addons/material_maker/nodes/preview_sdf2d.gdshader +++ b/addons/material_maker/nodes/preview_sdf2d.gdshader @@ -2,6 +2,7 @@ uniform float variation = 0.0; vec4 preview_2d(vec2 uv) { float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) float d = $(value); vec3 col = vec3(clamp(6.0*cos(d*min((256), preview_size))-5.0, 0.0, 1.0)); diff --git a/addons/material_maker/nodes/preview_sdf3d.gdshader b/addons/material_maker/nodes/preview_sdf3d.gdshader index c5a381ae5..94518d84c 100644 --- a/addons/material_maker/nodes/preview_sdf3d.gdshader +++ b/addons/material_maker/nodes/preview_sdf3d.gdshader @@ -2,6 +2,7 @@ uniform float variation = 0.0; float calcdist(vec3 uv) { float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) float v = $(value); v = v == 0.0 ? 1.0 : v; diff --git a/addons/material_maker/nodes/preview_sdf3dc.gdshader b/addons/material_maker/nodes/preview_sdf3dc.gdshader index 6fe0971c3..792c30a91 100644 --- a/addons/material_maker/nodes/preview_sdf3dc.gdshader +++ b/addons/material_maker/nodes/preview_sdf3dc.gdshader @@ -2,6 +2,7 @@ uniform float variation = 0.0; vec2 calcdist(vec3 uv) { float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) vec2 v = $(value); v.x = v.x == 0.0 ? 1.0 : v.x; diff --git a/addons/material_maker/nodes/preview_tex3d.gdshader b/addons/material_maker/nodes/preview_tex3d.gdshader index 5afef6723..65ce251bc 100644 --- a/addons/material_maker/nodes/preview_tex3d.gdshader +++ b/addons/material_maker/nodes/preview_tex3d.gdshader @@ -6,6 +6,7 @@ float calcdist(vec3 p) { vec3 calcColor(vec4 uv) { float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) return $(value); } diff --git a/addons/material_maker/nodes/preview_tex3d_gs.gdshader b/addons/material_maker/nodes/preview_tex3d_gs.gdshader index 6c55707bb..9354b309e 100644 --- a/addons/material_maker/nodes/preview_tex3d_gs.gdshader +++ b/addons/material_maker/nodes/preview_tex3d_gs.gdshader @@ -6,6 +6,7 @@ float calcdist(vec3 p) { vec3 calcColor(vec4 uv) { float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) return vec3($(value)); } diff --git a/addons/material_maker/nodes/preview_v4v4.gdshader b/addons/material_maker/nodes/preview_v4v4.gdshader index 002e15648..4e150205d 100644 --- a/addons/material_maker/nodes/preview_v4v4.gdshader +++ b/addons/material_maker/nodes/preview_v4v4.gdshader @@ -1,9 +1,10 @@ uniform float variation = 0.0; vec4 mfield(vec4 uv) { - float _seed_variation_ = variation; + float _seed_variation_ = variation; + vec4 _controlled_variation_ = vec4(0.0); $(code) - return $(value); + return $(value); } float raymarch(vec3 ro, vec3 rd) { diff --git a/material_maker/nodes/debug/debug_popup.gd b/material_maker/nodes/debug/debug_popup.gd index 6a716d414..7df647bcd 100644 --- a/material_maker/nodes/debug/debug_popup.gd +++ b/material_maker/nodes/debug/debug_popup.gd @@ -47,6 +47,7 @@ func generate_shadertoy() -> String: code += "void mainImage(out vec4 fragColor, in vec2 fragCoord) {\n" code += "float minSize = min(iResolution.x, iResolution.y);\n" code += "float _seed_variation_ = SEED_VARIATION;\n" + code += "vec4 _controlled_variation_ = vec4(0.0);\n" code += "vec2 UV = vec2(0.0, 1.0) + vec2(1.0, -1.0) * (fragCoord-0.5*(iResolution.xy-vec2(minSize)))/minSize;\n" code += src_code.code if src_code.output_values.has("rgba"): @@ -71,6 +72,7 @@ func generate_godot_canvasitem() -> String: code += "\n" code += "void fragment() {\n" code += "float _seed_variation_ = seed_variation;\n" + code += "vec4 _controlled_variation_ = vec4(0.0);\n" code += src_code.code if src_code.output_values.has("rgba"): code += "COLOR = "+src_code.output_values.rgba+";\n" @@ -94,6 +96,7 @@ func generate_godot_spatial() -> String: code += "\n" code += "void fragment() {\n" code += "float _seed_variation_ = seed_variation;\n" + code += "vec4 _controlled_variation_ = vec4(0.0);\n" code += src_code.code if src_code.output_values.has("rgb"): code += "ALBEDO = "+src_code.output_values.rgb+";\n" diff --git a/material_maker/panels/preview_2d/preview_2d.gd b/material_maker/panels/preview_2d/preview_2d.gd index b6fc2db72..dc9a73d10 100644 --- a/material_maker/panels/preview_2d/preview_2d.gd +++ b/material_maker/panels/preview_2d/preview_2d.gd @@ -148,7 +148,7 @@ func export_as_image_file(file_name : String, image_size : Vector2i) -> void: func export_to_reference(image_size : Vector2i): if generator != null: var texture : MMTexture = await generator.render_output_to_texture(output, image_size) - mm_globals.main_window.get_panel("Reference").add_reference(await texture.get_texture()) + mm_globals.main_window.get_panel("Reference").add_reference(ImageTexture.create_from_image(await texture.get_image())) func _on_Preview2D_visibility_changed(): diff --git a/material_maker/tools/painter/painter.gd b/material_maker/tools/painter/painter.gd index 3567d6b75..015bf5bd1 100644 --- a/material_maker/tools/painter/painter.gd +++ b/material_maker/tools/painter/painter.gd @@ -519,6 +519,7 @@ func get_output_code(index : int) -> Dictionary: new_code += source_mask.defs+"\n" new_code += "\nfloat brush_function(vec2 uv) {\n" new_code += "float _seed_variation_ = 0.0;\n" + new_code += "vec4 _controlled_variation_ = vec4(0.0);\n" new_code += source_mask.code+"\n" new_code += "vec2 __brush_box = abs(uv-vec2(0.5));\n" new_code += "return (max(__brush_box.x, __brush_box.y) < 0.5) ? "+source_mask.output_values.f+" : 0.0;\n" @@ -526,6 +527,7 @@ func get_output_code(index : int) -> Dictionary: new_code += source.defs+"\n" new_code += "\nvec4 pattern_function(vec2 uv) {\n" new_code += "float _seed_variation_ = 0.0;\n" + new_code += "vec4 _controlled_variation_ = vec4(0.0);\n" new_code += source.code+"\n" new_code += "return "+source.output_values.rgba+";\n" new_code += "}\n" diff --git a/material_maker/tools/painter/shaders/paint_shader_template.tres b/material_maker/tools/painter/shaders/paint_shader_template.tres index 8bcdcec41..dfb145398 100644 --- a/material_maker/tools/painter/shaders/paint_shader_template.tres +++ b/material_maker/tools/painter/shaders/paint_shader_template.tres @@ -358,6 +358,7 @@ void do_paint_111a(vec4 paint_value, float brush_value, vec4 old_stroke_value, v void main() { const float _seed_variation_ = 0.0; + const vec4 _controlled_variation_ = vec4(0.0); ivec2 pixel = ivec2(gl_GlobalInvocationID.xy)+ivec2(0, mm_chunk_y); ivec2 image_size = imageSize(GENERATED_IMAGE); vec2 UV = vec2(pixel)/image_size; diff --git a/material_maker/windows/export_taa/accumulate_compute.tres b/material_maker/windows/export_taa/accumulate_compute.tres index 2026a346d..6e5ac0871 100644 --- a/material_maker/windows/export_taa/accumulate_compute.tres +++ b/material_maker/windows/export_taa/accumulate_compute.tres @@ -23,6 +23,7 @@ const float seed_variation = 0.0; vec4 mm_image(vec2 uv) { float _seed_variation_ = seed_variation; + vec4 _controlled_variation_ = vec4(0.0); @CODE return @OUTPUT_VALUE; } diff --git a/material_maker/windows/sdf_builder/preview_2d.gdshader b/material_maker/windows/sdf_builder/preview_2d.gdshader index 851f5266a..75ebe5027 100644 --- a/material_maker/windows/sdf_builder/preview_2d.gdshader +++ b/material_maker/windows/sdf_builder/preview_2d.gdshader @@ -58,6 +58,7 @@ float sstep(float v1, float v2) { void fragment() { float _seed_variation_ = 0.0; + vec4 _controlled_variation_ = vec4(0.0); vec2 ratio = preview_2d_size; vec2 uv = preview_2d_center-vec2(0.5)+(UV-0.5)*preview_2d_scale*ratio/min(ratio.x, ratio.y); @@ -65,8 +66,8 @@ void fragment() { float edgewidth = 0.0001; float d = -DIST_FCT(uv, 0, _seed_variation_); - float d2 = -DIST_FCT(uv, int(round(INDEX_UNIFORM)), _seed_variation_); - float d3 = -DIST_FCT(uv, -int(round(INDEX_UNIFORM)), _seed_variation_); + float d2 = -DIST_FCT(uv, int(round(INDEX_UNIFORM)), _seed_variation_, _controlled_variation_); + float d3 = -DIST_FCT(uv, -int(round(INDEX_UNIFORM)), _seed_variation_, _controlled_variation_); float color = 0.5*sstep(0.0, d); color += sstep(abs(d2), 0.002*preview_2d_scale); color += sstep(abs(d3), 0.003*preview_2d_scale); @@ -75,7 +76,7 @@ void fragment() { float metallic; float roughness; vec3 emission; - COLOR_FCT(uv, albedo, metallic, roughness, emission, _seed_variation_); + COLOR_FCT(uv, albedo, metallic, roughness, emission, _seed_variation_, _controlled_variation_); vec4 image; if (view_style == 0) { image = clamp(albedo+vec4(vec3(clamp(color, 0.0, 1.0)), 1.0), vec4(0.0), vec4(1.0)); diff --git a/material_maker/windows/sdf_builder/preview_3d.gdshader b/material_maker/windows/sdf_builder/preview_3d.gdshader index f06406cf6..122e9649b 100644 --- a/material_maker/windows/sdf_builder/preview_3d.gdshader +++ b/material_maker/windows/sdf_builder/preview_3d.gdshader @@ -92,6 +92,7 @@ void vertex() { void fragment() { float _seed_variation_ = 0.0; + vec4 _controlled_variation_ = vec4(0.0); vec3 ro = world_camera; vec3 rd = normalize(world_position - world_camera); From e07c51be19553524bf2de226b7262bf25b2d59e0 Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sat, 24 Jan 2026 11:46:56 +0100 Subject: [PATCH 02/11] Updated variations code (added $?1 syntax) and added greyscale controlled variations and iterate varations nodes --- .../material_maker/engine/nodes/gen_shader.gd | 10 +- .../nodes/controlled_variations.mmg | 84 +++++++++++++ .../nodes/iterate_variations.mmg | 113 ++++++++++++++++++ 3 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 addons/material_maker/nodes/controlled_variations.mmg create mode 100644 addons/material_maker/nodes/iterate_variations.mmg diff --git a/addons/material_maker/engine/nodes/gen_shader.gd b/addons/material_maker/engine/nodes/gen_shader.gd index 9874a9cd1..e9ec5399b 100644 --- a/addons/material_maker/engine/nodes/gen_shader.gd +++ b/addons/material_maker/engine/nodes/gen_shader.gd @@ -424,8 +424,10 @@ func replace_input_with_function_call(string : String, input : String, seed_para string = string.replace("$%s(%s)" % [ input+input_suffix, uv ], "%s_input_%s(%s%s)" % [ genname, input, uv, seed_parameter ]) return string +const WORD_LETTERS : String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_?" + func is_word_letter(l) -> bool: - return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1 + return WORD_LETTERS.find(l) != -1 func replace_rnd(string : String, offset : int = 0) -> String: while true: @@ -455,8 +457,6 @@ func replace_rndi(string : String, offset : int = 0) -> String: string = string.replace(replace, with) return string -const WORD_LETTERS : String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" - func generate_parameter_declarations(rv : ShaderCode) -> void: var genname = "o"+str(get_instance_id()) if has_randomness(): @@ -716,6 +716,10 @@ func get_common_replace_variables(uv : String, rv : ShaderCode) -> Dictionary: variables["seed"] = "seed_"+genname else: variables["seed"] = "(seed_"+genname+"+fract(_seed_variation_))" + variables["?1"] = "_controlled_variation_.x" + variables["?2"] = "_controlled_variation_.y" + variables["?3"] = "_controlled_variation_.z" + variables["?4"] = "_controlled_variation_.w" variables["node_id"] = str(get_instance_id()) return variables diff --git a/addons/material_maker/nodes/controlled_variations.mmg b/addons/material_maker/nodes/controlled_variations.mmg new file mode 100644 index 000000000..abcda6146 --- /dev/null +++ b/addons/material_maker/nodes/controlled_variations.mmg @@ -0,0 +1,84 @@ +{ + "generic_size": 1, + "name": "controlled_variations", + "node_position": { + "x": 0, + "y": 0 + }, + "parameters": { + "v1": 0.5, + "variable": 0 + }, + "seed_int": 0, + "shader_model": { + "code": [ + "#for", + "vec4 $(name_uv)_cv_# = _controlled_variation_;", + "$(name_uv)_cv_#.$variable = $v#;", + "#end" + ], + "global": "", + "inputs": [ + { + "default": "1.0", + "function": true, + "label": "", + "longdesc": "The input image", + "name": "in", + "shortdesc": "Input", + "type": "f" + } + ], + "instance": "", + "longdesc": "Generates controlled variations for its input", + "name": "Controlled Variations", + "outputs": [ + { + "f": "$in.variation($uv, _seed_variation_, $(name_uv)_cv_#)", + "longdesc": "Shows a variation of the input", + "shortdesc": "Output1", + "type": "f" + } + ], + "parameters": [ + { + "control": "None", + "default": 0.0, + "label": "", + "longdesc": "Seed modifier for output 1", + "max": 1.0, + "min": 0.0, + "name": "v#", + "shortdesc": "Seed modifier", + "step": 0.01, + "type": "float" + }, + { + "default": 0, + "label": "Variable", + "name": "variable", + "type": "enum", + "values": [ + { + "name": "$?1", + "value": "x" + }, + { + "name": "$?2", + "value": "y" + }, + { + "name": "$?3", + "value": "z" + }, + { + "name": "$?4", + "value": "w" + } + ] + } + ], + "shortdesc": "Controlled Variations" + }, + "type": "shader" +} \ No newline at end of file diff --git a/addons/material_maker/nodes/iterate_variations.mmg b/addons/material_maker/nodes/iterate_variations.mmg new file mode 100644 index 000000000..77c0a7911 --- /dev/null +++ b/addons/material_maker/nodes/iterate_variations.mmg @@ -0,0 +1,113 @@ +{ + "name": "iterate_variations", + "node_position": { + "x": 0, + "y": 0 + }, + "parameters": { + "step": 0.1, + "v1": 0.0, + "v2": 1.0, + "variable": 0.0 + }, + "seed_int": 285134496, + "shader_model": { + "code": "", + "global": "", + "inputs": [ + { + "default": "1.0", + "function": true, + "label": "", + "longdesc": "The input image", + "name": "in", + "shortdesc": "Input", + "type": "f" + } + ], + "instance": [ + "float iterate_variations_$(name)(vec2 uv, float v1, float v2, float step) {", + "\tfloat v = 0.0;", + "\tvec4 var = _controlled_variation_;", + "\tif (sign(step) == sign(v2-v1)) {", + "\t\tfor (float x = v1; x < v2; x += step) {", + "\t\t\tvar.$variable = x;", + "\t\t\tfloat input = $in.variation(uv, _seed_variation_, var);", + "\t\t\tv = v+input;", + "\t\t}", + "\t}", + "\treturn v;", + "}" + ], + "longdesc": "Combines controlled variations for its input by iterating on the variable", + "name": "Iterate Variations", + "outputs": [ + { + "f": "iterate_variations_$(name)($uv, $v1, $v2, $step)", + "longdesc": "Shows a variation of the input", + "shortdesc": "Output1", + "type": "f" + } + ], + "parameters": [ + { + "default": 0.0, + "label": "Variable", + "name": "variable", + "type": "enum", + "values": [ + { + "name": "$?1", + "value": "x" + }, + { + "name": "$?2", + "value": "y" + }, + { + "name": "$?3", + "value": "z" + }, + { + "name": "$?4", + "value": "w" + } + ] + }, + { + "control": "None", + "default": 0.0, + "label": "From", + "longdesc": "Seed modifier for output 1", + "max": 1.0, + "min": 0.0, + "name": "v1", + "shortdesc": "Seed modifier", + "step": 0.01, + "type": "float" + }, + { + "control": "None", + "default": 1.0, + "label": "To", + "max": 1.0, + "min": 0.0, + "name": "v2", + "step": 0.01, + "type": "float" + }, + { + "control": "None", + "default": 0.1, + "label": "Step", + "max": 1.0, + "min": 0.0, + "name": "step", + "step": 0.001, + "type": "float" + } + ], + "shortdesc": "Iterate Variations" + }, + "type": "shader" +} \ No newline at end of file From 91769bc7adc4af1ada48705fc387c5bfd0ac0eb8 Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sun, 25 Jan 2026 09:13:02 +0100 Subject: [PATCH 03/11] Updated the iterate variations node --- .../nodes/iterate_variations.mmg | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/addons/material_maker/nodes/iterate_variations.mmg b/addons/material_maker/nodes/iterate_variations.mmg index 77c0a7911..41878b49c 100644 --- a/addons/material_maker/nodes/iterate_variations.mmg +++ b/addons/material_maker/nodes/iterate_variations.mmg @@ -5,10 +5,12 @@ "y": 0 }, "parameters": { + "combine": 0, + "randomize": false, "step": 0.1, "v1": 0.0, "v2": 1.0, - "variable": 0.0 + "variable": 0 }, "seed_int": 285134496, "shader_model": { @@ -28,12 +30,19 @@ "instance": [ "float iterate_variations_$(name)(vec2 uv, float v1, float v2, float step) {", "\tfloat v = 0.0;", - "\tvec4 var = _controlled_variation_;", "\tif (sign(step) == sign(v2-v1)) {", - "\t\tfor (float x = v1; x < v2; x += step) {", + "\t\tfloat count = floor((v2-v1)/step);", + "\t\tfloat seedvar = _seed_variation_;", + "\t\tvec4 var = _controlled_variation_;", + "\t\tvar.$variable = v1;", + "\t\tv = $in.variation(uv, _seed_variation_, var);", + "\t\tfor (float x = v1+step; x < v2; x += step) {", "\t\t\tvar.$variable = x;", - "\t\t\tfloat input = $in.variation(uv, _seed_variation_, var);", - "\t\t\tv = v+input;", + "\t\t\tfloat input_v = $in.variation(uv, seedvar, var);", + "\t\t\tv = $combine;", + "\t\t\tif ($randomize) {", + "\t\t\t\tseedvar = rand(vec2(seedvar,x));", + "\t\t\t}", "\t\t}", "\t}", "\treturn v;", @@ -105,6 +114,36 @@ "name": "step", "step": 0.001, "type": "float" + }, + { + "default": 0, + "label": "Combine", + "name": "combine", + "type": "enum", + "values": [ + { + "name": "Add", + "value": "v+input_v" + }, + { + "name": "Max", + "value": "max(v, input_v)" + }, + { + "name": "Min", + "value": "min(v, input_v)" + }, + { + "name": "Average", + "value": "v+input_v/count" + } + ] + }, + { + "default": true, + "label": "Randomize", + "name": "randomize", + "type": "boolean" } ], "shortdesc": "Iterate Variations" From bd61269dddb9e52cc9c449a4bc496cfebd13a298 Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sun, 25 Jan 2026 12:01:13 +0100 Subject: [PATCH 04/11] Fix in iterate variation node --- addons/material_maker/nodes/iterate_variations.mmg | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/addons/material_maker/nodes/iterate_variations.mmg b/addons/material_maker/nodes/iterate_variations.mmg index 41878b49c..83207c6b8 100644 --- a/addons/material_maker/nodes/iterate_variations.mmg +++ b/addons/material_maker/nodes/iterate_variations.mmg @@ -6,11 +6,11 @@ }, "parameters": { "combine": 0, - "randomize": false, + "randomize": true, "step": 0.1, "v1": 0.0, "v2": 1.0, - "variable": 0 + "variable": 0.0 }, "seed_int": 285134496, "shader_model": { @@ -31,14 +31,15 @@ "float iterate_variations_$(name)(vec2 uv, float v1, float v2, float step) {", "\tfloat v = 0.0;", "\tif (sign(step) == sign(v2-v1)) {", - "\t\tfloat count = floor((v2-v1)/step);", + "\t\tfloat count = 1.0+floor((v2-v1)/step);", "\t\tfloat seedvar = _seed_variation_;", "\t\tvec4 var = _controlled_variation_;", "\t\tvar.$variable = v1;", - "\t\tv = $in.variation(uv, _seed_variation_, var);", + "\t\tfloat input_v = $in.variation(uv, _seed_variation_, var);", + "\t\tv = $combine;", "\t\tfor (float x = v1+step; x < v2; x += step) {", "\t\t\tvar.$variable = x;", - "\t\t\tfloat input_v = $in.variation(uv, seedvar, var);", + "\t\t\tinput_v = $in.variation(uv, seedvar, var);", "\t\t\tv = $combine;", "\t\t\tif ($randomize) {", "\t\t\t\tseedvar = rand(vec2(seedvar,x));", @@ -116,7 +117,7 @@ "type": "float" }, { - "default": 0, + "default": 0.0, "label": "Combine", "name": "combine", "type": "enum", From 386060428a2a79d5842937fae56ec4dc3a4de9de Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sun, 25 Jan 2026 12:01:34 +0100 Subject: [PATCH 05/11] Added Layer Variations node --- .../material_maker/nodes/layer_variations.mmg | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 addons/material_maker/nodes/layer_variations.mmg diff --git a/addons/material_maker/nodes/layer_variations.mmg b/addons/material_maker/nodes/layer_variations.mmg new file mode 100644 index 000000000..bb243e772 --- /dev/null +++ b/addons/material_maker/nodes/layer_variations.mmg @@ -0,0 +1,138 @@ +{ + "name": "layer_variations", + "node_position": { + "x": 0, + "y": 0 + }, + "parameters": { + "randomize": true, + "step": 0.1, + "v1": 0.0, + "v2": 1.0, + "variable": 0.0 + }, + "seed_int": 285134496, + "shader_model": { + "code": "", + "global": "", + "inputs": [ + { + "default": "1.0", + "function": true, + "label": "", + "longdesc": "The input image", + "name": "in", + "shortdesc": "Input", + "type": "f" + }, + { + "default": "0.0", + "function": true, + "label": "", + "longdesc": "The input mask", + "name": "mask", + "shortdesc": "Mask", + "type": "f" + } + ], + "instance": [ + "float layer_variations_$(name)(vec2 uv, float v1, float v2, float step) {", + "\tfloat v = 0.0;", + "\tif (sign(step) == sign(v2-v1)) {", + "\t\tfloat count = 1.0+floor((v2-v1)/step);", + "\t\tfloat seedvar = _seed_variation_;", + "\t\tvec4 var = _controlled_variation_;", + "\t\tvar.$variable = v1;", + "\t\tfloat input_v = $in.variation(uv, seedvar, var);", + "\t\tv = input_v;", + "\t\tfor (float x = v1+step; x < v2; x += step) {", + "\t\t\tvar.$variable = x;", + "\t\t\tinput_v = $in.variation(uv, seedvar, var);", + "\t\t\tfloat mask_v = $mask.variation(uv, seedvar, var);", + "\t\t\tv = mix(v, input_v, mask_v);", + "\t\t\tif ($randomize) {", + "\t\t\t\tseedvar = rand(vec2(seedvar,x));", + "\t\t\t}", + "\t\t}", + "\t}", + "\treturn v;", + "}" + ], + "longdesc": "Layers controlled variations for its input using the variations of the mask by iterating on the variable", + "name": "Layer Variations", + "outputs": [ + { + "f": "layer_variations_$(name)($uv, $v1, $v2, $step)", + "longdesc": "Shows a variation of the input", + "shortdesc": "Output1", + "type": "f" + } + ], + "parameters": [ + { + "default": 0.0, + "label": "Variable", + "name": "variable", + "type": "enum", + "values": [ + { + "name": "$?1", + "value": "x" + }, + { + "name": "$?2", + "value": "y" + }, + { + "name": "$?3", + "value": "z" + }, + { + "name": "$?4", + "value": "w" + } + ] + }, + { + "control": "None", + "default": 0.0, + "label": "From", + "longdesc": "Seed modifier for output 1", + "max": 1.0, + "min": 0.0, + "name": "v1", + "shortdesc": "Seed modifier", + "step": 0.01, + "type": "float" + }, + { + "control": "None", + "default": 1.0, + "label": "To", + "max": 1.0, + "min": 0.0, + "name": "v2", + "step": 0.01, + "type": "float" + }, + { + "control": "None", + "default": 0.1, + "label": "Step", + "max": 1.0, + "min": 0.0, + "name": "step", + "step": 0.001, + "type": "float" + }, + { + "default": true, + "label": "Randomize", + "name": "randomize", + "type": "boolean" + } + ], + "shortdesc": "Layer Variations" + }, + "type": "shader" +} \ No newline at end of file From 493afcc072aab5b29a075bd2d82f4401f067bb85 Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sun, 25 Jan 2026 17:38:09 +0100 Subject: [PATCH 06/11] Added a color Layer Variation node --- .../nodes/layer_variations_color.mmg | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 addons/material_maker/nodes/layer_variations_color.mmg diff --git a/addons/material_maker/nodes/layer_variations_color.mmg b/addons/material_maker/nodes/layer_variations_color.mmg new file mode 100644 index 000000000..6abb4f6a3 --- /dev/null +++ b/addons/material_maker/nodes/layer_variations_color.mmg @@ -0,0 +1,128 @@ +{ + "name": "layer_variations_color", + "node_position": { + "x": 0, + "y": 0 + }, + "parameters": { + "randomize": true, + "step": 0.1, + "v1": 0.0, + "v2": 1.0, + "variable": 0.0 + }, + "seed_int": 0, + "shader_model": { + "code": "", + "global": "", + "inputs": [ + { + "default": "1.0", + "function": true, + "label": "", + "longdesc": "The input image", + "name": "in", + "shortdesc": "Input", + "type": "rgba" + } + ], + "instance": [ + "vec4 layer_variations_$(name)(vec2 uv, float v1, float v2, float step) {", + "\tvec4 v = vec4(0.0);", + "\tif (sign(step) == sign(v2-v1)) {", + "\t\tfloat count = 1.0+floor((v2-v1)/step);", + "\t\tfloat seedvar = _seed_variation_;", + "\t\tvec4 var = _controlled_variation_;", + "\t\tvar.$variable = v1;", + "\t\tvec4 input_v = $in.variation(uv, seedvar, var);", + "\t\tv = input_v;", + "\t\tfor (float x = v1+step; x < v2; x += step) {", + "\t\t\tvar.$variable = x;", + "\t\t\tinput_v = $in.variation(uv, seedvar, var);", + "\t\t\tv = vec4(mix(v.rgb, input_v.rgb, input_v.a), min(1.0, input_v.a+v.a));", + "\t\t\tif ($randomize) {", + "\t\t\t\tseedvar = rand(vec2(seedvar,x));", + "\t\t\t}", + "\t\t}", + "\t}", + "\treturn v;", + "}" + ], + "longdesc": "Layers controlled variations for its input using the variations of the mask by iterating on the variable", + "name": "Layer Variations", + "outputs": [ + { + "longdesc": "Shows a variation of the input", + "rgba": "layer_variations_$(name)($uv, $v1, $v2, $step)", + "shortdesc": "Output1", + "type": "rgba" + } + ], + "parameters": [ + { + "default": 0.0, + "label": "Variable", + "name": "variable", + "type": "enum", + "values": [ + { + "name": "$?1", + "value": "x" + }, + { + "name": "$?2", + "value": "y" + }, + { + "name": "$?3", + "value": "z" + }, + { + "name": "$?4", + "value": "w" + } + ] + }, + { + "control": "None", + "default": 0.0, + "label": "From", + "longdesc": "Seed modifier for output 1", + "max": 1.0, + "min": 0.0, + "name": "v1", + "shortdesc": "Seed modifier", + "step": 0.01, + "type": "float" + }, + { + "control": "None", + "default": 1.0, + "label": "To", + "max": 1.0, + "min": 0.0, + "name": "v2", + "step": 0.01, + "type": "float" + }, + { + "control": "None", + "default": 0.1, + "label": "Step", + "max": 1.0, + "min": 0.0, + "name": "step", + "step": 0.001, + "type": "float" + }, + { + "default": true, + "label": "Randomize", + "name": "randomize", + "type": "boolean" + } + ], + "shortdesc": "Layer Variations" + }, + "type": "shader" +} \ No newline at end of file From 33a3aa1762f9aebddaf7958e8e330aa39646d175 Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Mon, 26 Jan 2026 07:23:45 +0100 Subject: [PATCH 07/11] Added FBM variations node --- .../material_maker/nodes/fbm_variations.mmg | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 addons/material_maker/nodes/fbm_variations.mmg diff --git a/addons/material_maker/nodes/fbm_variations.mmg b/addons/material_maker/nodes/fbm_variations.mmg new file mode 100644 index 000000000..f43ec8d83 --- /dev/null +++ b/addons/material_maker/nodes/fbm_variations.mmg @@ -0,0 +1,116 @@ +{ + "name": "fbm_variations", + "node_position": { + "x": 0, + "y": 0 + }, + "parameters": { + "iterations": 10.0, + "persistance": 0.5, + "randomize": true, + "variable": 0.0 + }, + "seed_int": 0, + "shader_model": { + "code": "", + "global": "", + "inputs": [ + { + "default": "1.0", + "function": true, + "label": "", + "longdesc": "The input image", + "name": "in", + "shortdesc": "Input", + "type": "f" + } + ], + "instance": [ + "float fbm_variations_$(name)(vec2 uv, int iterations, float persistance) {", + "\tfloat v = 0.0;", + "\tfloat keep = 1.0;", + "\tfloat sum = 0.0;", + "\tfloat seedvar = _seed_variation_;", + "\tvec4 var = _controlled_variation_;", + "\tvar.$variable = 1.0;", + "\tfor (int i = 0; i < iterations; i++) {", + "\t\tfloat input_v = $in.variation(uv, seedvar, var);", + "\t\tv += input_v*keep;", + "\t\tif ($randomize) {", + "\t\t\tseedvar = rand(vec2(seedvar,sum));", + "\t\t}", + "\t\tsum += keep;", + "\t\tvar.$variable *= 2.0;", + "\t\tkeep *= persistance;", + "\t}", + "\treturn v/sum;", + "}" + ], + "longdesc": "Combines the octaves of controlled variations for its input", + "name": "FBM Variations", + "outputs": [ + { + "f": "fbm_variations_$(name)($uv, int($iterations), $persistance)", + "longdesc": "Shows a variation of the input", + "shortdesc": "Output1", + "type": "f" + } + ], + "parameters": [ + { + "default": 0.0, + "label": "Variable", + "name": "variable", + "type": "enum", + "values": [ + { + "name": "$?1", + "value": "x" + }, + { + "name": "$?2", + "value": "y" + }, + { + "name": "$?3", + "value": "z" + }, + { + "name": "$?4", + "value": "w" + } + ] + }, + { + "control": "None", + "default": 5.0, + "label": "Iterations", + "longdesc": "Seed modifier for output 1", + "max": 10.0, + "min": 1.0, + "name": "iterations", + "shortdesc": "Seed modifier", + "step": 1.0, + "type": "float" + }, + { + "control": "None", + "default": 0.5, + "label": "Persistance", + "max": 1.0, + "min": 0.0, + "name": "persistance", + "step": 0.01, + "type": "float" + }, + { + "default": true, + "label": "Randomize", + "name": "randomize", + "type": "boolean" + } + ], + "shortdesc": "FBM Variations" + }, + "type": "shader" +} \ No newline at end of file From d94673376332ff1886d45f412b2f3842d12a3897 Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sat, 7 Mar 2026 16:27:16 +0100 Subject: [PATCH 08/11] Fix for being able to update the base library when MM is run from the editor --- addons/material_maker/engine/paths.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/material_maker/engine/paths.gd b/addons/material_maker/engine/paths.gd index 377feb01a..855334c39 100644 --- a/addons/material_maker/engine/paths.gd +++ b/addons/material_maker/engine/paths.gd @@ -7,7 +7,7 @@ const WEBSITE_ADDRESS : String = "https://www.materialmaker.org" const STD_GENDEF_PATH = "res://addons/material_maker/nodes" static func get_resource_dir() -> String: - if OS.has_feature("editor"): + if Engine.is_editor_hint(): return ProjectSettings.globalize_path("res://material_maker") return OS.get_executable_path().get_base_dir() From 9dd195df81b8f8b3e4f5102cd83ef00cf9a7a52c Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sat, 7 Mar 2026 16:39:19 +0100 Subject: [PATCH 09/11] Updated nodes comments --- .../nodes/controlled_variations.mmg | 10 ++++---- .../nodes/iterate_variations.mmg | 24 +++++++++++++------ .../material_maker/nodes/layer_variations.mmg | 14 ++++++++--- .../nodes/layer_variations_color.mmg | 14 ++++++++--- 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/addons/material_maker/nodes/controlled_variations.mmg b/addons/material_maker/nodes/controlled_variations.mmg index abcda6146..82c03c087 100644 --- a/addons/material_maker/nodes/controlled_variations.mmg +++ b/addons/material_maker/nodes/controlled_variations.mmg @@ -7,7 +7,7 @@ }, "parameters": { "v1": 0.5, - "variable": 0 + "variable": 0.0 }, "seed_int": 0, "shader_model": { @@ -45,18 +45,20 @@ "control": "None", "default": 0.0, "label": "", - "longdesc": "Seed modifier for output 1", + "longdesc": "Variable value", "max": 1.0, "min": 0.0, "name": "v#", - "shortdesc": "Seed modifier", + "shortdesc": "Value", "step": 0.01, "type": "float" }, { - "default": 0, + "default": 0.0, "label": "Variable", + "longdesc": "Variable name", "name": "variable", + "shortdesc": "Variable", "type": "enum", "values": [ { diff --git a/addons/material_maker/nodes/iterate_variations.mmg b/addons/material_maker/nodes/iterate_variations.mmg index 83207c6b8..42841f878 100644 --- a/addons/material_maker/nodes/iterate_variations.mmg +++ b/addons/material_maker/nodes/iterate_variations.mmg @@ -5,14 +5,14 @@ "y": 0 }, "parameters": { - "combine": 0, - "randomize": true, + "combine": 1.0, + "randomize": false, "step": 0.1, "v1": 0.0, "v2": 1.0, "variable": 0.0 }, - "seed_int": 285134496, + "seed_int": 0, "shader_model": { "code": "", "global": "", @@ -54,8 +54,8 @@ "outputs": [ { "f": "iterate_variations_$(name)($uv, $v1, $v2, $step)", - "longdesc": "Shows a variation of the input", - "shortdesc": "Output1", + "longdesc": "The output image", + "shortdesc": "Output", "type": "f" } ], @@ -63,7 +63,9 @@ { "default": 0.0, "label": "Variable", + "longdesc": "Variable name", "name": "variable", + "shortdesc": "Variable", "type": "enum", "values": [ { @@ -88,11 +90,11 @@ "control": "None", "default": 0.0, "label": "From", - "longdesc": "Seed modifier for output 1", + "longdesc": "Initial value of the variable", "max": 1.0, "min": 0.0, "name": "v1", - "shortdesc": "Seed modifier", + "shortdesc": "From", "step": 0.01, "type": "float" }, @@ -100,9 +102,11 @@ "control": "None", "default": 1.0, "label": "To", + "longdesc": "Maximum value of the variable", "max": 1.0, "min": 0.0, "name": "v2", + "shortdesc": "To", "step": 0.01, "type": "float" }, @@ -110,16 +114,20 @@ "control": "None", "default": 0.1, "label": "Step", + "longdesc": "Step value when iterating", "max": 1.0, "min": 0.0, "name": "step", + "shortdesc": "Step", "step": 0.001, "type": "float" }, { "default": 0.0, "label": "Combine", + "longdesc": "Operator used to combine iterations (Add, Min, Max or average)", "name": "combine", + "shortdesc": "Combine", "type": "enum", "values": [ { @@ -143,7 +151,9 @@ { "default": true, "label": "Randomize", + "longdesc": "Pick different seeds for different variations", "name": "randomize", + "shortdesc": "Randomize", "type": "boolean" } ], diff --git a/addons/material_maker/nodes/layer_variations.mmg b/addons/material_maker/nodes/layer_variations.mmg index bb243e772..186e755e4 100644 --- a/addons/material_maker/nodes/layer_variations.mmg +++ b/addons/material_maker/nodes/layer_variations.mmg @@ -11,7 +11,7 @@ "v2": 1.0, "variable": 0.0 }, - "seed_int": 285134496, + "seed_int": 0, "shader_model": { "code": "", "global": "", @@ -72,7 +72,9 @@ { "default": 0.0, "label": "Variable", + "longdesc": "Variable name", "name": "variable", + "shortdesc": "Variable", "type": "enum", "values": [ { @@ -97,11 +99,11 @@ "control": "None", "default": 0.0, "label": "From", - "longdesc": "Seed modifier for output 1", + "longdesc": "Initial value of the variable", "max": 1.0, "min": 0.0, "name": "v1", - "shortdesc": "Seed modifier", + "shortdesc": "From", "step": 0.01, "type": "float" }, @@ -109,9 +111,11 @@ "control": "None", "default": 1.0, "label": "To", + "longdesc": "Maximum value of the variable", "max": 1.0, "min": 0.0, "name": "v2", + "shortdesc": "To", "step": 0.01, "type": "float" }, @@ -119,16 +123,20 @@ "control": "None", "default": 0.1, "label": "Step", + "longdesc": "Step value when iterating", "max": 1.0, "min": 0.0, "name": "step", + "shortdesc": "Step", "step": 0.001, "type": "float" }, { "default": true, "label": "Randomize", + "longdesc": "Pick different seeds for different variations", "name": "randomize", + "shortdesc": "Randomize", "type": "boolean" } ], diff --git a/addons/material_maker/nodes/layer_variations_color.mmg b/addons/material_maker/nodes/layer_variations_color.mmg index 6abb4f6a3..eac47a9e4 100644 --- a/addons/material_maker/nodes/layer_variations_color.mmg +++ b/addons/material_maker/nodes/layer_variations_color.mmg @@ -5,7 +5,7 @@ "y": 0 }, "parameters": { - "randomize": true, + "randomize": false, "step": 0.1, "v1": 0.0, "v2": 1.0, @@ -62,7 +62,9 @@ { "default": 0.0, "label": "Variable", + "longdesc": "Variable name", "name": "variable", + "shortdesc": "Variable", "type": "enum", "values": [ { @@ -87,11 +89,11 @@ "control": "None", "default": 0.0, "label": "From", - "longdesc": "Seed modifier for output 1", + "longdesc": "Initial value of the variable", "max": 1.0, "min": 0.0, "name": "v1", - "shortdesc": "Seed modifier", + "shortdesc": "From", "step": 0.01, "type": "float" }, @@ -99,9 +101,11 @@ "control": "None", "default": 1.0, "label": "To", + "longdesc": "Maximum value of the variable", "max": 1.0, "min": 0.0, "name": "v2", + "shortdesc": "To", "step": 0.01, "type": "float" }, @@ -109,16 +113,20 @@ "control": "None", "default": 0.1, "label": "Step", + "longdesc": "Step value when iterating", "max": 1.0, "min": 0.0, "name": "step", + "shortdesc": "Step", "step": 0.001, "type": "float" }, { "default": true, "label": "Randomize", + "longdesc": "Pick different seeds for different variations", "name": "randomize", + "shortdesc": "Randomize", "type": "boolean" } ], From adb62d44fcc5d6b8166c9af4828997702085b49a Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sat, 7 Mar 2026 16:40:21 +0100 Subject: [PATCH 10/11] Added controlled variations nodes to the base library --- material_maker/library/base.json | 113 +++++++++++++++++++++++++------ 1 file changed, 92 insertions(+), 21 deletions(-) diff --git a/material_maker/library/base.json b/material_maker/library/base.json index 26ef2aba9..7f5a3d042 100644 --- a/material_maker/library/base.json +++ b/material_maker/library/base.json @@ -127,10 +127,22 @@ "icon_data": "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAa5JREFUeJztmNuNgzAQRW2gBZQyqCQlpCcKpAL++QO8X8laiW0Gx85ZbeZISECG8fXN+AHWGOPMF9PQAmjUAFoAjRpAC6BRA2gBNGoALYBGDaAF0KgBtAAaNYAWQKMG0AJo1ABaAE0Xuulc/mdCa232swRfXwHWnPgq7FfGX/ync/R9fQWoAbQAmo8Y4Jx7OYZhSMZJ8sWuQ23GqD4JHnXmOc9RG6HfJct2TG9wH1CKWGdy9xmxfCEj8FUgJSZlhsSokktw9Tmg7/vg/VQnjkq/JNXmgHtsKi4V47fVNI3Z912cT6LvTpU5wBeyLEtWDmvtI4+k8+/gpIePNE5CLM/tdhO3eUaff1QZAmfHayxXaoI8ikeHgE9u2Y7j+HLPOVd8GFSpgLZtzbquh3GStp7X+NKTYJVlcNu2x3nO8pV6pvRy+JF3gWmaxLFd9zsqQ7s9Y8qaUPVdQCJ0nmdzuVxEbUjaP7t7rFoBEpOu1+vj/KiDNargVAX8R/SDCC2ARg2gBdCoAbQAGjWAFkCjBtACaNQAWgCNGkALoFEDaAE0agAtgEYNoAXQqAG0AJofyDhQx506hhgAAAAASUVORK5CYII=", "name": "text", "parameters": { - "alignment": 0, - "bg": { "a": 1.0, "b": 0.0, "g": 0.0, "r": 0.0, "type": "Color" }, + "alignment": 0.0, + "bg": { + "a": 1.0, + "b": 0.0, + "g": 0.0, + "r": 0.0, + "type": "Color" + }, "center": false, - "fg": { "a": 1.0, "b": 1.0, "g": 1.0, "r": 1.0, "type": "Color" }, + "fg": { + "a": 1.0, + "b": 1.0, + "g": 1.0, + "r": 1.0, + "type": "Color" + }, "font": "", "font_size": 64.0, "line_spacing": 0.0, @@ -7860,12 +7872,12 @@ "x": 0.0, "y": 0.0 }, - "seed_int": 0, + "seed_int": 0.0, "tree_item": "Filter/Fill/Select", "type": "fill_select" }, { - "display_name": "Comment Line", + "display_name": "Line", "icon": "miscellaneous_comment_line", "icon_data": "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABCtJREFUeJztmk9MI1Ucxz8tHbpt7RJKI4gL8kcpB4MX42GBJlwgniDawEGixsNe1oSLnk00IRoPHoyJHgzZxBA9ctkFPdiEA0gkYSUxoBGyDbiAdgVWScBOn4ducTpMYRjKvOl2PskkM+/Ne/y+X6a/Xzv5gYuLSyXjMXnfc8CrwEtAPeC/tIguThq4B9wG7gCHF9ksCtwCVECU4bEOvGJVfAfwmwNElOL4oJjIYh+BWuAHco8+AH6/n3g8TiwWIxQKnWacNFRVZWdnh9nZWdbX1/XTbwOfmd3rUzQO9vf3i1QqJcoFVVXFxMSECAaD2qfgALhmRvyT5BKHAERfX584OjqSrckSMzMzwuv1ak34xIwBb+UXeDwesbKyIlvHhRgZGdEacE8v1mtgwAv5k66uLmKxmBnTHMvw8LD2shmIaAd8Bmvqj+9ubj5188N/sxcIrbRU+7x4DFJ6S0uLfqgeeJC/MDLgeMznM5rOMX13m9X7D88X5SUSDvh4M/4MXp0LBhqUgnmrf/BqwEdNUDn7RpuIhKrxmP5i+z+WDbjeUcf1jjqryx2DURKsKFwDZAcgG8s5AOAwk819vXAAxcrgWVg24PbSFr9u/W11ecm5GlB4I958ogyehWUDaoKKo8pgbUixtwx2d9TR7ZbB8sc1QHYAsql4AywnwTt3t/jlvnPKYE1Q4fVeG8tg+IqzymBN0OYy2BOroyfmlsGyxzVAdgCyqXgDLCdBp70UrQ0pjPbYWAZD/iquKFUIh7wQCPl99pbB3s4ovZ1Rq8sdQ8XnANcA2QHIpuINsJwEZ37aZuV355TByBPVvNbdZF8ZDFRX4Vec8wAFqqtKVgbV4xNVNZjOEe+MEi+DMmigoWDA6F/4R/5kc3PzEkKyl42NDf3QtvbCyICf8ydLS0ukUqlLCMs+pqamtJfb5BopT+UamsbIoaEhkc1mZbf6WGJ+fl4oiqLtEfrCrHG3NIvE6Oio2N3dla3nXExPT4toNKoVf4Sm7zFPsbT5FPAj0JgfiEQiDA4O0t7eTjgcJpFI0NjYeGJhOp1mcnKSg4MDs2aXlL29PZLJJHNzc/qp94D3z7PXi8AORdpP29raRCaTKXB9dXVVNDU1yW6LNTq+xHxjeAEtwLdGm3o8HrG/v38sfnl5WTQ0NMgWqj8eADdPE2jWlR5gGEiQ+3jQ2trK2toaAIuLiwwMDJBOFyTYh0DG5P6lQiX31K6Ra5X/Gk1LXCn4nkfuJhIJIYQQCwsLIhKJ6J3/Bl072uOAB/iLRyLHx8dFMpkU4XBYL/4rLth54lSeRSN0bGxMBAIBvfjPeYx/YQ5zesL5GIuZtlz4iOLiP5QYl218x0nhWeBdmUHZyZ8Uis8AN6RGZCNPUyj+EBiRGpHNBMm9JxDAP8DLcsORQwx4B3hediAuLqXjP2stcqDv6aOOAAAAAElFTkSuQmCC", "tree_item": "Miscellaneous/Comment/Line", @@ -7892,40 +7904,40 @@ "display_name": "sdEllipse", "icon": "simple_sdf_shapes_sdellipse", "icon_data": "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", - "tree_item": "Simple/SDF/Shapes/sdEllipse", "parameters": { "cx": 0.0, "cy": 0.0, "h": 0.3, "w": 0.4 }, + "tree_item": "Simple/SDF/Shapes/sdEllipse", "type": "sdellipse" }, { "display_name": "sdTunnel", "icon": "simple_sdf_shapes_sdtunnel", "icon_data": "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", - "tree_item": "Simple/SDF/Shapes/sdTunnel", "parameters": { - "w": 0.35, - "h": 0.35, "cx": 0.0, - "cy": 0.0 + "cy": 0.0, + "h": 0.35, + "w": 0.35 }, + "tree_item": "Simple/SDF/Shapes/sdTunnel", "type": "sdtunnel" }, { "display_name": "sdStairs", "icon": "simple_sdf_shapes_sdstairs", "icon_data": "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", - "tree_item": "Simple/SDF/Shapes/sdStairs", "parameters": { - "cx": 0.0, - "cy": 0.0, - "h": 0.35, - "steps": 5.0, - "w": 0.35 - }, + "cx": 0.0, + "cy": 0.0, + "h": 0.35, + "steps": 5.0, + "w": 0.35 + }, + "tree_item": "Simple/SDF/Shapes/sdStairs", "type": "sdstairs" }, { @@ -7977,7 +7989,7 @@ "icon": "simple_sdf_shapes_sdkite", "icon_data": "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", "parameters": { - "apex": -0.3, + "apex": -0.3, "base": 0.4, "width": 0.225 }, @@ -7986,16 +7998,75 @@ }, { "display_name": "Directional Warp", + "icon": "transform_directional_warp", + "icon_data": "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAAAAXNSR0IArs4c6QAAFdlJREFUaIG1WllvG9fZnjNzZuNs3CVSkiNapiRvrZuiaIq2aJHeBP0L7Y/rDyhQoDfdgCZdkgZNrTip6kCKLdsURYmruM6+fBeP+HqiXH9zIQyp4Zl3ed7nXc5hv/vd74rF4scff3x8fDwajWazmWmaWZalaco5j+PY8zzDMAzDME2zXq+/8847b968WSwW4/HY87z5fK5pmiAIjUZje3u70WioqtpqtTY3NxVFKRQK3W73N7/5zdnZ2XA4vHPnzoMHD7744ovlcul5niiKqqq6rpskiSRJhUIhyzLXdTVNUxRlsVhYljWZTHRdLxQKxWKRc65p2vX19XA4NAyjXq//8pe/5MvlslAo/PSnP93c3Pz8888Hg8FyuQyCgDGWZZmiKLZt67peqVRs23706NFwOGSMMcYEQUjTFDeiKAqCkGUZ7vGlIAiSJP3pT38aDAaj0WhnZ2d/f//vf/87Y4xznqapqqqc82q1KghCFEVBEMRxnKapLMvL5RIC0GpYPMsyx3EuLy89z5tMJp988gn/9NNP33vvPcuy2u321tbW69evX7x44XlekiRZlkmSxDkvFoutVqtWqyVJMplMsBZjLEkSLCqKYpZl8Bveh/9+9tlnnU5nMBhUq9V79+598sknaZoGQWCa5tbWlqZpsixD1SzLPM+L43i1Wnmel2UZ5zxJElEUoUOSJJxzvKJWqy0WizAMz87O+JdffhmG4Q9/+EPXdTc3Nw8PDx8/fjyfz33fT9NUFEVFUUzTxJsGgwEZQxCEOI5xwxhL0zRNU6gENUql0rNnz8bjcZIkDx8+PD4+5py7rlutVkulkiRJq9VqNBpB1mKxqOs6fsg5931/tVpxzsX1BQNh/SRJoijinEdRxJMk+eqrr+bz+cHBQRAEqqo6jqNpmmVZwvoKwzDLMk3T4FY4B8bAAxA9SZI4jvGXc35+ft7r9cbjsWVZhJBKpWKa5mKxuL6+BoqAe8TSxsaGpmkwHAQlBfCRMSZJEqDhuq6qqjwIAl3XT09PJ5PJmzdvGo3GxsaGZVmyLONn0Ad+JDPAVLA6liafpGkKcZ8/f75areI43t3d/e9//6uqqiRJmqbNZrPFYiFJkizLkiTFcSyKoqZpvu9fXV3V63VEiK7rruvmnUCoRqRJkiRJEpckCaAcDAbX19fdbrdUKtXrdcdxarVatVqF0EDOLQXCMHQcx7KsR48e1Wq1SqXSbDaLxSIiZzgczmazQqEgy/JqtdI0DXwwHo9FUYTmaZqGYWjbtud5siwzxq6vr+v1ehRFmqYBKpCYMRZFEWNM13WsD5tyWouwATBEURSGIWycVwBvXSwWnU5HVdUHDx4cHBzs7u5ubW0BIViQMQauDIJAkiTHceI4DoLA8zx4bHt727KsIAjG4/F8PrdtG6AXBMHzPIiEeICgFAYgN0mS8A0noAPTyfqK1xfsTbHLGAPYNE37+c9/fnBwcHh4WCqVFotFt9t9+vQpGEySJGBJURTXdSVJIm4FlPf29srl8nA4jON4NputVis8oCgKuAG2J/zQz7MsIyKO45jjM+EY30Ju+AFuIbb57LPPXr58qev6+++//+DBg52dHUVRPvroo/Pzc9/3J5NJEASCIHDOHccBWPEKIIFznmcCvAU3gBAey0spiiIIFFEHSUCyNwrgNwh5OCGOY/griqIoikj1v/zlL19//XW5XH78+HG73T44OBiNRh9++OHFxcWLFy+iKAInwvaappHQyOuEiuVyeXJygnw0nU5936/X6xSyedZHsFJOyKPoZjU8RAoQfgD9OI6hgCiK/X6/2+2Cnb7zne+0Wq3Ly8t//etfX3zxxXw+l2VZURRYV5ZlWZazLDMMA5lruVzu7u7GcQzhsizrdDoQwvf9Wq0Wx7Gu64ZhIPMwxlRVRRACfjA0pGKMUQZ8GwPQgTxAiIJdRVH88ssve72erusffPDBxsaGJElPnz79xz/+YRhGoVAAI6Eu8jxvNptRZSEIAiQDrEEvlmU5jgNUTKfTQqGgaVqhUPB93/d9BCTMT/7HR2iiKMoNzPACXJCVFIAEgBNj7Pnz57hxHGd3d/evf/3r0dGR4zjz+Xxzc1OSpPl8Pp1OdV1H4RXH8WQysW271+s1Go2Li4vNzU0EqGmajUbj6uoKZiqVStVqNUmS1WoF+eBAJDX4DUREuFJVFd/zPLCQcQF9oIhy02QyieNYUZR2u22a5uXlZa/XWy6Xsixvbm72+33kdkEQkKdQpRWLxevr63K5DFcsl8tSqeS6riiKKDaRIsMwXCwWgA3yWpIkKIoJ/dABH+GBm5IpX+vB6nkypXphPp+vVitFUfb391VVPTs7Ozk5qdVqg8FgMBgwxlqtFug/CALoMxqNHMcRRXG1Wk0mEzxsmqZt29ABeAjDUBRFXdfBfigudF0HgPNMiot46aYQhmZZ7sorgKhwHMfzvOvr6yiKbNsuFovj8Xg2myVJgjDd3t4Ow9B1Xfi92WyqqorEaZpmEATNZrPf79fr9cFg0O/3dV23bZugCxuBBgzD0HWdamlS4JYmVNJzShD5YoFKSygAQMdxLElSGIaKoiAcgXjOOefc8zywhKZp4E3GmO/7VF1vb2/3ej2Aqt/vl8tly7KAbIiLlzLGRqNRFEWNRgP/pQt0BE1IbI4wp0C55QfgHrakcpwUk2UZ0CdWJtqRZRkUTCIyxra2trrdrq7rYRheXl6ivIX+CDwqW5AQqGjDIvlUSHZ5+2P6lrwBBRhjaPNM00QlM51OYQZgCZYrFotwDshEFEXf91VVhQNR4s9ms1ar1ev1IEQYhkEQZFmmKAoiMAzDQqFQKBQgA0QHN5CZyFJQj8uyTPV9vt4gDyAKFUWpVqvdbnc4HMqyXCwWLctC3ZIkyXA4LBQKtm0nSTKdToMgCMMQBo7j2LZtxth0OpVl+c2bN7u7u2EYTqdTJC/IR5kUhRroFWQPNRDQlB9gbkmSRJgHVrxVM0EB8mCpVJJl+eTkZD6fNxqNVqs1GAxQvk+n08lkMhqN0KbMZrMoigqFQhRFhmHYtg1E2bZt2zaqpkajsbOzg3/B/2R1wiqygSiKSO2EIsKPJEki/kEKUF5DHQHSBc3VarUsy05OTuB9vNtxnHK5jPw/nU7BTiB43/cdxymVSrqu93o9WZY1TUMiQ3NDEId1CdPwALBHpInv8yi6CQAqrOEsMTcFQEjhG5Bjo9FIkuT8/DxN04ODg8Vi8ezZs3a7bRjGcrmM45iqAMuyRFEsFAqGYfR6Pd/379y5g+iHRYlSKHCFXJ9FtUP+S5ohkA5wFw/DEM99u/gW1vVwHMeFQuHu3bvT6fTDDz/89a9/3e12d3Z2oig6PT1FaYBCgFys63oURZ1Ox/O8ra0t0zQx0aB+CpJR0QWJKUNR+UAXVQx5CL1lQFI0T1IEqjAMJUlCPkrT9KOPPvrxj3/MGLt3755hGK9fv37+/Llpmrquq6oKPun3+77vG4axt7dXqVRmsxmqEhSbtDi4G9CCbrihSBVzHVneXSBrjsIDaxH7EqPTQpgpFAqF3d3d8Xg8GAyOjo7efffdJElarZbjOKPRaDqdTqfTxWKRZRmmG3fu3DFN03EcZDTQHUiTpBTWnTHMB1YExuATiI6PVNog5SmKwqnNIXGhAPVEUCAMQ6ocHz58GMfxaDT6+OOPf/KTnwwGA8MwUAu5rhsEASyiKIqqqiAZjPqoZMiDBNJAIOgQxzFRC2xP+RGLZOsBEef8ppWhwiNvGKzI1g1nur4qlcqTJ09KpVIYhr///e8vLy9Xq9VsNvM8j3Nu23a5XMagin1zPEhzK1ofF7oOEhdFqLDunm/FJBUdN4kMCSvfelJUsFyHSuUq8cCTJ09ev37d7/f//e9/a5p2eHi4vb0Ny0FuhCMFVR6r9JGMmq6nelTOgKCEdfdIg4U8kARB4NS7EFXRL+n1gBPeRA7NssyyrIuLC8uy0jT9z3/+c3x8vL29vbe3VywWISKeR4DihogcUKECTBCEWq0my7Lnec1mE1EEPsDz6FVIMAApyzJOkx/YBn7Mc23+hhTIL0H+IfuJ60kEYZd0JgXybIGsgglpmqa2baObUxQF1sRvhdxoh7zxjZ74/+/KG0XI2UWSpBcvXty/fz9N01KphFEXNh/Q7qmqioIK+wkY1eQvLqyNka4n46QrjQAIcGRaohFhHS3kCpI1y83z8p7J1uM93/f/97//vfPOO4Ig1Go10zQxjQQ/otskzKiqikoEglFw3mQNYR0l5CwKbigAWZG2iSvymhBHCeuxFHTOW4FzHgQBnsEoV9d1DAEMw1gsFqPRCE7Issx1XYz4OeeqqiLSoihyHMd1XarAb0ptIQcvAjcSJwWGkMMx6nshB8c0N0KlXpY+4iY/2Fkul6PR6ODgAPl7Pp8Ph0P07P1+fzAY0HAJzaBhGOVyuVQqeZ6nqqqwrpffDrby0uRffMuiLDfeoPCi+Sm5Ll+V5EkCzyiKgs0vaIV5DP717NmzUqlUq9WQCiE9AuD8/Nx13Y2NDd/3sRsioCfOk4awngXk5RNz03BSQBAE0CJmMKQeZRW2bqZoKWIez/MGgwHML8vy9fW1pmlhGB4fH9u2jV4Z/RAWNwwDs+vJZCIIAgrHG1hSBFNck8TQJEkSjDroMcqgaO3DMIyiKJ9uKfuSEyi5MsZkWZ7P51EUeZ5Xr9fRiM7n8/Pzc8dxTNPc3t7+/ve/b1lWHMfT6fTk5KTT6Wia5nlesVicTCaO42AW+LZyznNc/p48cAtL+Iux6a1miGKJrStcihzcW5bl+z42YQEP3/cxhLNt++HDhx988IFhGHj71tbWD37wg8PDQ1EUUZsoitLr9YARQRD4t3NW3hv5UiSfNeE+yuJQLF+0UL0g5vpX9E9ZlqE/juM4DEPsJ2BuwBj70Y9+dHV1RUEP7r93796bN2+m02mapoh4dKFZln2jFyPapioqW/fUeeSwdXmHCCM9xdy8CTqgNKLvaVMsiiIqE9I0DYJgOp2KomjbNsIM074sy+bzeRAEhmEUi8V8CQgJsyy7wQaWzisAg6W5uT7LTXiy9RgHdfK3x2akgJCrGmRZpkwirHdL6XVkCEEQsNEGwSiiKEd94y2kAJiRIASZ8nUIWRdEic0bhIG0vsT81HLtAfoGEArDEKM+mhj4vl+tVtFOCIJgWZZpmgA9rvF4vFqtsPeT5oZ/b3kNbX+ehaTcrhaxJ0EfOzdkQnHdjqKlwg/hQ5iGwgAKELdiPwHVG2NsNBr98Y9/tCxL13UwrK7rICLf91GQMsYsy8rWw7i32zjZujGlXEsKAHBQFZYLwzAMQ9oHoRjIz8/IIdQY3FIAPIaWLYoiy7IWi8XZ2dlvf/vbdrvdbDaTJDk9Pb24uEDaJixBYfAHJ4sCOTs7O+iqisVioVCgREuRgG0fcP8tCoL5qWFA54XoktZTIKwgSVIQBEEQXF9f44EgCAqFQpqmq9Xq9PTUdd2vv/4ai89ms/F4TANGx3Hytubz+RyN7P7+vmVZBwcHOzs7sC6iIgiCfBVAe/Hf3sAkofMZQFh322Q/mAOzrdFo1G63waq9Xq/ZbOI8Rb/fF9dbUuRG0BSWGgwGpVIpyzKOvcF2u/29732vXq9LkrRcLlEgQHRZlqnfA3Bv7R/nsx6FMgGGOAqBxNbbdb7vFwoFxthwOAQk6vX6xcVFs9mUZRkQRYTARpiiAsNXV1cI8dVqxU3T3Nvb+8UvfgESuLq6QkWOiKG9W4wQkXShwK0mlayO1yAYaEfoVkIEgbiu6zjOdDrF9JdzXqvVVquVIAiGYdDZEpZrNkajEee80WgIghAEwWq14u12+/3334+iqNvtYr+o0+lgiIK3WpZVr9eXy+V4PK7X69l6ZprP3/lxAxRAMED/PLGivgKCsTVmmubZ2dmdO3cwlAfxLxYL13UZYxjQI+4VRSmVSnEc9/v9jY2Nm9MqkP6rr766uLg4Pj6ez+f5gzZJknQ6naurK9u27969i8IwzZ0LyjMvTVo554qiiLkxB4pCqqwoo69WK5wFOz8/bzabiBBMwaiShRriesLJOa/X65jOv/vuuzyO45OTk9PT06Ojo2KxWKlULMsC0S6Xy+l0apomkOq6brvdhvvyFQcFAJU6iFExt62LeRuBJ58Te71eq9VijL169apWq6EJRqGB5JCvvhhjOAHjuu79+/efPHnCh8Nhp9P5/PPPy+Vyq9Xa3d2lXd4gCGazGc6MMcYWi8Xp6amiKJVK5ZYCVKgBJGjG8RGTBQTDrYyORXDMrFwuM8YmkwlAyxhD04g9IbQvUN4wDBBPq9UqlUq81+sdHR1Vq9XHjx8/ePBgb28PpJllWRiGnU4Hc/2LiwtRFKfTabfb1TQty50aQqxTugVLQu58HsBsnbIBIRD9hqIouq47jhMEAfpJwzCyLEMjTy+CT9I0bTabgDTv9XppmtZqtcePH9+/f79Wq11dXWmaVi6Xx+MxDmykaYrxP+d8PB43m00xNy/I10Js3buQ3FSQkgJCrmvFDdpfqiaJ6NDxwfAIbkqgOzs7aCF4r9dzHOfw8PDRo0ec8z/84Q+z2axare7t7e3v749Go7t3745Go2az6bpuGIYYg9q2ne8BWK7cxz0EogTEchupxBCUBPM1CLRK1zt0qLXwL03TMDkWBKFSqRiG8fLlS75arVRVBe8eHR397W9/y7Ls3r17qqoipNI0LRaLOLSE12DsQXKTE2gbi+Qmt4jrAzHQgYIH5TrlDbYezyBh4UmCK/b8wGOO43DOV6vVTU+MTQfiR8yPSAiCRLo+/ELgoVEzFMCTtIMk5nZ5CUWEpWw9gMlyPTSlRfTZ8fooLDTJ9083rsMhSAT7e++9hxNsxWJxa2urWq3ioCgcR7NYMPStFoysCAVIaHqMXg8FsvWhLepD4C7yLVI4+g14gCoAalGKxSIvlUqTyaTb7Z6dne3t7f3qV78aDAaaplUqleFwmGXZxcXFbDa7urryPA/78qBqMXeYh4IBQgAVYq4tFtYtqLQe2GTruRMcm+amhcJ6PMPWgw88SXt5GH7V6/Vms8mr1Wqn0zk9Pb179y4ehb8Gg0Ecx91u9+XLl77v4wAKY6xUKpVKJUqWsBCZTfzmDpWY21xJkgSDWxzxsyxrc3Nze3sbZ6HyCmCpdH3Yh+4lSapWq8PhUNf1y8vL7373u6VSif/sZz8bj8cvXrz485//vFwuX716Va/XdV0PgmAymWACdXZ2NpvNsO9rmqaqqohjlI3CepNdWI9h8gSFiFwsFq9evbq4uBiNRsVi8f79+41Gw/O84XDY7XZROCJ7pLltJfbNw3OiKGKoGEXRcDjEpihHCkMd+s9//rNarVYqFexpY99uNBqhUHUcB6dh8/RHjM5y/SdVzvjX+fn5p59+en5+Ph6Pt7e39/f3h8Ph06dPXdc1DAOtBVIvzpmSD1luME6gRe+F3s0wjP8Dg15ZbtRjykkAAAAASUVORK5CYII=", "name": "directional_warp", "parameters": { "angle": 0.0, "strength": 0.1 }, - "icon": "transform_directional_warp", - "icon_data": "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", "tree_item": "Transform/Directional Warp", "type": "directional_warp" + }, + { + "display_name": "Controlled", + "generic_size": 1.0, + "icon_data": "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAMVJREFUeJzt2rENwzAQxdBLkCXtAe0xkyobWHiFyAE+CAJqDnrNzHc25q0FNAXQApoCaAFNAbSApgBaQFMALaApgBbQFEALaAqgBTQF0AKa7QN8Vowex7Fidu77fnxzSYCZmeu6Ht07z/PRvT/bP4ECaAFNAbSApgBaQFMALaApgBbQFEALaAqgBTQF0AKaAmgBzbKb4Kob3tO8pq+ye1MALaApgBbQFEALaAqgBTQF0AKaAmgBTQG0gKYAWkBTAC2g2T7AD/p7CZEtpDlJAAAAAElFTkSuQmCC", + "name": "controlled_variations_2", + "parameters": { + "v1": 0.5, + "variable": 0.0 + }, + "seed_int": 0.0, + "tree_item": "Miscellaneous/Variations/Controlled", + "type": "controlled_variations" + }, + { + "display_name": "Iterate", + "icon_data": "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAqJJREFUeJztmb+K8kAUxa9GkQSxCoqmskghKD6GhfoCVra2tjZ29naWlloJ4isEgmAnFhapxCKgYCQo+Ge7+eKibDZzM+O3zq+6o+Tc4yHXTJIIANzhg4nyNsAbEQBvA7wRAfA2wBsRAG8DvIm9+kKWZYhGcfO5Xq9wOp1QNWl5GQAAQCqVQm223+9R9TAQI8C0WSwGyWSSrI/HI8v2T/EdQC6XQ2283W7fIgAxAlybx/61v1wufDwEOUhVVZAkiapxJpMhtW3bMJ/PqfSCEvgMwN4j8OJv/AoKUP4DvLMcBE3TQNM0sp5MJrSWfIMSQDqdxpABAPZ7AzECvA08o1arkdowDNjtdqH1Qg8gm82i6hmGgar3HTECvA38RKlUIrXjOLBYLFD1Qw0A4waq0WiQejAYUOt9R4wAbwO/pVAokHq1WlHrMQsA4+rQ7XZJPRqNwg3gdruR668kSegPRN6FlwGcz2dSK4rCxMxv8fpyXTeQRgR8vB5XFOVh9lRVhXg8Ttbes8N7qr/6XFEUkGU5kOFnmKYJ7XY70LG+/wM2mw2pVVUN1MxLIpGg1sDAVwCu6z6cYuVyOTRDrPnvLoPP0HUdptMpWdfrdd/HBgrAtm1SY1zeaDW8x3tH1Q+BAvDux6vVahCJt0FshTFEvC89sZ8HhA11ALPZjNSVSoVWjjkfPwIfHwDqPsAwDPIMr1gsQrPZxJQPBdQAHMfBlGOCGIGwhA+HA/T7fbLu9XphtaIitACWyyWp8/l8WG2oESPAqtFwOCR1q9Vi1fZHmARgWRZYlgUAAJFI5K0CECPAo6lpmqTWdZ3rDRTzAO73O3Q6HbIej8esLTwgRoC3AQCA9XrNrbev9wJ/mY8fAREAbwO8EQHwNsAbEQBvA7z5+AC+AIRYlV6uwUK/AAAAAElFTkSuQmCC", + "name": "iterate_variations_2", + "parameters": { + "combine": 1.0, + "randomize": false, + "step": 0.1, + "v1": 0.0, + "v2": 1.0, + "variable": 0.0 + }, + "seed_int": 0.0, + "tree_item": "Miscellaneous/Variations/Iterate", + "type": "iterate_variations" + }, + { + "display_name": "Layer", + "icon_data": "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAA4NJREFUeJztmt2V4yAMheU924SZMpw2nDJcVHpyG1CG94k5DJHQDyJMzua+TcbG3A8hZPACABf8x/ozuwOz9QEwuwOz9QEwuwOz9dejkeuas5Asy9LdxvAIiDGOfkSXFuisA7jRbwEIIfQ8GgD6o6ALQI/5lrRgeiAMA8CZTykBAMC6rqpnYnCmAPAwX0sLo9TX15fpPncAVvO1LDAsEEzL4Gjz9bU9kcHJFAEWABLz+f5WEuRgaKNADWC0+VLcaoDBGApghHnJUildFjMQDYTuUpgyYB311nUcCE2OyRIDwEbfat5aIElBXNclrg3c3wU8zaeU0PZijM12zvMUP0OUA6Sj3zIvNW4pkrCI2LZNFAWmHKAx32u8/j8GQjo1MLERUI++t3lL4uJqgRACrOsKIQQ2CpoArOZHGS8lgbBtGwC0X5a6lkGt+V7TWFsUiBjjdxS0RALgRl9j3mpcUh2mlNhoaC2LogiQmKekuVYydWKMKAQA20sTWgeUo491yuvtLK/n3LqO3YepFZVUGf8EYPQOr8Uw1Q6mEkINBPP21ucC0khowf4BACPUs3PrmfUpaSOp9uhyMCKVxxJJVYLWgTJPAY9EmF92PFYVLhKo/4sAeBxgeEoDgYP7A4DHWdtscZFQe3zZKtBTTGGy3I/BeUqCy7KQq8HIg06ubWwaSspgTmgESKeC9eGadZq7pm6LAgWAb5aqpsCIZOhRAtfSDAwJoDchliNTdnxEcSRpk9oqn1oKW3KKdx5qAsCioDUNevbtLUWR9Pm32428h40AbipYEyFXFreA1Pe2+tAyD2CcAtZkmDvqXRNQkkwXEQBLQixHpQZW/u25XVbrfr+z1wxNghiE8jepeey6ur0S6r7vIvMACgB1FJQPbI32uq5PncR2az2zuyZiu47HufWdmuv59/M8IaX0dB2WY7hoCiHAcRwAoAOg2hCh3hMo5Y5mg2WH8yaG5iCzbLPUcRzfv2vzlXpHqIRQviBlc635ioGQCLs+/5ZHPfdNK/ctsVaSK0FIIVD5Zd93NAFq5fKZnPUssMwFj8cDAOjkmkeayv7Wd5eXASiFvQ6XuQCDwP32cgAAus9mKJUwSghU6HuaBxj8sXQt6YeU1AcPFJRpAAB8jtK43dw6YXqZB3AAADDuPJE7HvfYxf7VADj9GgDvrLc+HfbQB8DsDszWB8DsDszWP8r9grAlvpVDAAAAAElFTkSuQmCC", + "name": "layer_variations", + "parameters": { + "randomize": false, + "step": 0.1, + "v1": 0.0, + "v2": 1.0, + "variable": 0.0 + }, + "seed_int": 0.0, + "tree_item": "Miscellaneous/Variations/Layer", + "type": "layer_variations" + }, + { + "display_name": "Layer Color", + "icon_data": "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", + "name": "layer_variations_color", + "parameters": { + "randomize": false, + "step": 0.1, + "v1": 0.0, + "v2": 1.0, + "variable": 0.0 + }, + "seed_int": 0.0, + "tree_item": "Miscellaneous/Variations/Layer Color", + "type": "layer_variations_color" } ], "name": "Base library" -} +} \ No newline at end of file From 16c215ceabacb2f69bfd8ef73da38aed25e82df0 Mon Sep 17 00:00:00 2001 From: Rodz Labs Date: Sun, 8 Mar 2026 18:19:06 +0100 Subject: [PATCH 11/11] Added doc for controlled variations nodes --- ...de_miscellaneous_variations_controlled.png | Bin 0 -> 10302 bytes .../node_miscellaneous_variations_iterate.png | Bin 0 -> 15846 bytes .../node_miscellaneous_variations_layer.png | Bin 0 -> 13544 bytes ...e_miscellaneous_variations_layer_color.png | Bin 0 -> 13560 bytes .../doc/node_miscellaneous_variations.rst | 1 + ...de_miscellaneous_variations_controlled.rst | 36 ++++++++++++++ .../node_miscellaneous_variations_iterate.rst | 45 ++++++++++++++++++ .../node_miscellaneous_variations_layer.rst | 44 +++++++++++++++++ ...e_miscellaneous_variations_layer_color.rst | 44 +++++++++++++++++ material_maker/doc/nodes_miscellaneous.rst | 4 ++ 10 files changed, 174 insertions(+) create mode 100644 material_maker/doc/images/node_miscellaneous_variations_controlled.png create mode 100644 material_maker/doc/images/node_miscellaneous_variations_iterate.png create mode 100644 material_maker/doc/images/node_miscellaneous_variations_layer.png create mode 100644 material_maker/doc/images/node_miscellaneous_variations_layer_color.png create mode 100644 material_maker/doc/node_miscellaneous_variations_controlled.rst create mode 100644 material_maker/doc/node_miscellaneous_variations_iterate.rst create mode 100644 material_maker/doc/node_miscellaneous_variations_layer.rst create mode 100644 material_maker/doc/node_miscellaneous_variations_layer_color.rst diff --git a/material_maker/doc/images/node_miscellaneous_variations_controlled.png b/material_maker/doc/images/node_miscellaneous_variations_controlled.png new file mode 100644 index 0000000000000000000000000000000000000000..15bcf7d9158562839b5e3fa5e8eda5c05404f17e GIT binary patch literal 10302 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 literal 0 HcmV?d00001 diff --git a/material_maker/doc/images/node_miscellaneous_variations_iterate.png b/material_maker/doc/images/node_miscellaneous_variations_iterate.png new file mode 100644 index 0000000000000000000000000000000000000000..281edf6863fe5a952d8298b577984a4cb25ee360 GIT binary patch literal 15846 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

tCL< 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 literal 0 HcmV?d00001 diff --git a/material_maker/doc/images/node_miscellaneous_variations_layer.png b/material_maker/doc/images/node_miscellaneous_variations_layer.png new file mode 100644 index 0000000000000000000000000000000000000000..d052d3966b1d445f92f20d64f24e6ad6ade2501a GIT binary patch literal 13544 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 BornMc literal 0 HcmV?d00001 diff --git a/material_maker/doc/images/node_miscellaneous_variations_layer_color.png b/material_maker/doc/images/node_miscellaneous_variations_layer_color.png new file mode 100644 index 0000000000000000000000000000000000000000..9bab5a33f099c210584146b6d1fe92af1ed98135 GIT binary patch literal 13560 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 literal 0 HcmV?d00001 diff --git a/material_maker/doc/node_miscellaneous_variations.rst b/material_maker/doc/node_miscellaneous_variations.rst index 2aef8a677..d94a794f9 100644 --- a/material_maker/doc/node_miscellaneous_variations.rst +++ b/material_maker/doc/node_miscellaneous_variations.rst @@ -2,6 +2,7 @@ Variations node ~~~~~~~~~~~~~~~ The **Variations** node can be used to generate several variations of its input. +Variations differ by the seeds used for all random aspects of the input. .. image:: images/node_miscellaneous_variations.png :align: center diff --git a/material_maker/doc/node_miscellaneous_variations_controlled.rst b/material_maker/doc/node_miscellaneous_variations_controlled.rst new file mode 100644 index 000000000..eb49e0ce5 --- /dev/null +++ b/material_maker/doc/node_miscellaneous_variations_controlled.rst @@ -0,0 +1,36 @@ +Controlled Variations node +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The **Controlled Variations** node can be used to generate several variations of its input. +Variations differ by the value of a variable (defined in the **Variable** parameter), +that can be used in parameter expressions of the input. + +.. image:: images/node_miscellaneous_variations_controlled.png + :align: center + +Inputs +++++++ + +The **Controlled Variations** node has a single input whose variations will be generated. + +Outputs ++++++++ + +The **Controlled Variations** node is variadic and can several outputs that generate different variations. + +Parameters +++++++++++ + +The **Controlled Variations** node accepts the following parameters: + +* the *Value* selected for the variable for each output + +* the *Variable* that is controlled by the node (**$?1**, **$?2**, **$?3** or **$?4**) + +Note +++++ + +To generate variations, the **Controlled Variations** node sets different values of the variations +variable. + +The whole incoming branch is affected, until a buffer, text or image node is reached. diff --git a/material_maker/doc/node_miscellaneous_variations_iterate.rst b/material_maker/doc/node_miscellaneous_variations_iterate.rst new file mode 100644 index 000000000..d1cb03650 --- /dev/null +++ b/material_maker/doc/node_miscellaneous_variations_iterate.rst @@ -0,0 +1,45 @@ +Iterate Variations node +~~~~~~~~~~~~~~~~~~~~~~~ + +The **Iterate Variations** node can be used to combine several variations of its input. +Variations differ by the value of a variable (defined in the **Variable** parameter), +that can is modified automatically according to the **From**, **To** and **Step** +parameters. + +.. image:: images/node_miscellaneous_variations_iterate.png + :align: center + +Inputs +++++++ + +The **Iterate Variations** node has a single grayscale input whose variations will be generated and combined. + +Outputs ++++++++ + +The **Iterate Variations** node has a single grayscale output that shows the combined variations. + +Parameters +++++++++++ + +The **Iterate Variations** node accepts the following parameters: + +* *From*, the initial value of the variable + +* *To*, the maximum value of the variable + +* the *Step* used to loop through all values + +* *Combine*, the operator used to combine variations (**Add**, **Min**, **Max** or **Average**) + +* the *Variable* that is controlled by the node (**$?1**, **$?2**, **$?3** or **$?4**) + +* the *Randomize* option, that sets different seeds for different variations + +Note +++++ + +To generate variations, the **Iterate Variations** node sets different values of the variations +variable. + +The whole incoming branch is affected, until a buffer, text or image node is reached. diff --git a/material_maker/doc/node_miscellaneous_variations_layer.rst b/material_maker/doc/node_miscellaneous_variations_layer.rst new file mode 100644 index 000000000..b8205ca7c --- /dev/null +++ b/material_maker/doc/node_miscellaneous_variations_layer.rst @@ -0,0 +1,44 @@ +Layer Variations node +~~~~~~~~~~~~~~~~~~~~~ + +The **Layer Variations** node can be used to layer several variations of its input. +Variations differ by the value of a variable (defined in the **Variable** parameter), +that can is modified automatically according to the **From**, **To** and **Step** +parameters. + +.. image:: images/node_miscellaneous_variations_layer.png + :align: center + +Inputs +++++++ + +The **Layer Variations** node has a grayscale input whose variations will be generated +and stacked, and a mask input that is applied to each layer. + +Outputs ++++++++ + +The **Layer Variations** node has a single grayscale output that shows the layered variations. + +Parameters +++++++++++ + +The **Layer Variations** node accepts the following parameters: + +* *From*, the initial value of the variable + +* *To*, the maximum value of the variable + +* the *Step* used to loop through all values + +* the *Variable* that is controlled by the node (**$?1**, **$?2**, **$?3** or **$?4**) + +* the *Randomize* option, that sets different seeds for different variations + +Note +++++ + +To generate variations, the **Layer Variations** node sets different values of the variations +variable. + +The whole incoming branch is affected, until a buffer, text or image node is reached. diff --git a/material_maker/doc/node_miscellaneous_variations_layer_color.rst b/material_maker/doc/node_miscellaneous_variations_layer_color.rst new file mode 100644 index 000000000..b36d5daea --- /dev/null +++ b/material_maker/doc/node_miscellaneous_variations_layer_color.rst @@ -0,0 +1,44 @@ +Color Layer Variations node +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The **Color Layer Variations** node can be used to layer several variations of its input. +Variations differ by the value of a variable (defined in the **Variable** parameter), +that can is modified automatically according to the **From**, **To** and **Step** +parameters. + +.. image:: images/node_miscellaneous_variations_layer_color.png + :align: center + +Inputs +++++++ + +The **Color Layer Variations** node has a grayscale input whose variations will be generated +and stacked, and a mask input that is applied to each layer. + +Outputs ++++++++ + +The **Color Layer Variations** node has a single grayscale output that shows the layered variations. + +Parameters +++++++++++ + +The **Color Layer Variations** node accepts the following parameters: + +* *From*, the initial value of the variable + +* *To*, the maximum value of the variable + +* the *Step* used to loop through all values + +* the *Variable* that is controlled by the node (**$?1**, **$?2**, **$?3** or **$?4**) + +* the *Randomize* option, that sets different seeds for different variations + +Note +++++ + +To generate variations, the **Color Layer Variations** node sets different values of the variations +variable. + +The whole incoming branch is affected, until a buffer, text or image node is reached. diff --git a/material_maker/doc/nodes_miscellaneous.rst b/material_maker/doc/nodes_miscellaneous.rst index 085720543..40b19a3f5 100644 --- a/material_maker/doc/nodes_miscellaneous.rst +++ b/material_maker/doc/nodes_miscellaneous.rst @@ -15,6 +15,10 @@ Miscellaneous nodes node_miscellaneous_export node_miscellaneous_debug node_miscellaneous_variations + node_miscellaneous_variations_controlled + node_miscellaneous_variations_iterate + node_miscellaneous_variations_layer + node_miscellaneous_variations_layer_color node_miscellaneous_randomize node_miscellaneous_mesh_map node_miscellaneous_mesh_triplanar