mirror of
https://github.com/Relintai/material-maker.git
synced 2024-12-23 21:16:54 +01:00
First version
Created base framework and created simple operators
This commit is contained in:
parent
ae2294bc9e
commit
6c615aeb02
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.import
|
21
addons/procedural_material/boolean.gd
Normal file
21
addons/procedural_material/boolean.gd
Normal file
@ -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
|
103
addons/procedural_material/boolean.tscn
Normal file
103
addons/procedural_material/boolean.tscn
Normal file
@ -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"]
|
||||
|
||||
|
23
addons/procedural_material/bricks.gd
Normal file
23
addons/procedural_material/bricks.gd
Normal file
@ -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" ]
|
290
addons/procedural_material/bricks.tscn
Normal file
290
addons/procedural_material/bricks.tscn
Normal file
@ -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"]
|
||||
|
||||
|
15
addons/procedural_material/graph_edit.gd
Normal file
15
addons/procedural_material/graph_edit.gd
Normal file
@ -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)
|
18
addons/procedural_material/iqnoise.gd
Normal file
18
addons/procedural_material/iqnoise.gd
Normal file
@ -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
|
198
addons/procedural_material/iqnoise.tscn
Normal file
198
addons/procedural_material/iqnoise.tscn
Normal file
@ -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"]
|
||||
|
||||
|
25
addons/procedural_material/material.gd
Normal file
25
addons/procedural_material/material.gd
Normal file
@ -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
|
62
addons/procedural_material/material.tscn
Normal file
62
addons/procedural_material/material.tscn
Normal file
@ -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
|
||||
|
||||
|
28
addons/procedural_material/node_base.gd
Normal file
28
addons/procedural_material/node_base.gd
Normal file
@ -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()
|
17
addons/procedural_material/perlin.gd
Normal file
17
addons/procedural_material/perlin.gd
Normal file
@ -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
|
152
addons/procedural_material/perlin.tscn
Normal file
152
addons/procedural_material/perlin.tscn
Normal file
@ -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"]
|
||||
|
||||
|
7
addons/procedural_material/plugin.cfg
Normal file
7
addons/procedural_material/plugin.cfg
Normal file
@ -0,0 +1,7 @@
|
||||
[plugin]
|
||||
|
||||
name="ProceduralMaterial"
|
||||
description="Procedural Material creation tool"
|
||||
author="RodZilla"
|
||||
version="0.1"
|
||||
script="plugin.gd"
|
20
addons/procedural_material/plugin.gd
Normal file
20
addons/procedural_material/plugin.gd
Normal file
@ -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
|
54
addons/procedural_material/pm_editor.gd
Normal file
54
addons/procedural_material/pm_editor.gd
Normal file
@ -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)
|
||||
|
213
addons/procedural_material/pm_editor.tscn
Normal file
213
addons/procedural_material/pm_editor.tscn
Normal file
@ -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"]
|
||||
|
||||
|
93
addons/procedural_material/shader_header.txt
Normal file
93
addons/procedural_material/shader_header.txt
Normal file
@ -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;
|
||||
}
|
24
addons/procedural_material/sine.gd
Normal file
24
addons/procedural_material/sine.gd
Normal file
@ -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()
|
104
addons/procedural_material/sine.tscn
Normal file
104
addons/procedural_material/sine.tscn
Normal file
@ -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"]
|
||||
|
||||
|
25
addons/procedural_material/transform.gd
Normal file
25
addons/procedural_material/transform.gd
Normal file
@ -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()
|
71
addons/procedural_material/transform.tscn
Normal file
71
addons/procedural_material/transform.tscn
Normal file
@ -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"]
|
||||
|
||||
|
5
default_env.tres
Normal file
5
default_env.tres
Normal file
@ -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 )
|
29
icon.png.import
Normal file
29
icon.png.import
Normal file
@ -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
|
22
project.godot
Normal file
22
project.godot
Normal file
@ -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"
|
Loading…
Reference in New Issue
Block a user