diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..37f05f2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.import diff --git a/addons/procedural_material/boolean.gd b/addons/procedural_material/boolean.gd new file mode 100644 index 0000000..5eb41d0 --- /dev/null +++ b/addons/procedural_material/boolean.gd @@ -0,0 +1,21 @@ +tool +extends "res://addons/procedural_material/node_base.gd" + +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)) + +func get_shader_code(uv): + var rv = { defs="", code="", uv=null, rgb=null, f=null } + var src0 = get_source(0) + var src1 = get_source(1) + if src0 == null || src1 == null: + return rv + var src0_code = src0.get_shader_code(uv) + var src1_code = src1.get_shader_code(uv) + if !generated: + rv.defs = src0_code.defs+src1_code.defs + rv.code = "float "+name+"_f = "+src0_code.f+"+"+src1_code.f+";\n" + generated = true + rv.f = name+"_f" + return rv diff --git a/addons/procedural_material/boolean.tscn b/addons/procedural_material/boolean.tscn new file mode 100644 index 0000000..22d5b44 --- /dev/null +++ b/addons/procedural_material/boolean.tscn @@ -0,0 +1,103 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/procedural_material/boolean.gd" type="Script" id=1] + +[sub_resource type="Theme" id=1] + + +[node name="Boolean" type="GraphNode" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 329.0 +margin_top = 117.0 +margin_right = 462.0 +margin_bottom = 279.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 +theme = SubResource( 1 ) +title = "Boolean" +offset = Vector2( 0, 0 ) +show_close = true +resizable = false +selected = false +comment = false +overlay = 0 +slot/0/left_enabled = true +slot/0/left_type = 0 +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 = true +slot/1/left_type = 0 +slot/1/left_color = Color( 0.5, 0.5, 1, 1 ) +slot/1/right_enabled = false +slot/1/right_type = 0 +slot/1/right_color = Color( 0.5, 0.5, 1, 1 ) +script = ExtResource( 1 ) +_sections_unfolded = [ "Theme" ] + +[node name="OptionButton" type="OptionButton" 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 = 117.0 +margin_bottom = 44.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 +action_mode = 0 +enabled_focus_mode = 2 +shortcut = null +group = null +flat = false +align = 0 +items = [ ] +selected = -1 + +[node name="OptionButton2" type="OptionButton" parent="." index="1"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 16.0 +margin_top = 44.0 +margin_right = 117.0 +margin_bottom = 64.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 +action_mode = 0 +enabled_focus_mode = 2 +shortcut = null +group = null +flat = false +align = 0 +items = [ ] +selected = -1 + +[connection signal="close_request" from="." to="." method="queue_free"] + + diff --git a/addons/procedural_material/bricks.gd b/addons/procedural_material/bricks.gd new file mode 100644 index 0000000..3998d60 --- /dev/null +++ b/addons/procedural_material/bricks.gd @@ -0,0 +1,23 @@ +tool +extends "res://addons/procedural_material/node_base.gd" + +var rows +var columns +var row_offset +var mortar +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 ]) + +func get_shader_code(uv): + var rv = { defs="", code="", rgb=null, f=null } + if !generated: + rv.defs = "float "+name+"_f(vec2 uv) { return bricks(uv, vec2("+str(rows)+", "+str(columns)+"), "+str(row_offset)+", "+str(mortar)+", "+str(bevel)+"); }\n" + generated = true + rv.f = name+"_f("+uv+")" + return rv + +func _get_state_variables(): + return [ "rows", "columns", "row_offset", "mortar", "bevel" ] diff --git a/addons/procedural_material/bricks.tscn b/addons/procedural_material/bricks.tscn new file mode 100644 index 0000000..2ea26dd --- /dev/null +++ b/addons/procedural_material/bricks.tscn @@ -0,0 +1,290 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/procedural_material/bricks.gd" type="Script" id=1] + +[sub_resource type="Theme" id=1] + + +[node name="Bricks" type="GraphNode" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 251.0 +margin_top = 121.0 +margin_right = 405.0 +margin_bottom = 286.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 +theme = SubResource( 1 ) +title = "Bricks" +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( 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 ) +script = ExtResource( 1 ) +_sections_unfolded = [ "Theme" ] + +[node name="GridContainer" type="GridContainer" 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 = 138.0 +margin_bottom = 160.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 + +[node name="Label1" type="Label" parent="GridContainer" 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 = 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 = "Rows:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="rows" type="LineEdit" parent="GridContainer" index="1"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 64.0 +margin_right = 122.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 = 1 +size_flags_vertical = 1 +text = "3" +focus_mode = 2 +context_menu_enabled = true +placeholder_alpha = 0.6 +caret_blink = false +caret_blink_speed = 0.65 +caret_position = 0 +_sections_unfolded = [ "Caret", "Placeholder" ] + +[node name="Label2" type="Label" parent="GridContainer" index="2"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 33.0 +margin_right = 60.0 +margin_bottom = 47.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 = "Columns:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="columns" type="LineEdit" parent="GridContainer" index="3"] + +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 = 122.0 +margin_bottom = 52.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 = 1 +size_flags_vertical = 1 +text = "6" +focus_mode = 2 +context_menu_enabled = true +placeholder_alpha = 0.6 +caret_blink = false +caret_blink_speed = 0.65 +caret_position = 0 +_sections_unfolded = [ "Caret", "Placeholder" ] + +[node name="Label3" type="Label" parent="GridContainer" index="4"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 61.0 +margin_right = 60.0 +margin_bottom = 75.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 = "Offset:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="row_offset" type="LineEdit" parent="GridContainer" index="5"] + +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 = 122.0 +margin_bottom = 80.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 = 1 +size_flags_vertical = 1 +text = "0.5" +focus_mode = 2 +context_menu_enabled = true +placeholder_alpha = 0.6 +caret_blink = false +caret_blink_speed = 0.65 +caret_position = 0 +_sections_unfolded = [ "Caret", "Placeholder" ] + +[node name="Label4" type="Label" parent="GridContainer" index="6"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 89.0 +margin_right = 60.0 +margin_bottom = 103.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 = "Mortar:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="mortar" type="LineEdit" parent="GridContainer" index="7"] + +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 = 122.0 +margin_bottom = 108.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 = 1 +size_flags_vertical = 1 +text = "0.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 = [ "Caret", "Placeholder" ] + +[node name="Label5" type="Label" parent="GridContainer" index="8"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 117.0 +margin_right = 60.0 +margin_bottom = 131.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 = "Bevel:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="bevel" type="LineEdit" parent="GridContainer" index="9"] + +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 = 122.0 +margin_bottom = 136.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 = 1 +size_flags_vertical = 1 +text = "0.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 = [ "Caret", "Placeholder" ] + +[connection signal="close_request" from="." to="." method="queue_free"] + + diff --git a/addons/procedural_material/graph_edit.gd b/addons/procedural_material/graph_edit.gd new file mode 100644 index 0000000..69294f4 --- /dev/null +++ b/addons/procedural_material/graph_edit.gd @@ -0,0 +1,15 @@ +tool +extends GraphEdit + +func _ready(): + pass + +func get_source(node, port): + for c in get_connection_list(): + if c.to == node && c.to_port == port: + return { node=c.from, slot=c.from_port } + +func remove_node(node): + for c in get_connection_list(): + if c.from == node or c.to == node: + disconnect_node(c.from, c.from_port, c.to, c.to_port) \ No newline at end of file diff --git a/addons/procedural_material/iqnoise.gd b/addons/procedural_material/iqnoise.gd new file mode 100644 index 0000000..5671351 --- /dev/null +++ b/addons/procedural_material/iqnoise.gd @@ -0,0 +1,18 @@ +tool +extends "res://addons/procedural_material/node_base.gd" + +var subdivide +var u +var v + +func _ready(): + set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) + initialize_properties([ $GridContainer/subdivide, $GridContainer/u, $GridContainer/v ]) + +func get_shader_code(uv): + var rv = { defs="", code="", rgb=null, f=null } + if !generated: + rv.defs = "float "+name+"_f(vec2 uv) { return iqnoise(uv, "+str(subdivide)+", "+str(u)+", "+str(v)+"); }\n" + generated = true + rv.f = name+"_f("+uv+")" + return rv diff --git a/addons/procedural_material/iqnoise.tscn b/addons/procedural_material/iqnoise.tscn new file mode 100644 index 0000000..a759705 --- /dev/null +++ b/addons/procedural_material/iqnoise.tscn @@ -0,0 +1,198 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/procedural_material/iqnoise.gd" type="Script" id=1] + +[sub_resource type="Theme" id=1] + + +[node name="IQNoise" type="GraphNode" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 1.0 +margin_top = 2.0 +margin_right = 161.0 +margin_bottom = 139.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 +theme = SubResource( 1 ) +title = "IQNoise" +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( 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 ) +script = ExtResource( 1 ) +_sections_unfolded = [ "Theme" ] + +[node name="GridContainer" type="GridContainer" 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 = 144.0 +margin_bottom = 104.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 + +[node name="Label1" type="Label" parent="GridContainer" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 5.0 +margin_right = 66.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 = "Subdivide:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="subdivide" type="LineEdit" parent="GridContainer" index="1"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 70.0 +margin_right = 128.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 = 1 +size_flags_vertical = 1 +text = "3" +focus_mode = 2 +context_menu_enabled = true +placeholder_alpha = 0.6 +caret_blink = false +caret_blink_speed = 0.65 +caret_position = 0 +_sections_unfolded = [ "Caret", "Placeholder" ] + +[node name="Label2" type="Label" parent="GridContainer" index="2"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 33.0 +margin_right = 66.0 +margin_bottom = 47.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 = "U:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="u" type="LineEdit" parent="GridContainer" index="3"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 70.0 +margin_top = 28.0 +margin_right = 128.0 +margin_bottom = 52.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 = 1 +size_flags_vertical = 1 +text = "0.5" +focus_mode = 2 +context_menu_enabled = true +placeholder_alpha = 0.6 +caret_blink = false +caret_blink_speed = 0.65 +caret_position = 0 +_sections_unfolded = [ "Caret", "Placeholder" ] + +[node name="Label3" type="Label" parent="GridContainer" index="4"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 61.0 +margin_right = 66.0 +margin_bottom = 75.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 = "V:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="v" type="LineEdit" parent="GridContainer" index="5"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 70.0 +margin_top = 56.0 +margin_right = 128.0 +margin_bottom = 80.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 = 1 +size_flags_vertical = 1 +text = "0.5" +focus_mode = 2 +context_menu_enabled = true +placeholder_alpha = 0.6 +caret_blink = false +caret_blink_speed = 0.65 +caret_position = 0 +_sections_unfolded = [ "Caret", "Placeholder" ] + +[connection signal="close_request" from="." to="." method="queue_free"] + + diff --git a/addons/procedural_material/material.gd b/addons/procedural_material/material.gd new file mode 100644 index 0000000..2103bfa --- /dev/null +++ b/addons/procedural_material/material.gd @@ -0,0 +1,25 @@ +tool +extends "res://addons/procedural_material/node_base.gd" + +func _ready(): + set_slot(0, true, 0, Color(0.5, 0.5, 1), false, 0, Color(0.5, 0.5, 1)) + +func get_shader_code(uv): + var rv = { defs="", code="", rgb=null, f=null } + var src = get_source() + if src == null: + rv.code += "void fragment() {\n" + rv.code += "COLOR = vec4(0.0, 0.0, 0.0, 1.0);" + else: + var src_code = src.get_shader_code("UV") + rv.code += src_code.defs + rv.code += "void fragment() {\n" + rv.code += src_code.code+"\n" + if src_code.rgb != null: + rv.code += "vec3 "+name+"_rgb = "+src_code.rgb+"\n" + rv.code += "COLOR = vec4("+name+"_rgb.r, "+name+"_rgb.g, "+name+"_rgb.b, 1.0);" + elif src_code.f != null: + rv.code += "float "+name+"_f = "+src_code.f+";\n" + rv.code += "COLOR = vec4("+name+"_f, "+name+"_f, "+name+"_f, 1.0);" + rv.code += "\n}\n" + return rv \ No newline at end of file diff --git a/addons/procedural_material/material.tscn b/addons/procedural_material/material.tscn new file mode 100644 index 0000000..6b26c55 --- /dev/null +++ b/addons/procedural_material/material.tscn @@ -0,0 +1,62 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/procedural_material/material.gd" type="Script" id=1] + +[sub_resource type="Theme" id=1] + + +[node name="Material" type="GraphNode" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 550.0 +margin_top = 226.0 +margin_right = 683.0 +margin_bottom = 419.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 +theme = SubResource( 1 ) +title = "Material" +offset = Vector2( 0, 0 ) +show_close = false +resizable = false +selected = false +comment = false +overlay = 0 +slot/0/left_enabled = true +slot/0/left_type = 0 +slot/0/left_color = Color( 0.5, 0.5, 1, 1 ) +slot/0/right_enabled = false +slot/0/right_type = 0 +slot/0/right_color = Color( 0.5, 0.5, 1, 1 ) +script = ExtResource( 1 ) +_sections_unfolded = [ "Theme" ] + +[node name="Label" type="Label" 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 = 117.0 +margin_bottom = 38.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 = "Texture" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + + diff --git a/addons/procedural_material/node_base.gd b/addons/procedural_material/node_base.gd new file mode 100644 index 0000000..7a29335 --- /dev/null +++ b/addons/procedural_material/node_base.gd @@ -0,0 +1,28 @@ +tool +extends GraphNode + +var generated = false + +func _ready(): + pass + +func initialize_properties(object_list): + for o in object_list: + if o is LineEdit: + set(o.name, float(o.text)) + o.connect("text_changed", self, "_on_text_changed", [ o.name ]) + +func _on_text_changed(new_text, variable): + set(variable, float(new_text)) + get_parent().get_parent().generate_shader() + +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 + return null + +func queue_free(): + get_parent().remove_node(self.name) + .queue_free() diff --git a/addons/procedural_material/perlin.gd b/addons/procedural_material/perlin.gd new file mode 100644 index 0000000..e3422a1 --- /dev/null +++ b/addons/procedural_material/perlin.gd @@ -0,0 +1,17 @@ +tool +extends "res://addons/procedural_material/node_base.gd" + +var iterations +var turbulence + +func _ready(): + set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) + initialize_properties([ $GridContainer/iterations, $GridContainer/turbulence ]) + +func get_shader_code(uv): + var rv = { defs="", code="", rgb=null, f=null } + if !generated: + rv.defs = "float "+name+"_f(vec2 uv) { return perlin(uv, "+str(iterations)+", "+str(turbulence)+"); }\n" + generated = true + rv.f = name+"_f("+uv+")" + return rv diff --git a/addons/procedural_material/perlin.tscn b/addons/procedural_material/perlin.tscn new file mode 100644 index 0000000..f5de7a0 --- /dev/null +++ b/addons/procedural_material/perlin.tscn @@ -0,0 +1,152 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/procedural_material/perlin.gd" type="Script" id=1] + +[sub_resource type="Theme" id=1] + + +[node name="Perlin" type="GraphNode" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 1.0 +margin_top = 2.0 +margin_right = 166.0 +margin_bottom = 83.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 +theme = SubResource( 1 ) +title = "Perlin" +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( 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 ) +script = ExtResource( 1 ) +_sections_unfolded = [ "Theme" ] + +[node name="GridContainer" type="GridContainer" 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 = 149.0 +margin_bottom = 76.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 + +[node name="Label1" type="Label" parent="GridContainer" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 5.0 +margin_right = 71.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 = "Iterations:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="iterations" type="LineEdit" parent="GridContainer" index="1"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 75.0 +margin_right = 133.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 = 1 +size_flags_vertical = 1 +text = "3" +focus_mode = 2 +context_menu_enabled = true +placeholder_alpha = 0.6 +caret_blink = false +caret_blink_speed = 0.65 +caret_position = 0 +_sections_unfolded = [ "Caret", "Placeholder" ] + +[node name="Label2" type="Label" parent="GridContainer" index="2"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 33.0 +margin_right = 71.0 +margin_bottom = 47.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 = "Turbulence" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="turbulence" type="LineEdit" parent="GridContainer" index="3"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 75.0 +margin_top = 28.0 +margin_right = 133.0 +margin_bottom = 52.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 = 1 +size_flags_vertical = 1 +text = "0.5" +focus_mode = 2 +context_menu_enabled = true +placeholder_alpha = 0.6 +caret_blink = false +caret_blink_speed = 0.65 +caret_position = 0 +_sections_unfolded = [ "Caret", "Placeholder" ] + +[connection signal="close_request" from="." to="." method="queue_free"] + + diff --git a/addons/procedural_material/plugin.cfg b/addons/procedural_material/plugin.cfg new file mode 100644 index 0000000..31378ae --- /dev/null +++ b/addons/procedural_material/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="ProceduralMaterial" +description="Procedural Material creation tool" +author="RodZilla" +version="0.1" +script="plugin.gd" diff --git a/addons/procedural_material/plugin.gd b/addons/procedural_material/plugin.gd new file mode 100644 index 0000000..e2545a2 --- /dev/null +++ b/addons/procedural_material/plugin.gd @@ -0,0 +1,20 @@ +tool +extends EditorPlugin + +var editor = null + +func _enter_tree(): + editor = preload("res://addons/procedural_material/pm_editor.tscn").instance() + add_control_to_bottom_panel(editor, "ProceduralMaterial") + +func _exit_tree(): + remove_control_from_bottom_panel(editor) + editor.queue_free() + editor = null + +func _get_state(): + var s = {} + return s + +func _set_state(s): + pass diff --git a/addons/procedural_material/pm_editor.gd b/addons/procedural_material/pm_editor.gd new file mode 100644 index 0000000..b903121 --- /dev/null +++ b/addons/procedural_material/pm_editor.gd @@ -0,0 +1,54 @@ +tool +extends Container + +var popup_position = Vector2(0, 0) + +const MENU = [ + { name="sine", description="Sine" }, + { name="boolean", description="Boolean" }, + { name="bricks", description="Bricks" }, + { name="iqnoise", description="IQ Noise" }, + { name="perlin", description="Perlin noise" }, + { name="transform", description="Transform" } +] + +func _ready(): + $GraphEdit.add_valid_connection_type(0, 0) + $GraphEdit/PopupMenu.clear() + for i in MENU.size(): + $GraphEdit/PopupMenu.add_item(MENU[i].description, i) + +func _on_GraphEdit_popup_request(position): + popup_position = position + $GraphEdit/PopupMenu.popup(Rect2(position, $GraphEdit/PopupMenu.rect_size)) + +func _on_PopupMenu_id_pressed(id): + var node_type = null + node_type = load("res://addons/procedural_material/"+MENU[id].name+".tscn") + if node_type != null: + var node = node_type.instance() + $GraphEdit.add_child(node) + node.set_begin(popup_position) + +func _on_GraphEdit_connection_request(from, from_slot, to, to_slot): + var disconnect = $GraphEdit.get_source(to, to_slot) + if disconnect != null: + $GraphEdit.disconnect_node(disconnect.node, disconnect.slot, to, to_slot) + $GraphEdit.connect_node(from, from_slot, to, to_slot) + generate_shader(); + +func generate_shader(): + var code = "" + var file = File.new() + file.open("res://addons/procedural_material/shader_header.txt", File.READ) + while !file.eof_reached(): + code += file.get_line() + code += "\n" + for c in $GraphEdit.get_children(): + if c is GraphNode: + c.generated = false + var shader_code = $GraphEdit/Material.get_shader_code("UV") + code += shader_code.code + #print(code) + $Preview.material.shader.set_code(code) + diff --git a/addons/procedural_material/pm_editor.tscn b/addons/procedural_material/pm_editor.tscn new file mode 100644 index 0000000..ee3eaad --- /dev/null +++ b/addons/procedural_material/pm_editor.tscn @@ -0,0 +1,213 @@ +[gd_scene load_steps=6 format=2] + +[ext_resource path="res://addons/procedural_material/pm_editor.gd" type="Script" id=1] +[ext_resource path="res://addons/procedural_material/graph_edit.gd" type="Script" id=2] +[ext_resource path="res://addons/procedural_material/material.tscn" type="PackedScene" id=3] + +[sub_resource type="Shader" id=1] + +code = "shader_type canvas_item; + +float hash1(vec2 p) { + float q = dot(p,vec2(127.1,311.7)); + return fract(sin(q)*43758.5453); +} + +vec2 hash2(vec2 p) { + vec2 q = vec2( dot(p,vec2(127.1,311.7)), + dot(p,vec2(269.5,183.3)) ); + return fract(sin(q)*43758.5453); +} + +vec3 hash3(vec2 p) { + vec3 q = vec3( dot(p,vec2(127.1,311.7)), + dot(p,vec2(269.5,183.3)), + dot(p,vec2(419.2,371.9)) ); + return fract(sin(q)*43758.5453); +} + +float sine(vec2 uv, float count, float sharpness) { + return max(0.0, min(1.0, (0.5+sharpness*0.5*sin(count*3.1415928*2.0*uv.x)))); +} + +vec2 rotate(vec2 uv, float angle) { + vec2 rv; + rv.x = cos(angle)*uv.x + sin(angle)*uv.y; + rv.y = -sin(angle)*uv.x + cos(angle)*uv.y; + return rv; +} + +float 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 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 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 min(min(f1, f2), min(f3, f4)); +} + +float colored_bricks(vec2 uv, vec2 count, float offset) { + float x = floor(uv.x*count.x+offset*step(0.5, fract(uv.y*count.y*0.5))); + float y = floor(uv.y*count.y); + return fract(x/3.0+y/7.0); +} + +float iqnoise(vec2 uv, float s, float u, float v) { + uv *= s; + vec2 p = floor(uv); + vec2 f = fract(uv); + + float k = 1.0+63.0*pow(1.0-v,4.0); + + float va = 0.0; + float wt = 0.0; + for( int j=-2; j<=2; j++ ) + for( int i=-2; i<=2; i++ ) + { + vec2 g = vec2( float(i),float(j) ); + vec3 o = hash3( p + g )*vec3(u,u,1.0); + vec2 r = g - f + o.xy; + float d = dot(r,r); + float ww = pow( 1.0-smoothstep(0.0,1.414,sqrt(d)), k ); + va += o.z*ww; + wt += ww; + } + + return va/wt; +} + +float perlin(vec2 uv, int iterations, float turbulence) { + float f = 0.0; + float c = 1.0; + float s = 2.0; + float m = 0.0; + for(int i = 0; i < iterations; i++) { + vec2 uv2 = float(s) * uv; + vec2 uv2_floor = floor(uv2); + vec2 uv2_fract = fract(uv2); + f += c * ( (1.0 - uv2_fract.x) * ((1.0 - uv2_fract.y) * hash1(uv2_floor) + uv2_fract.y * hash1(uv2_floor+vec2(0.0, 1.0))) + + uv2_fract.x * ((1.0 - uv2_fract.y) * hash1(uv2_floor+vec2(1.0, 0.0)) + uv2_fract.y * hash1(uv2_floor+vec2(1.0, 1.0)))); + m += c; + s *= 2.0; + c *= turbulence; + } + return f/m; +} + +float Sine_f(vec2 uv) { return sine(uv, 1, 1); } +void fragment() { + +float Material_f = Sine_f(UV); +COLOR = vec4(Material_f, Material_f, Material_f, 1.0); +} +" +_sections_unfolded = [ "Resource" ] + +[sub_resource type="ShaderMaterial" id=2] + +render_priority = 0 +shader = SubResource( 1 ) + +[node name="ProceduralMaterialEditor" type="MarginContainer" index="0"] + +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 +custom_constants/margin_left = 0 +script = ExtResource( 1 ) +_sections_unfolded = [ "custom_constants" ] + +[node name="GraphEdit" type="GraphEdit" parent="." index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_right = 1024.0 +margin_bottom = 600.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = true +focus_mode = 2 +mouse_filter = 0 +mouse_default_cursor_shape = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +right_disconnects = false +scroll_offset = Vector2( 0, 0 ) +snap_distance = 20 +use_snap = false +zoom = 1.0 +script = ExtResource( 2 ) +_sections_unfolded = [ "Mouse" ] + +[node name="Material" parent="GraphEdit" index="0" instance=ExtResource( 3 )] + +margin_left = 0.0 +margin_top = 0.0 +margin_right = 84.0 +margin_bottom = 43.0 +_sections_unfolded = [ "Anchor", "Margin", "Mouse", "slot" ] + +[node name="PopupMenu" type="PopupMenu" parent="GraphEdit" index="1"] + +visible = false +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 920.0 +margin_top = 548.0 +margin_right = 1024.0 +margin_bottom = 600.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 +popup_exclusive = false +items = [ "Material", null, 0, false, false, 0, 0, null, "", false, "Sine", null, 0, false, false, 1, 0, null, "", false, "Boolean", null, 0, false, false, 2, 0, null, "", false, "Bricks", null, 0, false, false, 3, 0, null, "", false, "IQ Noise", null, 0, false, false, 4, 0, null, "", false, "Perlin noise", null, 0, false, false, 5, 0, null, "", false, "Transform", null, 0, false, false, 6, 0, null, "", false ] +hide_on_state_item_selection = false +_sections_unfolded = [ "Rect" ] + +[node name="Preview" type="ColorRect" parent="." index="1"] + +material = SubResource( 2 ) +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 768.0 +margin_right = 1024.0 +margin_bottom = 256.0 +rect_min_size = Vector2( 256, 256 ) +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 2 +mouse_default_cursor_shape = 0 +size_flags_horizontal = 8 +size_flags_vertical = 0 +color = Color( 1, 1, 1, 1 ) +_sections_unfolded = [ "Material", "Mouse", "Rect" ] + +[connection signal="connection_request" from="GraphEdit" to="." method="_on_GraphEdit_connection_request"] + +[connection signal="popup_request" from="GraphEdit" to="." method="_on_GraphEdit_popup_request"] + +[connection signal="id_pressed" from="GraphEdit/PopupMenu" to="." method="_on_PopupMenu_id_pressed"] + + diff --git a/addons/procedural_material/shader_header.txt b/addons/procedural_material/shader_header.txt new file mode 100644 index 0000000..b22a0dc --- /dev/null +++ b/addons/procedural_material/shader_header.txt @@ -0,0 +1,93 @@ +shader_type canvas_item; + +float hash1(vec2 p) { + float q = dot(p,vec2(127.1,311.7)); + return fract(sin(q)*43758.5453); +} + +vec2 hash2(vec2 p) { + vec2 q = vec2( dot(p,vec2(127.1,311.7)), + dot(p,vec2(269.5,183.3)) ); + return fract(sin(q)*43758.5453); +} + +vec3 hash3(vec2 p) { + vec3 q = vec3( dot(p,vec2(127.1,311.7)), + dot(p,vec2(269.5,183.3)), + dot(p,vec2(419.2,371.9)) ); + return fract(sin(q)*43758.5453); +} + +float sine(vec2 uv, float count, float sharpness) { + return max(0.0, min(1.0, (0.5+sharpness*0.5*sin(count*3.1415928*2.0*uv.x)))); +} + +vec2 rotate(vec2 uv, float angle) { + vec2 rv; + rv.x = cos(angle)*uv.x + sin(angle)*uv.y; + rv.y = -sin(angle)*uv.x + cos(angle)*uv.y; + return rv; +} + +float 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 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 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 min(min(f1, f2), min(f3, f4)); +} + +float colored_bricks(vec2 uv, vec2 count, float offset) { + float x = floor(uv.x*count.x+offset*step(0.5, fract(uv.y*count.y*0.5))); + float y = floor(uv.y*count.y); + return fract(x/3.0+y/7.0); +} + +float iqnoise(vec2 uv, float s, float u, float v) { + uv *= s; + vec2 p = floor(uv); + vec2 f = fract(uv); + + float k = 1.0+63.0*pow(1.0-v,4.0); + + float va = 0.0; + float wt = 0.0; + for( int j=-2; j<=2; j++ ) + for( int i=-2; i<=2; i++ ) + { + vec2 g = vec2( float(i),float(j) ); + vec3 o = hash3( p + g )*vec3(u,u,1.0); + vec2 r = g - f + o.xy; + float d = dot(r,r); + float ww = pow( 1.0-smoothstep(0.0,1.414,sqrt(d)), k ); + va += o.z*ww; + wt += ww; + } + + return va/wt; +} + +float perlin(vec2 uv, int iterations, float turbulence) { + float f = 0.0; + float c = 1.0; + float s = 2.0; + float m = 0.0; + for(int i = 0; i < iterations; i++) { + vec2 uv2 = float(s) * uv; + vec2 uv2_floor = floor(uv2); + vec2 uv2_fract = fract(uv2); + f += c * ( (1.0 - uv2_fract.x) * ((1.0 - uv2_fract.y) * hash1(uv2_floor) + uv2_fract.y * hash1(uv2_floor+vec2(0.0, 1.0))) + + uv2_fract.x * ((1.0 - uv2_fract.y) * hash1(uv2_floor+vec2(1.0, 0.0)) + uv2_fract.y * hash1(uv2_floor+vec2(1.0, 1.0)))); + m += c; + s *= 2.0; + c *= turbulence; + } + return f/m; +} diff --git a/addons/procedural_material/sine.gd b/addons/procedural_material/sine.gd new file mode 100644 index 0000000..154b54a --- /dev/null +++ b/addons/procedural_material/sine.gd @@ -0,0 +1,24 @@ +tool +extends "res://addons/procedural_material/node_base.gd" + +var waves = 1.0 +var sharpness = 1.0 + +func _ready(): + set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) + +func get_shader_code(uv): + var rv = { defs="", code="", rgb=null, f=null } + if !generated: + rv.defs = "float "+name+"_f(vec2 uv) { return sine(uv, "+str(waves)+", "+str(sharpness)+"); }\n" + generated = true + rv.f = name+"_f("+uv+")" + return rv + +func _on_Count_text_changed(new_text): + waves = float(new_text) + get_parent().get_parent().generate_shader() + +func _on_Sharpness_text_changed(new_text): + sharpness = float(new_text) + get_parent().get_parent().generate_shader() diff --git a/addons/procedural_material/sine.tscn b/addons/procedural_material/sine.tscn new file mode 100644 index 0000000..471295b --- /dev/null +++ b/addons/procedural_material/sine.tscn @@ -0,0 +1,104 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/procedural_material/sine.gd" type="Script" id=1] + +[sub_resource type="Theme" id=1] + + +[node name="Sine" type="GraphNode" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 1.0 +margin_right = 133.0 +margin_bottom = 163.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 +theme = SubResource( 1 ) +title = "Sine" +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( 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( 1, 1, 1, 1 ) +slot/1/right_enabled = false +slot/1/right_type = 0 +slot/1/right_color = Color( 1, 1, 1, 1 ) +script = ExtResource( 1 ) +_sections_unfolded = [ "Theme" ] + +[node name="Count" type="LineEdit" 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 = 117.0 +margin_bottom = 48.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 = 1 +size_flags_vertical = 1 +text = "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 = [ "Caret", "Placeholder" ] + +[node name="Sharpness" type="LineEdit" parent="." index="1"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 16.0 +margin_top = 48.0 +margin_right = 117.0 +margin_bottom = 72.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 = 1 +size_flags_vertical = 1 +text = "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 = [ "Caret", "Placeholder" ] + +[connection signal="close_request" from="." to="." method="queue_free"] + +[connection signal="text_changed" from="Count" to="." method="_on_Count_text_changed"] + +[connection signal="text_changed" from="Sharpness" to="." method="_on_Sharpness_text_changed"] + + diff --git a/addons/procedural_material/transform.gd b/addons/procedural_material/transform.gd new file mode 100644 index 0000000..6b379a7 --- /dev/null +++ b/addons/procedural_material/transform.gd @@ -0,0 +1,25 @@ +tool +extends "res://addons/procedural_material/node_base.gd" + +var angle = 0.0 + +func _ready(): + set_slot(0, true, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) + +func get_shader_code(uv): + var rv = { defs="", code="", uv=null, rgb=null, f=null } + var src = get_source() + if src == null: + return rv + rv.uv = name+"_uv("+uv+")" + var src_code = src.get_shader_code(rv.uv) + if !generated: + rv.defs = src_code.defs+"vec2 "+name+"_uv(vec2 uv) { return rotate(uv, "+str(angle)+"); }\n" + generated = true + rv.f = src_code.f + rv.rgb = src_code.rgb + return rv + +func _on_Rotate_text_changed(new_text): + angle = float(new_text)*3.1415928/180.0 + get_parent().get_parent().generate_shader() diff --git a/addons/procedural_material/transform.tscn b/addons/procedural_material/transform.tscn new file mode 100644 index 0000000..4051a4d --- /dev/null +++ b/addons/procedural_material/transform.tscn @@ -0,0 +1,71 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/procedural_material/transform.gd" type="Script" id=1] + +[sub_resource type="Theme" id=1] + + +[node name="Transform" type="GraphNode" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 329.0 +margin_top = 117.0 +margin_right = 462.0 +margin_bottom = 279.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 +theme = SubResource( 1 ) +title = "Transform" +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( 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 ) +script = ExtResource( 1 ) +_sections_unfolded = [ "Theme" ] + +[node name="Rotate" type="LineEdit" 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 = 117.0 +margin_bottom = 48.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 = 1 +size_flags_vertical = 1 +text = "0" +focus_mode = 2 +context_menu_enabled = true +placeholder_alpha = 0.6 +caret_blink = false +caret_blink_speed = 0.65 +caret_position = 0 +_sections_unfolded = [ "Caret", "Placeholder" ] + +[connection signal="close_request" from="." to="." method="queue_free"] + +[connection signal="text_changed" from="Rotate" to="." method="_on_Rotate_text_changed"] + + diff --git a/default_env.tres b/default_env.tres new file mode 100644 index 0000000..98f26a7 --- /dev/null +++ b/default_env.tres @@ -0,0 +1,5 @@ +[gd_resource type="Environment" load_steps=2 format=2] +[sub_resource type="ProceduralSky" id=1] +[resource] +background_mode = 2 +background_sky = SubResource( 1 ) diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..a0b64ee Binary files /dev/null and b/icon.png differ diff --git a/icon.png.import b/icon.png.import new file mode 100644 index 0000000..0041ef8 --- /dev/null +++ b/icon.png.import @@ -0,0 +1,29 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" + +[deps] + +source_file="res://icon.png" +dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..9dcf3ce --- /dev/null +++ b/project.godot @@ -0,0 +1,22 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=3 + +[application] + +config/name="Procedural textures addon" +config/icon="res://icon.png" + +[editor_plugins] + +enabled=PoolStringArray( "procedural_material" ) + +[rendering] + +environment/default_environment="res://default_env.tres"