Updated bricks and voronoi nodes to provide several outputs

Updated base node class to support several outputs.
Now bricks support 2 outputs : greyscale depth map, and (random) brick color.
Now Voronoi supports 3 outputs : center distance, edge distance and cell color.
Updated bricks example to use brick color output.
This commit is contained in:
RodZill4 2018-08-03 22:38:48 +02:00
parent a946206a34
commit 507586cbec
10 changed files with 219 additions and 100 deletions

View File

@ -1,14 +1,14 @@
float rand(vec2 x) {
return fract(sin(dot(x, vec2(13.9898, 8.141))) * 43758.5453);
return fract(cos(dot(x, vec2(13.9898, 8.141))) * 43758.5453);
}
vec2 rand2(vec2 x) {
return fract(sin(vec2(dot(x, vec2(13.9898, 8.141)),
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(sin(vec3(dot(x, vec2(13.9898, 8.141)),
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);
}
@ -129,19 +129,21 @@ vec2 transform(vec2 uv, vec2 translate, float rotate, float scale) {
return rv;
}
float bricks(vec2 uv, vec2 count, float offset, float mortar, float bevel) {
vec3 bricks(vec2 uv, vec2 count, float offset, float mortar, float bevel) {
mortar /= max(count.x, count.y);
bevel /= max(count.x, count.y);
float fract_x = fract(uv.x*count.x+offset*step(0.5, fract(uv.y*count.y*0.5)));
float x = uv.x*count.x+offset*step(0.5, fract(uv.y*count.y*0.5));
float fract_x = fract(x);
float slope_x = 1.0/(bevel*count.x);
float off = 0.5*mortar/bevel;
float f1 = fract_x*slope_x-off;
float f2 = (1.0-fract_x)*slope_x-off;
float y = uv.y*count.y;
float fract_y = fract(uv.y*count.y);
float slope_y = 1.0/(bevel*count.y);
float f3 = fract_y*slope_y-off;
float f4 = (1.0-fract_y)*slope_y-off;
return max(0.0, min(1.0, min(min(f1, f2), min(f3, f4))));
return vec3(max(0.0, min(1.0, min(min(f1, f2), min(f3, f4)))), floor(mod(x, count.x)), floor(mod(y, count.y)));
}
float colored_bricks(vec2 uv, vec2 count, float offset) {

View File

@ -91,32 +91,6 @@ func send_changed_signal():
func do_send_changed_signal():
emit_signal("graph_changed")
func generate_shader(node):
var code
code = "shader_type canvas_item;\n\n"
var file = File.new()
file.open("res://addons/procedural_material/common.shader", File.READ)
code += file.get_as_text()
code += "\n"
for c in get_children():
if c is GraphNode:
c.generated = false
c.generated_variants = []
var src_code = node.get_shader_code("UV")
var shader_code = src_code.defs
shader_code += "void fragment() {\n"
shader_code += src_code.code
if src_code.has("rgb"):
shader_code += "COLOR = vec4("+src_code.rgb+", 1.0);\n"
elif src_code.has("f"):
shader_code += "COLOR = vec4(vec3("+src_code.f+"), 1.0);\n"
else:
shader_code += "COLOR = vec4(1.0);\n"
shader_code += "}\n"
#print("GENERATED SHADER:\n"+shader_code)
code += shader_code
return code
func setup_material(shader_material, textures, shader_code):
for k in textures.keys():
shader_material.set_shader_param(k+"_tex", textures[k])
@ -127,7 +101,7 @@ func setup_material(shader_material, textures, shader_code):
var render_queue = []
func render_to_viewport(node, size, method, args):
render_queue.append( { shader=generate_shader(node), textures=node.get_textures(), size=size, method=method, args=args } )
render_queue.append( { shader=node.generate_shader(), textures=node.get_textures(), size=size, method=method, args=args } )
if render_queue.size() == 1:
while !render_queue.empty():
var job = render_queue.front()

View File

@ -1,6 +1,19 @@
tool
extends GraphNode
class OutPort:
var node = null
var port = null
func get_shader_code(uv):
return node.get_shader_code(uv, port)
func generate_shader():
return node.generate_shader(port)
func get_textures():
return node.get_textures()
var generated = false
var generated_variants = []
@ -55,10 +68,15 @@ func _on_color_changed(new_color, variable):
update_shaders()
func get_source(index = 0):
for c in get_parent().get_children():
if c != self && c is GraphNode:
if get_parent().is_node_connected(c.name, 0, name, index):
return c
for c in get_parent().get_connection_list():
if c.to == name and c.to_port == index:
if c.from_port == 0:
return get_parent().get_node(c.from)
else:
var out_port = OutPort.new()
out_port.node = get_parent().get_node(c.from)
out_port.port = c.from_port
return out_port
return null
func get_source_f(source):
@ -81,8 +99,12 @@ func get_source_rgb(source):
rv = "***error***"
return rv
func get_shader_code(uv):
var rv = _get_shader_code(uv)
func get_shader_code(uv, slot = 0):
var rv
if slot == 0:
rv = _get_shader_code(uv)
else:
rv = _get_shader_code(uv, slot)
if !rv.has("f"):
if rv.has("rgb"):
rv.f = "(dot("+rv.rgb+", vec3(1.0))/3.0)"
@ -116,6 +138,27 @@ func deserialize_element(e):
return Color(e.r, e.g, e.b, e.a)
return e
func generate_shader(slot = 0):
var code
code = "shader_type canvas_item;\n\n"
var file = File.new()
file.open("res://addons/procedural_material/common.shader", File.READ)
code += file.get_as_text()
code += "\n"
for c in get_parent().get_children():
if c is GraphNode:
c.generated = false
c.generated_variants = []
var src_code = get_shader_code("UV", slot)
var shader_code = src_code.defs
shader_code += "void fragment() {\n"
shader_code += src_code.code
shader_code += "COLOR = vec4("+src_code.rgb+", 1.0);\n"
shader_code += "}\n"
#print("GENERATED SHADER:\n"+shader_code)
code += shader_code
return code
func serialize():
var type = get_script().resource_path
type = type.right(type.find_last("/")+1)

View File

@ -9,16 +9,19 @@ var bevel
func _ready():
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
initialize_properties([ $GridContainer/rows, $GridContainer/columns, $GridContainer/row_offset, $GridContainer/mortar, $GridContainer/bevel ])
initialize_properties([ $HBoxContainer1/rows, $HBoxContainer2/columns, $HBoxContainer3/row_offset, $HBoxContainer4/mortar, $HBoxContainer5/bevel ])
func _get_shader_code(uv):
func _get_shader_code(uv, slot = 0):
var rv = { defs="", code="" }
if generated_variants.empty():
rv.defs = "float "+name+"_f(vec2 uv) { return bricks(uv, vec2("+str(columns)+", "+str(rows)+"), "+str(row_offset)+", "+str(mortar)+", "+str(max(0.001, bevel))+"); }\n"
rv.defs = "vec3 "+name+"_xyz(vec2 uv) { return bricks(uv, vec2("+str(columns)+", "+str(rows)+"), "+str(row_offset)+", "+str(mortar)+", "+str(max(0.001, bevel))+"); }\n"
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
generated_variants.append(uv)
rv.code = "float "+name+"_"+str(variant_index)+"_f = "+name+"_f("+uv+");\n"
rv.f = name+"_"+str(variant_index)+"_f"
rv.code = "vec3 "+name+"_"+str(variant_index)+"_xyz = "+name+"_xyz("+uv+");\n"
if slot == 0:
rv.f = name+"_"+str(variant_index)+"_xyz.x"
else:
rv.rgb = "rand3("+name+"_"+str(variant_index)+"_xyz.yz)"
return rv

View File

@ -13,7 +13,7 @@ anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 1.0
margin_right = 171.0
margin_bottom = 165.0
margin_bottom = 154.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
@ -34,10 +34,34 @@ slot/0/left_color = Color( 0.5, 0.5, 1, 1 )
slot/0/right_enabled = true
slot/0/right_type = 0
slot/0/right_color = Color( 0.5, 0.5, 1, 1 )
slot/1/left_enabled = false
slot/1/left_type = 0
slot/1/left_color = Color( 0.498039, 0.498039, 1, 1 )
slot/1/right_enabled = true
slot/1/right_type = 0
slot/1/right_color = Color( 0.498039, 0.498039, 1, 1 )
slot/2/left_enabled = false
slot/2/left_type = 0
slot/2/left_color = Color( 1, 1, 1, 1 )
slot/2/right_enabled = false
slot/2/right_type = 0
slot/2/right_color = Color( 1, 1, 1, 1 )
slot/3/left_enabled = false
slot/3/left_type = 0
slot/3/left_color = Color( 1, 1, 1, 1 )
slot/3/right_enabled = false
slot/3/right_type = 0
slot/3/right_color = Color( 1, 1, 1, 1 )
slot/4/left_enabled = false
slot/4/left_type = 0
slot/4/left_color = Color( 1, 1, 1, 1 )
slot/4/right_enabled = false
slot/4/right_type = 0
slot/4/right_color = Color( 1, 1, 1, 1 )
script = ExtResource( 1 )
_sections_unfolded = [ "Mouse", "Theme" ]
_sections_unfolded = [ "Mouse", "Theme", "slot", "slot/0", "slot/1" ]
[node name="GridContainer" type="GridContainer" parent="." index="0"]
[node name="HBoxContainer1" type="HBoxContainer" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
@ -46,16 +70,16 @@ anchor_bottom = 0.0
margin_left = 16.0
margin_top = 24.0
margin_right = 154.0
margin_bottom = 160.0
margin_bottom = 48.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
columns = 2
alignment = 0
[node name="Label1" type="Label" parent="GridContainer" index="0"]
[node name="Label1" type="Label" parent="HBoxContainer1" index="0"]
anchor_left = 0.0
anchor_top = 0.0
@ -68,14 +92,14 @@ rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_horizontal = 3
size_flags_vertical = 4
text = "Rows:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="rows" type="SpinBox" parent="GridContainer" index="1"]
[node name="rows" type="SpinBox" parent="HBoxContainer1" index="1"]
anchor_left = 0.0
anchor_top = 0.0
@ -88,7 +112,7 @@ rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_horizontal = 9
size_flags_vertical = 1
min_value = 1.0
max_value = 64.0
@ -102,41 +126,58 @@ prefix = ""
suffix = ""
_sections_unfolded = [ "Caret", "Placeholder" ]
[node name="Label2" type="Label" parent="GridContainer" index="2"]
[node name="HBoxContainer2" type="HBoxContainer" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 33.0
margin_left = 16.0
margin_top = 48.0
margin_right = 154.0
margin_bottom = 72.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="Label2" type="Label" parent="HBoxContainer2" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 5.0
margin_right = 60.0
margin_bottom = 47.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_horizontal = 3
size_flags_vertical = 4
text = "Columns:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="columns" type="SpinBox" parent="GridContainer" index="3"]
[node name="columns" type="SpinBox" parent="HBoxContainer2" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 64.0
margin_top = 28.0
margin_right = 138.0
margin_bottom = 52.0
margin_bottom = 24.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_horizontal = 9
size_flags_vertical = 1
min_value = 1.0
max_value = 64.0
@ -150,41 +191,58 @@ prefix = ""
suffix = ""
_sections_unfolded = [ "Caret", "Placeholder" ]
[node name="Label3" type="Label" parent="GridContainer" index="4"]
[node name="HBoxContainer3" type="HBoxContainer" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 61.0
margin_left = 16.0
margin_top = 73.0
margin_right = 154.0
margin_bottom = 97.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="Label3" type="Label" parent="HBoxContainer3" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 5.0
margin_right = 60.0
margin_bottom = 75.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_horizontal = 3
size_flags_vertical = 4
text = "Offset:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="row_offset" type="SpinBox" parent="GridContainer" index="5"]
[node name="row_offset" type="SpinBox" parent="HBoxContainer3" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 64.0
margin_top = 56.0
margin_right = 138.0
margin_bottom = 80.0
margin_bottom = 24.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_horizontal = 9
size_flags_vertical = 1
min_value = 0.0
max_value = 1.0
@ -198,41 +256,58 @@ prefix = ""
suffix = ""
_sections_unfolded = [ "Caret", "Placeholder" ]
[node name="Label4" type="Label" parent="GridContainer" index="6"]
[node name="HBoxContainer4" type="HBoxContainer" parent="." index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 89.0
margin_left = 16.0
margin_top = 98.0
margin_right = 154.0
margin_bottom = 122.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="Label4" type="Label" parent="HBoxContainer4" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 5.0
margin_right = 60.0
margin_bottom = 103.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_horizontal = 3
size_flags_vertical = 4
text = "Mortar:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="mortar" type="SpinBox" parent="GridContainer" index="7"]
[node name="mortar" type="SpinBox" parent="HBoxContainer4" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 64.0
margin_top = 84.0
margin_right = 138.0
margin_bottom = 108.0
margin_bottom = 24.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_horizontal = 9
size_flags_vertical = 1
min_value = 0.0
max_value = 1.0
@ -246,41 +321,58 @@ prefix = ""
suffix = ""
_sections_unfolded = [ "Caret", "Placeholder" ]
[node name="Label5" type="Label" parent="GridContainer" index="8"]
[node name="HBoxContainer5" type="HBoxContainer" parent="." index="4"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 117.0
margin_left = 16.0
margin_top = 123.0
margin_right = 154.0
margin_bottom = 147.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="Label5" type="Label" parent="HBoxContainer5" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 5.0
margin_right = 60.0
margin_bottom = 131.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_horizontal = 3
size_flags_vertical = 4
text = "Bevel:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="bevel" type="SpinBox" parent="GridContainer" index="9"]
[node name="bevel" type="SpinBox" parent="HBoxContainer5" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 64.0
margin_top = 112.0
margin_right = 138.0
margin_bottom = 136.0
margin_bottom = 24.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_horizontal = 9
size_flags_vertical = 1
min_value = 0.0
max_value = 1.0

View File

@ -9,7 +9,7 @@ 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 ])
func _get_shader_code(uv):
func _get_shader_code(uv, slot = 0):
var rv = { defs="", code="" }
if generated_variants.empty():
rv.defs = "vec4 "+name+"_xyzw(vec2 uv) { return voronoi(uv, vec2(%f, %f), %.9f, %d); }\n" % [ scale_x, scale_y, intensity, get_seed() ]
@ -18,7 +18,12 @@ func _get_shader_code(uv):
variant_index = generated_variants.size()
generated_variants.append(uv)
rv.code = "vec4 "+name+"_"+str(variant_index)+"_xyzw = "+name+"_xyzw("+uv+");\n"
if slot == 0:
rv.f = name+"_"+str(variant_index)+"_xyzw.z"
elif slot == 1:
rv.f = name+"_"+str(variant_index)+"_xyzw.w"
else:
rv.rgb = "rand3("+name+"_"+str(variant_index)+"_xyzw.xy)"
return rv
func _on_offset_changed():

View File

@ -5,7 +5,7 @@
[sub_resource type="Theme" id=1]
[node name="Voronoi" type="GraphNode"]
[node name="Voronoi" type="GraphNode" index="0"]
anchor_left = 0.0
anchor_top = 0.0
@ -37,18 +37,18 @@ slot/0/right_type = 0
slot/0/right_color = Color( 0.5, 0.5, 1, 1 )
slot/1/left_enabled = false
slot/1/left_type = 0
slot/1/left_color = Color( 1, 1, 1, 1 )
slot/1/right_enabled = false
slot/1/left_color = Color( 0.498039, 0.498039, 1, 1 )
slot/1/right_enabled = true
slot/1/right_type = 0
slot/1/right_color = Color( 1, 1, 1, 1 )
slot/1/right_color = Color( 0.498039, 0.498039, 1, 1 )
slot/2/left_enabled = false
slot/2/left_type = 0
slot/2/left_color = Color( 1, 1, 1, 1 )
slot/2/right_enabled = false
slot/2/left_color = Color( 0.498039, 0.498039, 1, 1 )
slot/2/right_enabled = true
slot/2/right_type = 0
slot/2/right_color = Color( 1, 1, 1, 1 )
slot/2/right_color = Color( 0.498039, 0.498039, 1, 1 )
script = ExtResource( 1 )
_sections_unfolded = [ "Theme" ]
_sections_unfolded = [ "Theme", "slot", "slot/0", "slot/1", "slot/2" ]
[node name="HBoxContainer1" type="HBoxContainer" parent="." index="0"]

View File

@ -138,10 +138,10 @@ func generate_shader():
if $GraphEdit/Material != null:
$GraphEdit/Material.update_materials($Preview/Preview.get_materials())
if selected_node != null && selected_node is GraphNode:
$GraphEdit.setup_material(texture_preview_material, selected_node.get_textures(), $GraphEdit.generate_shader(selected_node))
$GraphEdit.setup_material(texture_preview_material, selected_node.get_textures(), selected_node.generate_shader())
func _on_GraphEdit_node_selected(node):
if selected_node != node && node is GraphNode:
selected_node = node
$GraphEdit.setup_material(texture_preview_material, selected_node.get_textures(), $GraphEdit.generate_shader(selected_node))
$GraphEdit.setup_material(texture_preview_material, selected_node.get_textures(), selected_node.generate_shader())

View File

@ -534,7 +534,7 @@ tracks/2/keys = {
"values": [ 3 ]
}
[node name="ProceduralMaterialEditor" type="MarginContainer" index="0"]
[node name="ProceduralMaterialEditor" type="MarginContainer"]
anchor_left = 0.0
anchor_top = 0.0
@ -720,7 +720,7 @@ _sections_unfolded = [ "GUI", "Render Target" ]
[node name="Objects" type="Spatial" parent="Preview/Preview/MaterialPreview" index="0"]
transform = Transform( -0.730986, 0, -0.682388, 0, 1, 0, 0.682388, 0, -0.730986, 0, 0, 0 )
transform = Transform( -0.0754918, 0, -0.997143, 0, 1, 0, 0.997143, 0, -0.0754918, 0, 0, 0 )
_sections_unfolded = [ "Transform" ]
[node name="Cube" type="MeshInstance" parent="Preview/Preview/MaterialPreview/Objects" index="0"]

View File

@ -1 +1 @@
{"connections":[{"from":"Bricks","from_port":0,"to":"Warp","to_port":0},{"from":"Perlin","from_port":0,"to":"Warp","to_port":1},{"from":"Perlin2","from_port":0,"to":"colorize_0","to_port":0},{"from":"Perlin2","from_port":0,"to":"colorize_1","to_port":0},{"from":"Warp","from_port":0,"to":"colorize_2","to_port":0},{"from":"colorize_2","from_port":0,"to":"blend_0","to_port":2},{"from":"colorize_1","from_port":0,"to":"blend_0","to_port":0},{"from":"colorize_0","from_port":0,"to":"blend_0","to_port":1},{"from":"Warp","from_port":0,"to":"colorize_3","to_port":0},{"from":"blend_0","from_port":0,"to":"Material","to_port":0},{"from":"Warp","from_port":0,"to":"normal_map_0","to_port":0},{"from":"normal_map_0","from_port":0,"to":"Material","to_port":4},{"from":"colorize_3","from_port":0,"to":"Material","to_port":5},{"from":"colorize_2","from_port":0,"to":"colorize_4","to_port":0},{"from":"colorize_4","from_port":0,"to":"Material","to_port":2},{"from":"colorize_2","from_port":0,"to":"colorize_5","to_port":0},{"from":"colorize_5","from_port":0,"to":"Material","to_port":1}],"nodes":[{"bevel":0.2,"columns":3,"mortar":0.05,"name":"Bricks","node_position":{"x":260,"y":132},"row_offset":0.5,"rows":6,"type":"bricks"},{"iterations":6,"name":"Perlin","node_position":{"x":255,"y":322},"persistence":0.5,"scale_x":4,"scale_y":4,"type":"perlin"},{"amount":0.1,"name":"Warp","node_position":{"x":504,"y":199.75},"type":"warp"},{"name":"Material","node_position":{"x":1024,"y":204},"type":"material"},{"iterations":7,"name":"Perlin2","node_position":{"x":253,"y":-28},"persistence":0.75,"scale_x":8,"scale_y":8,"type":"perlin"},{"gradient":[{"b":0.273438,"g":0.273438,"pos":0,"r":0.273438},{"b":0,"g":0,"pos":1,"r":0}],"name":"colorize_3","node_position":{"x":631,"y":363},"type":"colorize"},{"amount":0.5,"name":"normal_map_0","node_position":{"x":691,"y":295},"type":"normal_map"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":0.054545,"r":1}],"name":"colorize_2","node_position":{"x":633.943665,"y":146},"type":"colorize"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":0,"g":0,"pos":1,"r":0}],"name":"colorize_5","node_position":{"x":837,"y":157},"type":"colorize"},{"gradient":[{"b":1,"g":1,"pos":0,"r":1},{"b":0.672727,"g":0.672727,"pos":1,"r":0.672727}],"name":"colorize_4","node_position":{"x":719,"y":224},"type":"colorize"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":1,"r":1}],"name":"colorize_0","node_position":{"x":560.943665,"y":50},"type":"colorize"},{"gradient":[{"b":0.002889,"g":0.102424,"pos":0,"r":0.184896},{"b":0,"g":0.19869,"pos":0.327273,"r":0.669271},{"b":0.019368,"g":0.060224,"pos":0.645455,"r":0.309896},{"b":0,"g":0.180135,"pos":1,"r":0.606771}],"name":"colorize_1","node_position":{"x":562.943665,"y":-65},"type":"colorize"},{"amount":0.5,"blend_type":0,"name":"blend_0","node_position":{"x":820.943726,"y":-33},"type":"blend"}]}
{"connections":[{"from":"Perlin","from_port":0,"to":"Warp","to_port":1},{"from":"Warp","from_port":0,"to":"colorize_2","to_port":0},{"from":"colorize_2","from_port":0,"to":"blend_0","to_port":2},{"from":"colorize_1","from_port":0,"to":"blend_0","to_port":0},{"from":"colorize_0","from_port":0,"to":"blend_0","to_port":1},{"from":"blend_0","from_port":0,"to":"Material","to_port":0},{"from":"normal_map_0","from_port":0,"to":"Material","to_port":4},{"from":"colorize_2","from_port":0,"to":"colorize_4","to_port":0},{"from":"colorize_4","from_port":0,"to":"Material","to_port":2},{"from":"colorize_2","from_port":0,"to":"colorize_5","to_port":0},{"from":"colorize_5","from_port":0,"to":"Material","to_port":1},{"from":"Bricks","from_port":0,"to":"Warp","to_port":0},{"from":"blend_1","from_port":0,"to":"colorize_1","to_port":0},{"from":"Bricks","from_port":1,"to":"blend_1","to_port":1},{"from":"Warp","from_port":0,"to":"blend_2","to_port":0},{"from":"Perlin","from_port":0,"to":"blend_2","to_port":1},{"from":"blend_2","from_port":0,"to":"colorize_3","to_port":0},{"from":"blend_2","from_port":0,"to":"colorize_6","to_port":0},{"from":"colorize_6","from_port":0,"to":"normal_map_0","to_port":0},{"from":"Perlin","from_port":0,"to":"blend_1","to_port":0},{"from":"Perlin","from_port":0,"to":"colorize_0","to_port":0}],"nodes":[{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":0,"g":0,"pos":1,"r":0}],"name":"colorize_5","node_position":{"x":837,"y":157},"type":"colorize"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":1,"r":1}],"name":"colorize_0","node_position":{"x":560.943665,"y":50},"type":"colorize"},{"gradient":[{"b":0.0016,"g":0.0016,"pos":0,"r":0.307292},{"b":0,"g":0.180135,"pos":0.2,"r":0.606771},{"b":0,"g":0,"pos":0.363636,"r":0.3125},{"b":0,"g":0.19869,"pos":0.572727,"r":0.669271},{"b":0.019368,"g":0.060224,"pos":0.736364,"r":0.309896},{"b":0,"g":0.180135,"pos":1,"r":0.606771}],"name":"colorize_1","node_position":{"x":562.943665,"y":-65},"type":"colorize"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":0.273438,"g":0.273438,"pos":1,"r":0.273438}],"name":"colorize_3","node_position":{"x":763,"y":373},"type":"colorize"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":0.1,"r":1}],"name":"colorize_2","node_position":{"x":535.943665,"y":163},"type":"colorize"},{"amount":0.5,"blend_type":6,"name":"blend_1","node_position":{"x":350,"y":244},"type":"blend"},{"bevel":0.2,"columns":3,"mortar":0.05,"name":"Bricks","node_position":{"x":118,"y":-22},"row_offset":0.5,"rows":6,"type":"bricks"},{"amount":0.04,"name":"Warp","node_position":{"x":384,"y":10.75},"type":"warp"},{"name":"Material","node_position":{"x":1081,"y":208},"type":"material"},{"amount":0.5,"name":"normal_map_0","node_position":{"x":925,"y":305},"type":"normal_map"},{"gradient":[{"b":1,"g":1,"pos":0,"r":1},{"b":0,"g":0,"pos":1,"r":0}],"name":"colorize_6","node_position":{"x":743,"y":291},"type":"colorize"},{"amount":0.5,"blend_type":0,"name":"blend_2","node_position":{"x":536,"y":331},"type":"blend"},{"gradient":[{"b":1,"g":1,"pos":0,"r":1},{"b":0.463542,"g":0.463542,"pos":1,"r":0.463542}],"name":"colorize_4","node_position":{"x":708,"y":224},"type":"colorize"},{"iterations":6,"name":"Perlin","node_position":{"x":107,"y":170},"persistence":0.85,"scale_x":4,"scale_y":4,"type":"perlin"},{"amount":0.5,"blend_type":0,"name":"blend_0","node_position":{"x":836.943726,"y":-71},"type":"blend"}]}