diff --git a/addons/material_maker/graph_edit.gd b/addons/material_maker/graph_edit.gd
index 22b2501..eab0249 100644
--- a/addons/material_maker/graph_edit.gd
+++ b/addons/material_maker/graph_edit.gd
@@ -116,9 +116,15 @@ func create_nodes(data, position = null):
if data == null:
return
if data.has("type"):
- var node_type = load("res://addons/material_maker/nodes/"+data.type+"/"+data.type+".tscn")
- if node_type != null:
- var node = node_type.instance()
+ var node = null
+ if File.new().file_exists("res://addons/material_maker/nodes/"+data.type+".json"):
+ node = preload("res://addons/material_maker/nodes/node_generic.gd").new()
+ node.model = data.type
+ else:
+ var node_type = load("res://addons/material_maker/nodes/"+data.type+"/"+data.type+".tscn")
+ if node_type != null:
+ node = node_type.instance()
+ if node != null:
if data.has("name") && !has_node(data.name):
node.name = data.name
else:
diff --git a/addons/material_maker/graph_edit.tscn b/addons/material_maker/graph_edit.tscn
index 1f756ee..3d9f9ed 100644
--- a/addons/material_maker/graph_edit.tscn
+++ b/addons/material_maker/graph_edit.tscn
@@ -3,11 +3,10 @@
[ext_resource path="res://addons/material_maker/graph_edit.gd" type="Script" id=1]
[ext_resource path="res://addons/material_maker/nodes/material/material.tscn" type="PackedScene" id=2]
-
[sub_resource type="Theme" id=1]
-[node name="GraphEdit" type="GraphEdit"]
+[node name="GraphEdit" type="GraphEdit" index="0"]
self_modulate = Color( 1, 1, 1, 0 )
anchor_left = 0.0
@@ -22,7 +21,7 @@ mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
right_disconnects = true
-scroll_offset = Vector2( -525, -250 )
+scroll_offset = Vector2( -458.75, -292.25 )
snap_distance = 20
use_snap = false
zoom = 1.0
@@ -31,11 +30,12 @@ _sections_unfolded = [ "Material", "Mouse", "Visibility" ]
[node name="Material" parent="." index="0" instance=ExtResource( 2 )]
-margin_left = 525.0
-margin_top = 250.0
-margin_right = 755.0
-margin_bottom = 470.0
+margin_left = 658.75
+margin_top = 292.25
+margin_right = 888.75
+margin_bottom = 512.25
theme = SubResource( 1 )
+offset = Vector2( 200, 0 )
_sections_unfolded = [ "Anchor", "Margin", "Mouse", "Theme", "slot", "slot/0", "slot/1", "slot/2", "slot/3", "slot/4", "slot/5" ]
[node name="Timer" type="Timer" parent="." index="1"]
diff --git a/addons/material_maker/icons/edit.png b/addons/material_maker/icons/edit.png
new file mode 100644
index 0000000..4e76bbc
Binary files /dev/null and b/addons/material_maker/icons/edit.png differ
diff --git a/addons/material_maker/icons/icons.svg b/addons/material_maker/icons/icons.svg
index 4a56982..54563e2 100644
--- a/addons/material_maker/icons/icons.svg
+++ b/addons/material_maker/icons/icons.svg
@@ -7,6 +7,7 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
@@ -17,7 +18,29 @@
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="icons.svg">
+ id="defs2">
+
+
+
+
+
+
image/svg+xml
-
+
@@ -117,5 +140,70 @@
d="m 23.783078,44.110649 -4.508983,4.648736 -3.980261,-5.27284 a 12.770835,12.770835 0 0 0 -2.631282,1.045173 l 0.825522,6.441784 -6.571368,-0.17469 a 12.770835,12.770835 0 0 0 -0.7896172,2.557631 12.770835,12.770835 0 0 0 -0.027504,0.173796 l 5.5120272,3.347264 -4.1861363,4.972095 a 12.770835,12.770835 0 0 0 1.6563998,2.37002 l 5.9760855,-2.194035 1.267643,6.324612 a 12.770835,12.770835 0 0 0 2.907828,0.192046 l 1.997862,-6.001057 5.727797,2.948399 a 12.770835,12.770835 0 0 0 1.98019,-2.135962 l -3.455675,-5.317616 5.926699,-2.662342 a 12.770835,12.770835 0 0 0 -0.414249,-2.850168 l -6.383635,-0.620945 1.631047,-6.361785 a 12.770835,12.770835 0 0 0 -2.46039,-1.430116 z m -4.472442,8.529047 a 3.1927084,3.1927084 0 0 1 2.523332,3.744269 3.1927084,3.1927084 0 0 1 -3.744267,2.523336 3.1927084,3.1927084 0 0 1 -2.523335,-3.744269 3.1927084,3.1927084 0 0 1 3.74427,-2.523336 z"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.80446196;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke" />
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/material_maker/icons/save.png b/addons/material_maker/icons/save.png
new file mode 100644
index 0000000..c2e227e
Binary files /dev/null and b/addons/material_maker/icons/save.png differ
diff --git a/addons/material_maker/main_window.tscn b/addons/material_maker/main_window.tscn
index 5ae8cf6..c488d39 100644
--- a/addons/material_maker/main_window.tscn
+++ b/addons/material_maker/main_window.tscn
@@ -241,7 +241,6 @@ size_flags_horizontal = 3
size_flags_vertical = 3
size_flags_stretch_ratio = 3.0
script = ExtResource( 4 )
-_sections_unfolded = [ "custom_styles" ]
[node name="Tabs" type="Tabs" parent="VBoxContainer/HBoxContainer/Projects" index="1"]
diff --git a/addons/material_maker/node_base.gd b/addons/material_maker/node_base.gd
index 77b5683..c208980 100644
--- a/addons/material_maker/node_base.gd
+++ b/addons/material_maker/node_base.gd
@@ -18,6 +18,7 @@ class OutPort:
var generated = false
var generated_variants = []
+var parameters = {}
var property_widgets = []
const Types = preload("res://addons/material_maker/types/types.gd")
@@ -31,25 +32,25 @@ func initialize_properties(object_list):
if o == null:
print("error in node "+name)
elif o is LineEdit:
- set(o.name, float(o.text))
+ parameters[o.name] = float(o.text)
o.connect("text_changed", self, "_on_text_changed", [ o.name ])
elif o is SpinBox:
- set(o.name, o.value)
+ parameters[o.name] = o.value
o.connect("value_changed", self, "_on_value_changed", [ o.name ])
elif o is HSlider:
- set(o.name, o.value)
+ parameters[o.name] = o.value
o.connect("value_changed", self, "_on_value_changed", [ o.name ])
elif o is OptionButton:
- set(o.name, o.selected)
+ parameters[o.name] = o.selected
o.connect("item_selected", self, "_on_value_changed", [ o.name ])
elif o is CheckBox:
- set(o.name, o.pressed)
+ parameters[o.name] = o.pressed
o.connect("toggled", self, "_on_value_changed", [ o.name ])
elif o is ColorPickerButton:
- set(o.name, o.color)
+ parameters[o.name] = o.color
o.connect("color_changed", self, "_on_color_changed", [ o.name ])
elif o is Control and o.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
- set(o.name, o.value)
+ parameters[o.name] = o.value
o.connect("updated", self, "_on_gradient_changed", [ o.name ])
else:
print("unsupported widget "+str(o))
@@ -59,40 +60,41 @@ func get_seed():
func update_property_widgets():
for o in property_widgets:
- if o is LineEdit:
- o.text = str(get(o.name))
- elif o is SpinBox:
- o.value = get(o.name)
- elif o is HSlider:
- o.value = get(o.name)
- elif o is OptionButton:
- o.selected = get(o.name)
- elif o is CheckBox:
- o.pressed = get(o.name)
- elif o is ColorPickerButton:
- o.color = get(o.name)
- elif o is Control and o.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
- o.value = get(o.name)
- else:
- print("Failed to update "+o.name)
+ if parameters.has(o.name) and parameters[o.name] != null:
+ if o is LineEdit:
+ o.text = str(parameters[o.name])
+ elif o is SpinBox:
+ o.value = parameters[o.name]
+ elif o is HSlider:
+ o.value = parameters[o.name]
+ elif o is OptionButton:
+ o.selected = parameters[o.name]
+ elif o is CheckBox:
+ o.pressed = parameters[o.name]
+ elif o is ColorPickerButton:
+ o.color = parameters[o.name]
+ elif o is Control and o.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
+ o.value = parameters[o.name]
+ else:
+ print("Failed to update "+o.name)
func update_shaders():
get_parent().send_changed_signal()
func _on_text_changed(new_text, variable):
- set(variable, float(new_text))
+ parameters[variable] = float(new_text)
update_shaders()
func _on_value_changed(new_value, variable):
- set(variable, new_value)
+ parameters[variable] = new_value
update_shaders()
func _on_color_changed(new_color, variable):
- set(variable, new_color)
+ parameters[variable] = new_color
update_shaders()
func _on_gradient_changed(new_gradient, variable):
- set(variable, new_gradient)
+ parameters[variable] = new_gradient
update_shaders()
func get_source(index = 0):
@@ -187,8 +189,8 @@ func serialize():
type = type.left(type.find_last("."))
var data = { name=name, type=type, node_position={x=offset.x, y=offset.y} }
for w in property_widgets:
- var v = w.name
- data[v] = Types.serialize_value(get(v)) # serialize_element(get(v))
+ var variable = w.name
+ data[variable] = Types.serialize_value(parameters[variable]) # serialize_element(get(v))
return data
func deserialize(data):
@@ -198,7 +200,7 @@ func deserialize(data):
var variable = w.name
if data.has(variable):
var value = Types.deserialize_value(data[variable]) #deserialize_element(data[variable])
- set(variable, value)
+ parameters[variable] = value
update_property_widgets()
# Render targets again for multipass filters
diff --git a/addons/material_maker/nodes/adjust_hsv/adjust_hsv.gd b/addons/material_maker/nodes/adjust_hsv/adjust_hsv.gd
index 40af204..714c314 100644
--- a/addons/material_maker/nodes/adjust_hsv/adjust_hsv.gd
+++ b/addons/material_maker/nodes/adjust_hsv/adjust_hsv.gd
@@ -1,10 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var hue
-var saturation
-var value
-
func _ready():
initialize_properties([ $HBoxContainer1/hue, $HBoxContainer2/saturation, $HBoxContainer3/value ])
@@ -17,7 +13,7 @@ func _get_shader_code(uv, output = 0):
src_code = src.get_shader_code(uv)
if generated_variants.empty():
rv.defs = src_code.defs;
- rv.defs += "vec3 %s_rgb(vec3 c) { vec3 hsv = rgb2hsv(c); return hsv2rgb(vec3(fract(hsv.x+%.9f), clamp(hsv.y*%.9f, 0.0, 1.0), clamp(hsv.z*%.9f, 0.0, 1.0))); }\n" % [ name, hue, saturation, value ]
+ rv.defs += "vec3 %s_rgb(vec3 c) { vec3 hsv = rgb2hsv(c); return hsv2rgb(vec3(fract(hsv.x+%.9f), clamp(hsv.y*%.9f, 0.0, 1.0), clamp(hsv.z*%.9f, 0.0, 1.0))); }\n" % [ name, parameters.hue, parameters.saturation, parameters.value ]
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
diff --git a/addons/material_maker/nodes/adjust_hsv/adjust_hsv.tscn b/addons/material_maker/nodes/adjust_hsv/adjust_hsv.tscn
index ba4aa02..42905b5 100644
--- a/addons/material_maker/nodes/adjust_hsv/adjust_hsv.tscn
+++ b/addons/material_maker/nodes/adjust_hsv/adjust_hsv.tscn
@@ -2,7 +2,6 @@
[ext_resource path="res://addons/material_maker/nodes/adjust_hsv/adjust_hsv.gd" type="Script" id=1]
-
[sub_resource type="Theme" id=1]
diff --git a/addons/material_maker/nodes/blend/blend.gd b/addons/material_maker/nodes/blend/blend.gd
index abd45d3..32695c7 100644
--- a/addons/material_maker/nodes/blend/blend.gd
+++ b/addons/material_maker/nodes/blend/blend.gd
@@ -1,9 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var blend_type = 0
-var amount = 0.0
-
const BLEND_TYPES = [
{ name="Normal", shortname="normal" },
{ name="Dissolve", shortname="dissolve" },
@@ -35,7 +32,7 @@ func _get_shader_code(uv):
var src0_code = src0.get_shader_code(uv)
var src1_code = src1.get_shader_code(uv)
var src2_code = { defs="", code="" }
- var amount_str = "%.9f" % amount
+ var amount_str = "%.9f" % parameters.amount
if src2 != null:
src2_code = src2.get_shader_code(uv)
amount_str = src2_code.f
@@ -46,7 +43,7 @@ func _get_shader_code(uv):
variant_index = generated_variants.size()
generated_variants.append(uv)
rv.code = src0_code.code+src1_code.code+src2_code.code
- rv.code += "vec3 %s_%d_rgb = blend_%s(%s, %s, %s, %s);\n" % [ name, variant_index, BLEND_TYPES[blend_type].shortname, uv, src0_code.rgb, src1_code.rgb, amount_str ]
+ rv.code += "vec3 %s_%d_rgb = blend_%s(%s, %s, %s, %s);\n" % [ name, variant_index, BLEND_TYPES[parameters.blend_type].shortname, uv, src0_code.rgb, src1_code.rgb, amount_str ]
rv.rgb = "%s_%d_rgb" % [ name, variant_index ]
return rv
diff --git a/addons/material_maker/nodes/blur/blur.gd b/addons/material_maker/nodes/blur/blur.gd
index 11bb9e7..9651693 100644
--- a/addons/material_maker/nodes/blur/blur.gd
+++ b/addons/material_maker/nodes/blur/blur.gd
@@ -1,10 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var size = 5
-var direction = 0
-var sigma = 1.0
-
var input_shader = ""
var saved_texture
@@ -21,17 +17,17 @@ func _ready():
$HBoxContainer1/size.clear()
for i in range(7):
$HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i)
- $HBoxContainer1/size.selected = size
+ $HBoxContainer1/size.selected = 5
# init direction widget
$HBoxContainer2/direction.clear()
for d in DIRECTIONS:
$HBoxContainer2/direction.add_item(d.name)
- $HBoxContainer2/direction.selected = direction
+ $HBoxContainer2/direction.selected = 0
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/direction, $HBoxContainer3/sigma ])
saved_texture = ImageTexture.new()
func get_gaussian_blur_shader(horizontal):
- var convolution = { x=0, y=0, kernel=[], epsilon=1.0/pow(2, 5+size) }
+ var convolution = { x=0, y=0, kernel=[], epsilon=1.0/pow(2, 5+parameters.size) }
var kernel_size = 50
if horizontal:
convolution.x = kernel_size
@@ -40,7 +36,7 @@ func get_gaussian_blur_shader(horizontal):
convolution.kernel.resize(2*kernel_size+1)
var sum = 0
for x in range(-kernel_size, kernel_size+1):
- var coef = exp(-0.5*(pow((x)/sigma, 2.0))) / (2.0*PI*sigma*sigma)
+ var coef = exp(-0.5*(pow((x)/parameters.sigma, 2.0))) / (2.0*PI*parameters.sigma*parameters.sigma)
convolution.kernel[x+kernel_size] = coef
sum += coef
for x in range(-kernel_size, kernel_size+1):
@@ -48,20 +44,19 @@ func get_gaussian_blur_shader(horizontal):
return get_convolution_shader(convolution)
func _rerender():
- if DIRECTIONS[direction].mask & DIRECTION_H != 0:
- get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+size)), saved_texture, self, "pass_1", [])
+ if DIRECTIONS[parameters.direction].mask & DIRECTION_H != 0:
+ get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), saved_texture, self, "pass_1", [])
else:
- get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+size)), saved_texture, self, "pass_2", [])
+ get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), saved_texture, self, "pass_2", [])
func pass_1():
- if DIRECTIONS[direction].mask & DIRECTION_V != 0:
- get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+size)), saved_texture, self, "pass_2", [])
+ if DIRECTIONS[parameters.direction].mask & DIRECTION_V != 0:
+ get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "pass_2", [])
else:
- get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+size)), saved_texture, self, "rerender_targets", [])
-
+ get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "rerender_targets", [])
func pass_2():
- get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(false), { input=saved_texture }, int(pow(2, 5+size)), saved_texture, self, "rerender_targets", [])
+ get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(false), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "rerender_targets", [])
func get_textures():
var list = {}
diff --git a/addons/material_maker/nodes/bricks.json b/addons/material_maker/nodes/bricks.json
new file mode 100644
index 0000000..7893471
--- /dev/null
+++ b/addons/material_maker/nodes/bricks.json
@@ -0,0 +1,122 @@
+{
+ "name":"Bricks",
+ "parameters":[
+ { "name":"pattern", "label":"", "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" }
+ ] },
+ { "name":"repeat", "label":"Repeat:", "type":"float", "min":1, "max":8, "step":1, "default":1, "widget":"spinbox" },
+ { "name":"rows", "label":"Rows:", "type":"float", "min":1, "max":64, "step":1, "default":6, "widget":"spinbox" },
+ { "name":"columns", "label":"Columns:", "type":"float", "min":1, "max":64, "step":1, "default":3, "widget":"spinbox" },
+ { "name":"row_offset", "label":"Offset:", "type":"float", "min":0, "max":1, "default":0.5 },
+ { "name":"mortar", "label":"Mortar:", "type":"float", "min":0, "max":0.5, "default":0.1 },
+ { "name":"bevel", "label":"Bevel:", "type":"float", "min":0, "max":0.5, "default":0.1 }
+ ],
+ "include":[ "noise" ],
+ "global":"
+ vec3 brick(vec2 uv, vec2 bmin, vec2 bmax, float mortar, float bevel) {
+ float color = 0.5;
+ vec2 c1 = (uv-bmin-vec2(mortar))/bevel;
+ vec2 c2 = (bmax-uv-vec2(mortar))/bevel;
+ vec2 c = min(c1, c2);
+ color = clamp(min(c.x, c.y), 0.0, 1.0);
+ return vec3(color, mod(bmin, vec2(1.0, 1.0)));
+ }
+
+ vec3 bricks_rb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
+ count *= repeat;
+ mortar /= max(count.x, count.y);
+ bevel /= max(count.x, count.y);
+ float x_offset = offset*step(0.5, fract(uv.y*count.y*0.5));
+ vec2 bmin = floor(vec2(uv.x*count.x-x_offset, uv.y*count.y));
+ bmin.x += x_offset;
+ bmin /= count;
+ return brick(uv, bmin, bmin+vec2(1.0)/count, mortar, bevel);
+ }
+
+ vec3 bricks_rb2(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
+ count *= repeat;
+ mortar /= max(2.0*count.x, count.y);
+ bevel /= max(2.0*count.x, count.y);
+ float x_offset = offset*step(0.5, fract(uv.y*count.y*0.5));
+ count.x = count.x*(1.0+step(0.5, fract(uv.y*count.y*0.5)));
+ vec2 bmin = floor(vec2(uv.x*count.x-x_offset, uv.y*count.y));
+ bmin.x += x_offset;
+ bmin /= count;
+ return brick(uv, bmin, bmin+vec2(1.0)/count, mortar, bevel);
+ }
+
+ vec3 bricks_hb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
+ float pc = count.x+count.y;
+ float c = pc*repeat;
+ mortar /= c;
+ bevel /= c;
+ vec2 corner = floor(uv*c);
+ float cdiff = mod(corner.x-corner.y, pc);
+ if (cdiff < count.x) {
+ return brick(uv, (corner-vec2(cdiff, 0.0))/c, (corner-vec2(cdiff, 0.0)+vec2(count.x, 1.0))/c, mortar, bevel);
+ } else {
+ return 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);
+ }
+ }
+
+ vec3 bricks_bw(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
+ vec2 c = 2.0*count*repeat;
+ float mc = max(c.x, c.y);
+ mortar /= mc;
+ bevel /= mc;
+ vec2 corner1 = floor(uv*c);
+ vec2 corner2 = count*floor(repeat*2.0*uv);
+ float cdiff = mod(dot(floor(repeat*2.0*uv), vec2(1.0)), 2.0);
+ vec2 corner;
+ vec2 size;
+ if (cdiff == 0.0) {
+ corner = vec2(corner1.x, corner2.y);
+ size = vec2(1.0, count.y);
+ } else {
+ corner = vec2(corner2.x, corner1.y);
+ size = vec2(count.x, 1.0);
+ }
+ return brick(uv, corner/c, (corner+size)/c, mortar, bevel);
+ }
+
+ vec3 bricks_sb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
+ vec2 c = (count+vec2(1.0))*repeat;
+ float mc = max(c.x, c.y);
+ mortar /= mc;
+ bevel /= mc;
+ vec2 corner1 = floor(uv*c);
+ vec2 corner2 = (count+vec2(1.0))*floor(repeat*uv);
+ vec2 rcorner = corner1 - corner2;
+ vec2 corner;
+ vec2 size;
+ if (rcorner.x == 0.0 && rcorner.y < count.y) {
+ corner = corner2;
+ size = vec2(1.0, count.y);
+ } else if (rcorner.y == 0.0) {
+ corner = corner2+vec2(1.0, 0.0);
+ size = vec2(count.x, 1.0);
+ } else if (rcorner.x == count.x) {
+ corner = corner2+vec2(count.x, 1.0);
+ size = vec2(1.0, count.y);
+ } else if (rcorner.y == count.y) {
+ corner = corner2+vec2(0.0, count.y);
+ size = vec2(count.x, 1.0);
+ } else {
+ corner = corner2+vec2(1.0);
+ size = vec2(count.x-1.0, count.y-1.0);
+ }
+ return brick(uv, corner/c, (corner+size)/c, mortar, bevel);
+ }",
+ "instance":"
+ vec3 $(name)_xyz(vec2 uv) {
+ return bricks_$(pattern)(uv, vec2($(columns), $(rows)), $(repeat), $(row_offset), $(mortar), max(0.001, $(bevel)));
+ }",
+ "outputs":[
+ { "f":"$(name)_xyz($(uv)).x" },
+ { "rgb":"rand3($(name)_xyz($(uv)).yz+vec2($(seed)))" }
+ ]
+}
\ No newline at end of file
diff --git a/addons/material_maker/nodes/bricks/bricks.gd b/addons/material_maker/nodes/bricks/bricks.gd
index d207f3c..b8a7b06 100644
--- a/addons/material_maker/nodes/bricks/bricks.gd
+++ b/addons/material_maker/nodes/bricks/bricks.gd
@@ -1,14 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var pattern = 0
-var repeat
-var rows
-var columns
-var row_offset
-var mortar
-var bevel
-
const BRICK_PATTERNS = [
{ name="Running bond", suffix="rb", has_offset=true, has_repeat=false },
{ name="Running bond (2)", suffix="rb2", has_offset=true, has_repeat=false },
@@ -26,7 +18,7 @@ func _ready():
func _get_shader_code(uv, slot = 0):
var rv = { defs="", code="" }
if generated_variants.empty():
- rv.defs = "vec3 %s_xyz(vec2 uv) { return bricks_%s(uv, vec2(%d, %d), %.9f, %.9f, %.9f, %.9f); }\n" % [ name, BRICK_PATTERNS[pattern].suffix, columns, rows, repeat, row_offset, mortar, max(0.001, bevel) ]
+ rv.defs = "vec3 %s_xyz(vec2 uv) { return bricks_%s(uv, vec2(%d, %d), %.9f, %.9f, %.9f, %.9f); }\n" % [ name, BRICK_PATTERNS[parameters.pattern].suffix, parameters.columns, parameters.rows, parameters.repeat, parameters.row_offset, parameters.mortar, max(0.001, parameters.bevel) ]
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
diff --git a/addons/material_maker/nodes/colorize/colorize.gd b/addons/material_maker/nodes/colorize/colorize.gd
index 749aa25..ab660f9 100644
--- a/addons/material_maker/nodes/colorize/colorize.gd
+++ b/addons/material_maker/nodes/colorize/colorize.gd
@@ -1,8 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var gradient
-
func _ready():
initialize_properties([ $gradient ])
@@ -13,7 +11,7 @@ func _get_shader_code(uv):
return rv
var src_code = src.get_shader_code(uv)
if generated_variants.empty():
- rv.defs = src_code.defs+gradient.get_shader("%s_gradient" % name);
+ rv.defs = src_code.defs+parameters.gradient.get_shader("%s_gradient" % name);
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
@@ -23,5 +21,5 @@ func _get_shader_code(uv):
return rv
func _on_Control_updated(v):
- gradient = v
+ parameters.gradient = v
update_shaders()
diff --git a/addons/material_maker/nodes/custom/custom.gd b/addons/material_maker/nodes/custom/custom.gd
new file mode 100644
index 0000000..760164c
--- /dev/null
+++ b/addons/material_maker/nodes/custom/custom.gd
@@ -0,0 +1,8 @@
+tool
+extends "res://addons/material_maker/nodes/node_generic.gd"
+
+func _on_Edit_pressed():
+ pass # replace with function body
+
+func _on_Save_pressed():
+ pass # replace with function body
diff --git a/addons/material_maker/nodes/custom/custom.tscn b/addons/material_maker/nodes/custom/custom.tscn
new file mode 100644
index 0000000..0b08856
--- /dev/null
+++ b/addons/material_maker/nodes/custom/custom.tscn
@@ -0,0 +1,107 @@
+[gd_scene load_steps=4 format=2]
+
+[ext_resource path="res://addons/material_maker/nodes/custom/custom.gd" type="Script" id=1]
+[ext_resource path="res://addons/material_maker/icons/edit.png" type="Texture" id=2]
+[ext_resource path="res://addons/material_maker/icons/save.png" type="Texture" id=3]
+
+[node name="Custom" type="GraphNode" index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_left = 385.0
+margin_top = 287.0
+margin_right = 479.0
+margin_bottom = 338.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+mouse_filter = 1
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 1
+title = "Custom"
+offset = Vector2( 0, 0 )
+show_close = true
+resizable = false
+selected = false
+comment = false
+overlay = 0
+slot/0/left_enabled = false
+slot/0/left_type = 0
+slot/0/left_color = Color( 1, 1, 1, 1 )
+slot/0/right_enabled = false
+slot/0/right_type = 0
+slot/0/right_color = Color( 1, 1, 1, 1 )
+script = ExtResource( 1 )
+
+[node name="CustomNodeButtons" type="HBoxContainer" parent="." index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_left = 16.0
+margin_top = 24.0
+margin_right = 78.0
+margin_bottom = 46.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+mouse_filter = 1
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 1
+alignment = 0
+
+[node name="Edit" type="Button" parent="CustomNodeButtons" index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_right = 27.0
+margin_bottom = 22.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+focus_mode = 2
+mouse_filter = 0
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 1
+toggle_mode = false
+enabled_focus_mode = 2
+shortcut = null
+group = null
+icon = ExtResource( 2 )
+flat = true
+align = 1
+
+[node name="Save" type="Button" parent="CustomNodeButtons" index="1"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_left = 31.0
+margin_right = 59.0
+margin_bottom = 22.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+focus_mode = 2
+mouse_filter = 0
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 1
+toggle_mode = false
+enabled_focus_mode = 2
+shortcut = null
+group = null
+icon = ExtResource( 3 )
+flat = true
+align = 1
+
+[connection signal="pressed" from="CustomNodeButtons/Edit" to="." method="_on_Edit_pressed"]
+
+[connection signal="pressed" from="CustomNodeButtons/Save" to="." method="_on_Save_pressed"]
+
+
diff --git a/addons/material_maker/nodes/emboss/emboss.gd b/addons/material_maker/nodes/emboss/emboss.gd
index ee7809f..935195a 100644
--- a/addons/material_maker/nodes/emboss/emboss.gd
+++ b/addons/material_maker/nodes/emboss/emboss.gd
@@ -1,9 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var size = 5
-var direction = 0
-
var input_shader = ""
var input_texture
var final_texture
@@ -28,20 +25,20 @@ func _ready():
$HBoxContainer1/size.clear()
for i in range(7):
$HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i)
- $HBoxContainer1/size.selected = size
+ $HBoxContainer1/size.selected = 5
input_texture = ImageTexture.new()
final_texture = ImageTexture.new()
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/direction ])
func _rerender():
- get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+size)), input_texture, self, "pass_1", [])
+ get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), input_texture, self, "pass_1", [])
func pass_1():
var convolution = CONVOLUTION
- convolution.epsilon=1.0/pow(2, 5+size)
+ convolution.epsilon=1.0/pow(2, 5+parameters.size)
for i in range(8):
- convolution.kernel[INDICES[i]] = COEFS[(i+8-int(direction))%8]
- get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), {input=input_texture}, int(pow(2, 5+size)), final_texture, self, "rerender_targets", [])
+ convolution.kernel[INDICES[i]] = COEFS[(i+8-int(parameters.direction))%8]
+ get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), {input=input_texture}, int(pow(2, 5+parameters.size)), final_texture, self, "rerender_targets", [])
func get_textures():
var list = {}
diff --git a/addons/material_maker/nodes/export/export.gd b/addons/material_maker/nodes/export/export.gd
index 5e81674..3094a8c 100644
--- a/addons/material_maker/nodes/export/export.gd
+++ b/addons/material_maker/nodes/export/export.gd
@@ -1,7 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var resolution = 1
var suffix = "suffix"
func _ready():
@@ -18,7 +17,7 @@ func export_textures(prefix, size = null):
var suffix = $Suffix.text
if suffix != "":
if size == null:
- size = int(pow(2, 8+resolution))
+ size = int(pow(2, 8+parameters.resolution))
get_parent().renderer.export_texture(get_source(), "%s_%s.png" % [ prefix, suffix ], size)
func serialize():
diff --git a/addons/material_maker/nodes/material/material.gd b/addons/material_maker/nodes/material/material.gd
index 4f56092..90eb786 100644
--- a/addons/material_maker/nodes/material/material.gd
+++ b/addons/material_maker/nodes/material/material.gd
@@ -1,15 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var resolution = 1
-var albedo_color
-var metallic
-var roughness
-var emission_energy
-var normal_scale
-var ao_light_affect
-var depth_scale
-
var texture_list
var current_material_list = []
@@ -42,7 +33,7 @@ func _ready():
initialize_properties([ $resolution, $Albedo/albedo_color, $Metallic/metallic, $Roughness/roughness, $Emission/emission_energy, $NormalMap/normal_scale, $AmbientOcclusion/ao_light_affect, $DepthMap/depth_scale ])
func _rerender():
- var size = int(pow(2, 8+resolution))
+ var size = int(pow(2, 8+parameters.resolution))
var has_textures = false
for t in texture_list:
var shader = generated_textures[t.texture].shader
@@ -116,10 +107,10 @@ func get_generated_texture(slot, file_prefix = null):
func update_spatial_material(m, file_prefix = null):
var texture
- m.albedo_color = albedo_color
+ m.albedo_color = parameters.albedo_color
m.albedo_texture = get_generated_texture("albedo", file_prefix)
- m.metallic = metallic
- m.roughness = roughness
+ m.metallic = parameters.metallic
+ m.roughness = parameters.roughness
if Engine.editor_hint:
texture = get_generated_texture("mrao", file_prefix)
m.metallic_texture = texture
@@ -132,7 +123,7 @@ func update_spatial_material(m, file_prefix = null):
texture = get_generated_texture("emission", file_prefix)
if texture != null:
m.emission_enabled = true
- m.emission_energy = emission_energy
+ m.emission_energy = parameters.emission_energy
m.emission_texture = texture
else:
m.emission_enabled = false
@@ -145,7 +136,7 @@ func update_spatial_material(m, file_prefix = null):
if Engine.editor_hint:
if (generated_textures.mrao.mask & (1 << 2)) != 0:
m.ao_enabled = true
- m.ao_light_affect = ao_light_affect
+ m.ao_light_affect = parameters.ao_light_affect
m.ao_texture = m.metallic_texture
m.ao_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_BLUE
else:
@@ -154,14 +145,14 @@ func update_spatial_material(m, file_prefix = null):
texture = get_generated_texture("ambient_occlusion", file_prefix)
if texture != null:
m.ao_enabled = true
- m.ao_light_affect = ao_light_affect
+ m.ao_light_affect = parameters.ao_light_affect
m.ao_texture = texture
else:
m.ao_enabled = false
texture = get_generated_texture("depth_map", file_prefix)
if texture != null:
m.depth_enabled = true
- m.depth_scale = depth_scale
+ m.depth_scale = parameters.depth_scale
m.depth_texture = texture
else:
m.depth_enabled = false
@@ -173,7 +164,7 @@ func do_update_materials(material_list):
func export_textures(prefix, size = null):
if size == null:
- size = int(pow(2, 8+resolution))
+ size = int(pow(2, 8+parameters.resolution))
for t in texture_list:
var texture = generated_textures[t.texture].texture
if texture != null:
diff --git a/addons/material_maker/nodes/node_generic.gd b/addons/material_maker/nodes/node_generic.gd
new file mode 100644
index 0000000..4dba772
--- /dev/null
+++ b/addons/material_maker/nodes/node_generic.gd
@@ -0,0 +1,149 @@
+tool
+extends "res://addons/material_maker/node_base.gd"
+
+export(String) var model = null setget set_model
+var model_data = null
+var uses_seed = false
+
+func _ready():
+ show_close = true
+ connect("offset_changed", self, "_on_offset_changed")
+
+func set_model(m):
+ if m != null and typeof(m) == TYPE_STRING:
+ var file = File.new()
+ var file_name = m
+ if !file.file_exists(file_name):
+ file_name = "res://addons/material_maker/nodes/%s.json" % [ m ]
+ if file.file_exists(file_name):
+ if file.open(file_name, File.READ) != OK:
+ return
+ var data = file.get_as_text()
+ var status = validate_json(data)
+ file.close()
+ if status != "":
+ print("Incorrect node description (%s)" % status)
+ return
+ data = parse_json(data)
+ model = m
+ update_node(data)
+
+func update_node(data):
+ if typeof(data) != TYPE_DICTIONARY:
+ return
+ if !data.has("name"):
+ return
+ title = data.name
+ model_data = data
+ uses_seed = false
+ if model_data.has("instance") and model_data.instance.find("$(seed)"):
+ uses_seed = true
+ if model_data.has("parameters") and typeof(model_data.parameters) == TYPE_ARRAY:
+ var control_list = []
+ for p in model_data.parameters:
+ if !p.has("name") or !p.has("type"):
+ continue
+ var control = null
+ if p.type == "float":
+ if p.has("widget") and p.widget == "spinbox":
+ control = SpinBox.new()
+ else:
+ control = HSlider.new()
+ control.min_value = p.min
+ control.max_value = p.max
+ control.step = 0 if !p.has("step") else p.step
+ control.rect_min_size.x = 80
+ parameters[p.name] = 0.5*(p.min+p.max)
+ elif p.type == "size":
+ control = OptionButton.new()
+ for i in range(p.first, p.last):
+ var s = pow(2, i)
+ control.add_item("%dx%d" % [ s, s ])
+ control.selected = 0 if !p.has("default") else p.default
+ elif p.type == "enum":
+ control = OptionButton.new()
+ for i in p.values.size():
+ var value = p.values[i]
+ control.add_item(value.name)
+ control.selected = 0 if !p.has("default") else p.default
+ if control != null:
+ var label = p.name
+ control.name = label
+ control_list.append(control)
+ var sizer = HBoxContainer.new()
+ sizer.size_flags_horizontal = SIZE_EXPAND | SIZE_FILL
+ if p.has("label"):
+ label = p.label
+ if label != "":
+ var label_widget = Label.new()
+ label_widget.text = label
+ label_widget.size_flags_horizontal = SIZE_EXPAND | SIZE_FILL
+ sizer.add_child(label_widget)
+ control.size_flags_horizontal = SIZE_EXPAND | SIZE_FILL
+ sizer.add_child(control)
+ add_child(sizer)
+ initialize_properties(control_list)
+ else:
+ model_data.parameters = []
+ if model_data.has("outputs") and typeof(model_data.outputs) == TYPE_ARRAY:
+ for i in model_data.outputs.size():
+ var output = model_data.outputs[i]
+ var enable_right = false
+ var color_right = Color(0.5, 0.5, 0.5)
+ if typeof(output) == TYPE_DICTIONARY:
+ if output.has("rgb"):
+ enable_right = true
+ color_right = Color(0.5, 0.5, 1.0)
+ elif output.has("f"):
+ enable_right = true
+ set_slot(i, false, 0, color_right, enable_right, 0, color_right)
+ else:
+ model_data.outputs = []
+
+func subst(string, uv = ""):
+ string = string.replace("$(name)", name)
+ string = string.replace("$(seed)", str(get_seed()))
+ string = string.replace("$(uv)", uv)
+ if model_data.has("parameters") and typeof(model_data.parameters) == TYPE_ARRAY:
+ for p in model_data.parameters:
+ if !p.has("name") or !p.has("type"):
+ continue
+ var value = parameters[p.name]
+ var value_string = null
+ if p.type == "float":
+ value_string = "%.9f" % value
+ elif p.type == "size":
+ value_string = "%.9f" % pow(2, value+p.first)
+ elif p.type == "enum":
+ value_string = p.values[value].value
+ if value_string != null:
+ string = string.replace("$(%s)" % p.name, value_string)
+ return string
+
+func _get_shader_code(uv, slot = 0):
+ var rv = { defs="", code="", f="0.0" }
+ if model_data != null and model_data.has("outputs") and model_data.outputs.size() > slot:
+ var output = model_data.outputs[slot]
+ if model_data.has("instance") && generated_variants.empty():
+ rv.defs = subst(model_data.instance)
+ var variant_index = generated_variants.find(uv)
+ if variant_index == -1:
+ variant_index = generated_variants.size()
+ generated_variants.append(uv)
+ if output.has("rgb"):
+ rv.code += "vec3 %s_%d_rgb = %s;\n" % [ name, variant_index, subst(output.rgb, uv) ]
+ if output.has("f"):
+ rv.code += "float %s_%d_f = %s;\n" % [ name, variant_index, subst(output.f, uv) ]
+ if output.has("rgb"):
+ rv.rgb = "%s_%d_rgb" % [ name, variant_index ]
+ if output.has("f"):
+ rv.f = "%s_%d_f" % [ name, variant_index ]
+ return rv
+
+func _on_offset_changed():
+ update_shaders()
+
+func serialize():
+ var return_value = .serialize()
+ return_value.type = model
+ return return_value
diff --git a/addons/material_maker/nodes/noise.json b/addons/material_maker/nodes/noise.json
new file mode 100644
index 0000000..cc216ba
--- /dev/null
+++ b/addons/material_maker/nodes/noise.json
@@ -0,0 +1,27 @@
+{
+ "name":"Noise",
+ "parameters":[
+ { "name":"size", "label":"Grid Size:", "type":"size", "first":2, "last":12, "default":8 },
+ { "name":"density", "label":"Density:", "type":"float", "min":0.0, "max":1.0 }
+ ],
+ "global":"
+ float rand(vec2 x) {
+ return fract(cos(dot(x, vec2(13.9898, 8.141))) * 43758.5453);
+ }
+ vec2 rand2(vec2 x) {
+ return fract(cos(vec2(dot(x, vec2(13.9898, 8.141)),
+ dot(x, vec2(3.4562, 17.398)))) * 43758.5453);
+ }
+ vec3 rand3(vec2 x) {
+ return fract(cos(vec3(dot(x, vec2(13.9898, 8.141)),
+ dot(x, vec2(3.4562, 17.398)),
+ dot(x, vec2(13.254, 5.867)))) * 43758.5453);
+ }",
+ "instance":"
+ float $(name)_f(vec2 uv) {
+ return dots(uv, 1.0/$(size), $(density), $(seed));
+ }",
+ "outputs":[
+ { "f":"$(name)_f($(uv))" }
+ ]
+}
\ No newline at end of file
diff --git a/addons/material_maker/nodes/noise/noise.gd b/addons/material_maker/nodes/noise/noise.gd
index 7d8e379..cf0ea9f 100644
--- a/addons/material_maker/nodes/noise/noise.gd
+++ b/addons/material_maker/nodes/noise/noise.gd
@@ -1,20 +1,17 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var size = 4
-var density = 0.5
-
func _ready():
$HBoxContainer1/size.clear()
for i in range(7):
$HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i)
- $HBoxContainer1/size.selected = size
+ $HBoxContainer1/size.selected = 4
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/density ])
func _get_shader_code(uv):
var rv = { defs="", code="" }
if generated_variants.empty():
- rv.defs = "float %s_f(vec2 uv) { return dots(uv, %.9f, %.9f, %d); }\n" % [ name, 1.0/pow(2.0, 5.0+size), density, get_seed() ]
+ rv.defs = "float %s_f(vec2 uv) { return dots(uv, %.9f, %.9f, %d); }\n" % [ name, 1.0/pow(2.0, 5.0+parameters.size), parameters.density, get_seed() ]
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
diff --git a/addons/material_maker/nodes/noise/noise.tscn b/addons/material_maker/nodes/noise/noise.tscn
index 40972e4..a7827de 100644
--- a/addons/material_maker/nodes/noise/noise.tscn
+++ b/addons/material_maker/nodes/noise/noise.tscn
@@ -2,11 +2,10 @@
[ext_resource path="res://addons/material_maker/nodes/noise/noise.gd" type="Script" id=1]
-
[sub_resource type="Theme" id=1]
-[node name="Dots" type="GraphNode" index="0"]
+[node name="Dots" type="GraphNode"]
anchor_left = 0.0
anchor_top = 0.0
diff --git a/addons/material_maker/nodes/normal_map/normal_map.gd b/addons/material_maker/nodes/normal_map/normal_map.gd
index cf49e16..ebaeadf 100644
--- a/addons/material_maker/nodes/normal_map/normal_map.gd
+++ b/addons/material_maker/nodes/normal_map/normal_map.gd
@@ -1,9 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var size = 5
-var amount = 0.0
-
var input_shader = ""
var input_texture
var final_texture
@@ -29,19 +26,20 @@ func _ready():
$HBoxContainer1/size.clear()
for i in range(7):
$HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i)
- $HBoxContainer1/size.selected = size
+ parameters.size = 2
+ $HBoxContainer1/size.selected = parameters.size
input_texture = ImageTexture.new()
final_texture = ImageTexture.new()
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/amount ])
func _rerender():
- get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+size)), input_texture, self, "pass_1", [])
+ get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), input_texture, self, "pass_1", [])
func pass_1():
var convolution = CONVOLUTION
- convolution.epsilon=1.0/pow(2, 5+size)
- convolution.scale_before_normalize = pow(2, size-1)*amount
- get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), { input=input_texture}, int(pow(2, 5+size)), final_texture, self, "rerender_targets", [])
+ convolution.epsilon=1.0/pow(2, 5+parameters.size)
+ convolution.scale_before_normalize = pow(2, parameters.size-1)*parameters.amount
+ get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), { input=input_texture}, int(pow(2, 5+parameters.size)), final_texture, self, "rerender_targets", [])
func get_textures():
var list = {}
diff --git a/addons/material_maker/nodes/pattern/pattern.gd b/addons/material_maker/nodes/pattern/pattern.gd
index f2cadeb..74f2b90 100644
--- a/addons/material_maker/nodes/pattern/pattern.gd
+++ b/addons/material_maker/nodes/pattern/pattern.gd
@@ -1,12 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var mix = 0;
-var x_wave = 0
-var x_scale = 4.0
-var y_wave = 0
-var y_scale = 4.0
-
const WAVE_FCT = [ "wave_sin", "wave_triangle", "wave_square", "fract", "wave_constant" ]
const MIX_FCT = [ "mix_multiply", "mix_add", "mix_max", "mix_min", "mix_xor", "mix_pow" ]
@@ -16,7 +10,7 @@ func _ready():
func _get_shader_code(uv):
var rv = { defs="", code="" }
if generated_variants.empty():
- rv.defs = "float %s_f(vec2 uv) { uv *= vec2(%.9f, %.9f); return %s(%s(uv.x), %s(uv.y)); }\n" % [ name, x_scale, y_scale, MIX_FCT[mix], WAVE_FCT[x_wave], WAVE_FCT[y_wave] ]
+ rv.defs = "float %s_f(vec2 uv) { uv *= vec2(%.9f, %.9f); return %s(%s(uv.x), %s(uv.y)); }\n" % [ name, parameters.x_scale, parameters.y_scale, MIX_FCT[parameters.mix], WAVE_FCT[parameters.x_wave], WAVE_FCT[parameters.y_wave] ]
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
diff --git a/addons/material_maker/nodes/perlin/perlin.gd b/addons/material_maker/nodes/perlin/perlin.gd
index 0e12fd9..a18bd4c 100644
--- a/addons/material_maker/nodes/perlin/perlin.gd
+++ b/addons/material_maker/nodes/perlin/perlin.gd
@@ -1,11 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var scale_x
-var scale_y
-var iterations
-var persistence
-
func _ready():
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
initialize_properties([ $GridContainer/scale_x, $GridContainer/scale_y, $GridContainer/iterations, $GridContainer/persistence ])
@@ -13,7 +8,7 @@ func _ready():
func _get_shader_code(uv):
var rv = { defs="", code="" }
if generated_variants.empty():
- rv.defs = "float %s_f(vec2 uv) { return perlin(uv, vec2(%f, %f), %d, %.9f, %d); }\n" % [ name, scale_x, scale_y, iterations, persistence, get_seed() ]
+ rv.defs = "float %s_f(vec2 uv) { return perlin(uv, vec2(%f, %f), %d, %.9f, %d); }\n" % [ name, parameters.scale_x, parameters.scale_y, parameters.iterations, parameters.persistence, get_seed() ]
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
diff --git a/addons/material_maker/nodes/shape/shape.gd b/addons/material_maker/nodes/shape/shape.gd
index 6c3d01b..f0cc284 100644
--- a/addons/material_maker/nodes/shape/shape.gd
+++ b/addons/material_maker/nodes/shape/shape.gd
@@ -1,11 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var shape
-var sides
-var radius
-var edge
-
const SHAPES = [ "circle", "polygon", "star", "curved_star", "rays" ]
func _ready():
@@ -13,5 +8,5 @@ func _ready():
func _get_shader_code(uv):
var rv = { defs="", code="" }
- rv.f = "%s(%s, %d, %f, %f)" % [ SHAPES[shape], uv, sides, radius, edge ]
+ rv.f = "%s(%s, %d, %f, %f)" % [ SHAPES[parameters.shape], uv, parameters.sides, parameters.radius, parameters.edge ]
return rv
diff --git a/addons/material_maker/nodes/switch/switch.gd b/addons/material_maker/nodes/switch/switch.gd
index d6a493f..9ed8401 100644
--- a/addons/material_maker/nodes/switch/switch.gd
+++ b/addons/material_maker/nodes/switch/switch.gd
@@ -1,8 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var source = 0
-
func _ready():
initialize_properties([ $source ])
@@ -12,7 +10,7 @@ func reset():
func _get_shader_code(uv, index = 0):
var rv = { defs="", code="" }
- var src = get_source(2*source+index)
+ var src = get_source(2*parameters.source+index)
var src_code = { defs="", code="", rgb="0.0" }
if src != null:
src_code = src.get_shader_code(uv)
diff --git a/addons/material_maker/nodes/transform/transform.gd b/addons/material_maker/nodes/transform/transform.gd
index 77e73c8..402341d 100644
--- a/addons/material_maker/nodes/transform/transform.gd
+++ b/addons/material_maker/nodes/transform/transform.gd
@@ -1,13 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var translate_x = 0.0
-var translate_y = 0.0
-var rotate = 0.0
-var scale_x = 1.0
-var scale_y = 1.0
-var repeat = true
-
func _ready():
set_slot(0, true, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
initialize_properties([ $HBoxContainer1/translate_x, $HBoxContainer2/translate_y, $HBoxContainer3/rotate, $HBoxContainer4/scale_x, $HBoxContainer5/scale_y, $repeat ])
@@ -30,7 +23,7 @@ func _get_shader_code(uv):
rv.defs += tsrc_code.defs
rv.code += tsrc_code.code
inputs[i] = "*(2.0*(%s)-1.0)" % tsrc_code.f
- rv.code += "vec2 %s_%d_uv = %s(%s, vec2(%.9f%s, %.9f%s), %.9f%s, vec2(%.9f%s, %.9f%s));\n" % [ name, variant_index, "transform_repeat" if repeat else "transform_norepeat", uv, translate_x, inputs[0], translate_y, inputs[1], PI*rotate/180.0, inputs[2], scale_x, inputs[3], scale_y, inputs[4] ]
+ rv.code += "vec2 %s_%d_uv = %s(%s, vec2(%.9f%s, %.9f%s), %.9f%s, vec2(%.9f%s, %.9f%s));\n" % [ name, variant_index, "transform_repeat" if parameters.repeat else "transform_norepeat", uv, parameters.translate_x, inputs[0], parameters.translate_y, inputs[1], PI*parameters.rotate/180.0, inputs[2], parameters.scale_x, inputs[3], parameters.scale_y, inputs[4] ]
var src_code = src.get_shader_code("%s_%d_uv" % [ name, variant_index ])
if rv.code != "":
if generated_variants.size() == 1:
@@ -41,6 +34,6 @@ func _get_shader_code(uv):
func deserialize(data):
if data.has("scale"):
- scale_x = data.scale
- scale_y = data.scale
+ parameters.scale_x = data.scale
+ parameters.scale_y = data.scale
.deserialize(data)
diff --git a/addons/material_maker/nodes/uniform/uniform.gd b/addons/material_maker/nodes/uniform/uniform.gd
index dfcc368..203a2d6 100644
--- a/addons/material_maker/nodes/uniform/uniform.gd
+++ b/addons/material_maker/nodes/uniform/uniform.gd
@@ -1,12 +1,10 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var color = Color(0.0, 0.0, 0.0)
-
func _ready():
initialize_properties([ $color ])
func _get_shader_code(uv):
var rv = { defs="", code="" }
- rv.rgb = "vec3(%.9f, %.9f, %.9f)" % [ color.r, color.g, color.b ]
+ rv.rgb = "vec3(%.9f, %.9f, %.9f)" % [ parameters.color.r, parameters.color.g, parameters.color.b ]
return rv
diff --git a/addons/material_maker/nodes/voronoi/voronoi.gd b/addons/material_maker/nodes/voronoi/voronoi.gd
index 1b98481..44afdb4 100644
--- a/addons/material_maker/nodes/voronoi/voronoi.gd
+++ b/addons/material_maker/nodes/voronoi/voronoi.gd
@@ -1,10 +1,6 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var scale_x
-var scale_y
-var intensity
-
func _ready():
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
initialize_properties([ $HBoxContainer1/scale_x, $HBoxContainer2/scale_y, $HBoxContainer3/intensity ])
@@ -12,7 +8,7 @@ func _ready():
func _get_shader_code(uv, slot = 0):
var rv = { defs="", code="" }
if generated_variants.empty():
- rv.defs = "vec4 %s_xyzw(vec2 uv) { return voronoi(uv, vec2(%f, %f), %.9f, %d); }\n" % [ name, scale_x, scale_y, intensity, get_seed() ]
+ rv.defs = "vec4 %s_xyzw(vec2 uv) { return voronoi(uv, vec2(%f, %f), %.9f, %d); }\n" % [ name, parameters.scale_x, parameters.scale_y, parameters.intensity, get_seed() ]
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
diff --git a/addons/material_maker/nodes/warp/warp.gd b/addons/material_maker/nodes/warp/warp.gd
index 2a8191b..c7c0dc9 100644
--- a/addons/material_maker/nodes/warp/warp.gd
+++ b/addons/material_maker/nodes/warp/warp.gd
@@ -1,11 +1,7 @@
tool
extends "res://addons/material_maker/node_base.gd"
-var amount = 0.0
-
func _ready():
- set_slot(0, true, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
- set_slot(1, true, 0, Color(0.5, 0.5, 1), false, 0, Color(0.5, 0.5, 1))
initialize_properties([ $amount ])
func _get_shader_code(uv):
@@ -25,7 +21,7 @@ func _get_shader_code(uv):
var src1_code3 = src1.get_shader_code("fract(%s-vec2(0.0, %.9f))" % [ uv, epsilon ])
rv.defs = src1_code0.defs
rv.code = src1_code0.code+src1_code1.code+src1_code2.code+src1_code3.code
- rv.code += "vec2 %s_%d_uv = %s+%.9f*vec2((%s)-(%s), (%s)-(%s));\n" % [ name, variant_index, uv, amount, src1_code0.f, src1_code1.f, src1_code2.f, src1_code3.f ]
+ rv.code += "vec2 %s_%d_uv = %s+%.9f*vec2((%s)-(%s), (%s)-(%s));\n" % [ name, variant_index, uv, parameters.amount, src1_code0.f, src1_code1.f, src1_code2.f, src1_code3.f ]
var src0_code = src0.get_shader_code("%s_%d_uv" % [ name, variant_index ])
rv.defs += src0_code.defs
rv.code += src0_code.code
diff --git a/addons/material_maker/nodes/warp/warp.tscn b/addons/material_maker/nodes/warp/warp.tscn
index 5af5895..00decbf 100644
--- a/addons/material_maker/nodes/warp/warp.tscn
+++ b/addons/material_maker/nodes/warp/warp.tscn
@@ -2,7 +2,6 @@
[ext_resource path="res://addons/material_maker/nodes/warp/warp.gd" type="Script" id=1]
-
[sub_resource type="Theme" id=1]
diff --git a/addons/material_maker/widgets/linked_widgets/config_control.gd b/addons/material_maker/widgets/linked_widgets/config_control.gd
index 36179a2..96fbde1 100644
--- a/addons/material_maker/widgets/linked_widgets/config_control.gd
+++ b/addons/material_maker/widgets/linked_widgets/config_control.gd
@@ -52,7 +52,7 @@ func apply_configuration(c):
for w in configurations[c]:
var value = duplicate_value(w.value)
w.widget.set(WIDGETS[get_widget_type(w.widget)].value_attr, value)
- w.node.set(w.widget.name, value)
+ w.node.parameters[w.widget.name] = value
var graph_node = get_parent()
while !(graph_node is GraphNode):
graph_node = graph_node.get_parent()
@@ -61,7 +61,7 @@ func apply_configuration(c):
func do_update_configuration(name):
var configuration = []
for w in linked_widgets:
- configuration.append({ node=w.node, widget=w.widget, value=duplicate_value(w.node.get(w.widget.name)) })
+ configuration.append({ node=w.node, widget=w.widget, value=duplicate_value(w.node.parameters[w.widget.name]) })
configurations[name] = configuration
current = name
update_options()
diff --git a/addons/material_maker/widgets/linked_widgets/linked_control.gd b/addons/material_maker/widgets/linked_widgets/linked_control.gd
index d60fa56..1d42a6d 100644
--- a/addons/material_maker/widgets/linked_widgets/linked_control.gd
+++ b/addons/material_maker/widgets/linked_widgets/linked_control.gd
@@ -68,24 +68,25 @@ func update_shaders():
func _on_value_changed(v):
for l in linked_widgets:
l.widget.value = v
- l.node.set(l.widget.name, v)
+ l.node.parameters[l.widget.name] = v
update_shaders()
func _on_color_changed(c):
for l in linked_widgets:
l.widget.color = c
- l.node.set(l.widget.name, c)
+ l.node.parameters[l.widget.name] = c
update_shaders()
func _on_item_selected(i):
for l in linked_widgets:
l.widget.selected = i
- l.node.set(l.widget.name, i)
+ l.node.parameters[l.widget.name] = i
update_shaders()
func _on_gradient_updated(g):
for l in linked_widgets:
l.widget.value = g
+ l.node.parameters[l.widget.name] = g
update_shaders()
func serialize():
diff --git a/addons/material_maker/widgets/node_editor.tscn b/addons/material_maker/widgets/node_editor.tscn
new file mode 100644
index 0000000..c54ec64
--- /dev/null
+++ b/addons/material_maker/widgets/node_editor.tscn
@@ -0,0 +1,187 @@
+[gd_scene format=2]
+
+[node name="WindowDialog" type="WindowDialog" index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_right = 666.0
+margin_bottom = 592.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+mouse_filter = 0
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 1
+popup_exclusive = false
+window_title = "Custom node"
+resizable = true
+
+[node name="TabContainer" type="TabContainer" parent="." index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_right = -89.0
+margin_bottom = -41.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+mouse_filter = 0
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 1
+tab_align = 1
+tabs_visible = true
+
+[node name="General" type="VBoxContainer" parent="TabContainer" index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_top = 26.0
+margin_bottom = 26.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+mouse_filter = 1
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 3
+size_flags_vertical = 3
+alignment = 0
+_sections_unfolded = [ "Anchor", "Grow Direction", "Margin", "Size Flags" ]
+
+[node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/General" index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_right = 577.0
+margin_bottom = 24.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+mouse_filter = 1
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 3
+size_flags_vertical = 1
+alignment = 0
+_sections_unfolded = [ "Size Flags" ]
+
+[node name="Label" type="Label" parent="TabContainer/General/HBoxContainer" index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_top = 5.0
+margin_right = 42.0
+margin_bottom = 19.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+mouse_filter = 2
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 4
+text = "Name:"
+percent_visible = 1.0
+lines_skipped = 0
+max_lines_visible = -1
+
+[node name="LineEdit" type="LineEdit" parent="TabContainer/General/HBoxContainer" index="1"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_left = 46.0
+margin_right = 577.0
+margin_bottom = 24.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+focus_mode = 2
+mouse_filter = 0
+mouse_default_cursor_shape = 1
+size_flags_horizontal = 3
+size_flags_vertical = 1
+focus_mode = 2
+context_menu_enabled = true
+placeholder_alpha = 0.6
+caret_blink = false
+caret_blink_speed = 0.65
+caret_position = 0
+_sections_unfolded = [ "Size Flags" ]
+
+[node name="Global functions" type="TextEdit" parent="TabContainer" index="1"]
+
+visible = false
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_top = 72.0
+margin_right = -8.0
+margin_bottom = 36.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+focus_mode = 2
+mouse_filter = 0
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 3
+size_flags_vertical = 3
+text = ""
+readonly = false
+highlight_current_line = false
+syntax_highlighting = false
+show_line_numbers = false
+highlight_all_occurrences = false
+override_selected_font_color = false
+context_menu_enabled = true
+smooth_scrolling = false
+v_scroll_speed = 80.0
+hiding_enabled = 0
+wrap_lines = false
+caret_block_mode = false
+caret_blink = false
+caret_blink_speed = 0.65
+caret_moving_by_right_click = true
+_sections_unfolded = [ "Size Flags" ]
+
+[node name="Instance functions" type="TextEdit" parent="TabContainer" index="2"]
+
+visible = false
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_left = 4.0
+margin_top = 32.0
+margin_right = -4.0
+margin_bottom = -4.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+focus_mode = 2
+mouse_filter = 0
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 3
+size_flags_vertical = 3
+text = ""
+readonly = false
+highlight_current_line = false
+syntax_highlighting = false
+show_line_numbers = false
+highlight_all_occurrences = false
+override_selected_font_color = false
+context_menu_enabled = true
+smooth_scrolling = false
+v_scroll_speed = 80.0
+hiding_enabled = 0
+wrap_lines = false
+caret_block_mode = false
+caret_blink = false
+caret_blink_speed = 0.65
+caret_moving_by_right_click = true
+_sections_unfolded = [ "Size Flags" ]
+
+
diff --git a/addons/material_maker/widgets/node_editor/node_editor.gd b/addons/material_maker/widgets/node_editor/node_editor.gd
new file mode 100644
index 0000000..7655466
--- /dev/null
+++ b/addons/material_maker/widgets/node_editor/node_editor.gd
@@ -0,0 +1,16 @@
+extends WindowDialog
+
+var model_data
+
+func _init(data):
+ model_data = data
+
+func _ready():
+ # Called when the node is added to the scene for the first time.
+ # Initialization here
+ pass
+
+#func _process(delta):
+# # Called every frame. Delta is time since last frame.
+# # Update game logic here.
+# pass
diff --git a/addons/material_maker/widgets/node_editor/node_editor.tscn b/addons/material_maker/widgets/node_editor/node_editor.tscn
new file mode 100644
index 0000000..ffc7dcd
--- /dev/null
+++ b/addons/material_maker/widgets/node_editor/node_editor.tscn
@@ -0,0 +1,73 @@
+[gd_scene load_steps=2 format=2]
+
+[ext_resource path="res://addons/material_maker/widgets/node_editor/node_editor.gd" type="Script" id=1]
+
+[node name="NodeEditor" type="WindowDialog" index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_right = 469.0
+margin_bottom = 373.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+mouse_filter = 0
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 1
+popup_exclusive = false
+window_title = "Node Editor"
+resizable = false
+script = ExtResource( 1 )
+
+[node name="Tabs" type="TabContainer" parent="." index="1"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+mouse_filter = 0
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 1
+tab_align = 0
+tabs_visible = true
+
+[node name="Global" type="TextEdit" parent="Tabs" index="0"]
+
+anchor_left = 0.0
+anchor_top = 0.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_left = 4.0
+margin_top = 32.0
+margin_right = -4.0
+margin_bottom = -4.0
+rect_pivot_offset = Vector2( 0, 0 )
+rect_clip_content = false
+focus_mode = 2
+mouse_filter = 0
+mouse_default_cursor_shape = 0
+size_flags_horizontal = 1
+size_flags_vertical = 1
+text = ""
+readonly = false
+highlight_current_line = false
+syntax_highlighting = false
+show_line_numbers = false
+highlight_all_occurrences = false
+override_selected_font_color = false
+context_menu_enabled = true
+smooth_scrolling = false
+v_scroll_speed = 80.0
+hiding_enabled = 0
+wrap_lines = false
+caret_block_mode = false
+caret_blink = false
+caret_blink_speed = 0.65
+caret_moving_by_right_click = true
+
+