mirror of
https://github.com/Relintai/material-maker.git
synced 2024-11-13 06:27:18 +01:00
Added a generic node type
Updated all nodes so parameters are located in a "parameters" variable. Started writing a generic node model whose behavior is defined in a json file. Should be able to replace all generators so far. Wrote json files for bricks and noise nodes. Started preparing a custom node.
This commit is contained in:
parent
ab9ae4ce5d
commit
ee0bc96f30
@ -116,9 +116,15 @@ func create_nodes(data, position = null):
|
||||
if data == null:
|
||||
return
|
||||
if data.has("type"):
|
||||
var node_type = load("res://addons/material_maker/nodes/"+data.type+"/"+data.type+".tscn")
|
||||
if node_type != null:
|
||||
var node = node_type.instance()
|
||||
var node = null
|
||||
if File.new().file_exists("res://addons/material_maker/nodes/"+data.type+".json"):
|
||||
node = preload("res://addons/material_maker/nodes/node_generic.gd").new()
|
||||
node.model = data.type
|
||||
else:
|
||||
var node_type = load("res://addons/material_maker/nodes/"+data.type+"/"+data.type+".tscn")
|
||||
if node_type != null:
|
||||
node = node_type.instance()
|
||||
if node != null:
|
||||
if data.has("name") && !has_node(data.name):
|
||||
node.name = data.name
|
||||
else:
|
||||
|
@ -3,11 +3,10 @@
|
||||
[ext_resource path="res://addons/material_maker/graph_edit.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/material_maker/nodes/material/material.tscn" type="PackedScene" id=2]
|
||||
|
||||
|
||||
[sub_resource type="Theme" id=1]
|
||||
|
||||
|
||||
[node name="GraphEdit" type="GraphEdit"]
|
||||
[node name="GraphEdit" type="GraphEdit" index="0"]
|
||||
|
||||
self_modulate = Color( 1, 1, 1, 0 )
|
||||
anchor_left = 0.0
|
||||
@ -22,7 +21,7 @@ mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
right_disconnects = true
|
||||
scroll_offset = Vector2( -525, -250 )
|
||||
scroll_offset = Vector2( -458.75, -292.25 )
|
||||
snap_distance = 20
|
||||
use_snap = false
|
||||
zoom = 1.0
|
||||
@ -31,11 +30,12 @@ _sections_unfolded = [ "Material", "Mouse", "Visibility" ]
|
||||
|
||||
[node name="Material" parent="." index="0" instance=ExtResource( 2 )]
|
||||
|
||||
margin_left = 525.0
|
||||
margin_top = 250.0
|
||||
margin_right = 755.0
|
||||
margin_bottom = 470.0
|
||||
margin_left = 658.75
|
||||
margin_top = 292.25
|
||||
margin_right = 888.75
|
||||
margin_bottom = 512.25
|
||||
theme = SubResource( 1 )
|
||||
offset = Vector2( 200, 0 )
|
||||
_sections_unfolded = [ "Anchor", "Margin", "Mouse", "Theme", "slot", "slot/0", "slot/1", "slot/2", "slot/3", "slot/4", "slot/5" ]
|
||||
|
||||
[node name="Timer" type="Timer" parent="." index="1"]
|
||||
|
BIN
addons/material_maker/icons/edit.png
Normal file
BIN
addons/material_maker/icons/edit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 482 B |
@ -7,6 +7,7 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
@ -17,7 +18,29 @@
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="icons.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
id="defs2">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient836">
|
||||
<stop
|
||||
style="stop-color:#7c5000;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop832" />
|
||||
<stop
|
||||
style="stop-color:#ffcb68;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop834" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient836"
|
||||
id="linearGradient840"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="25.135416"
|
||||
y1="58.875"
|
||||
x2="25.135416"
|
||||
y2="48.291668" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -26,8 +49,8 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8"
|
||||
inkscape:cx="127.97633"
|
||||
inkscape:cy="1033.5955"
|
||||
inkscape:cx="161.54776"
|
||||
inkscape:cy="928.95264"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
@ -48,7 +71,7 @@
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
@ -117,5 +140,70 @@
|
||||
d="m 23.783078,44.110649 -4.508983,4.648736 -3.980261,-5.27284 a 12.770835,12.770835 0 0 0 -2.631282,1.045173 l 0.825522,6.441784 -6.571368,-0.17469 a 12.770835,12.770835 0 0 0 -0.7896172,2.557631 12.770835,12.770835 0 0 0 -0.027504,0.173796 l 5.5120272,3.347264 -4.1861363,4.972095 a 12.770835,12.770835 0 0 0 1.6563998,2.37002 l 5.9760855,-2.194035 1.267643,6.324612 a 12.770835,12.770835 0 0 0 2.907828,0.192046 l 1.997862,-6.001057 5.727797,2.948399 a 12.770835,12.770835 0 0 0 1.98019,-2.135962 l -3.455675,-5.317616 5.926699,-2.662342 a 12.770835,12.770835 0 0 0 -0.414249,-2.850168 l -6.383635,-0.620945 1.631047,-6.361785 a 12.770835,12.770835 0 0 0 -2.46039,-1.430116 z m -4.472442,8.529047 a 3.1927084,3.1927084 0 0 1 2.523332,3.744269 3.1927084,3.1927084 0 0 1 -3.744267,2.523336 3.1927084,3.1927084 0 0 1 -2.523335,-3.744269 3.1927084,3.1927084 0 0 1 3.74427,-2.523336 z"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.80446196;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke" />
|
||||
</g>
|
||||
<g
|
||||
id="g855"
|
||||
transform="matrix(0.48976049,-0.48711566,0.48711566,0.48976049,-26.645494,39.257287)"
|
||||
inkscape:export-filename="edit.png"
|
||||
inkscape:export-xdpi="14.942099"
|
||||
inkscape:export-ydpi="14.942099">
|
||||
<rect
|
||||
ry="0"
|
||||
y="48.291664"
|
||||
x="7.9375"
|
||||
height="10.583336"
|
||||
width="35.71875"
|
||||
id="rect830"
|
||||
style="opacity:1;fill:url(#linearGradient840);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path842"
|
||||
d="M 7.9374999,48.291667 -3.96875,53.583334 7.9374999,58.875001 Z"
|
||||
style="fill:#ffe0a7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:#242424;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.08819444px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M -9.9999999e-8,51.819444 -3.96875,53.583333 -9.9999999e-8,55.347222 Z"
|
||||
id="path844"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
ry="0"
|
||||
y="48.291664"
|
||||
x="38.364582"
|
||||
height="10.583333"
|
||||
width="2.6458333"
|
||||
id="rect846"
|
||||
style="opacity:1;fill:#adadad;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ff66bc;fill-opacity:1;stroke:none;stroke-width:1.11803377;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
id="rect848"
|
||||
width="6.6145821"
|
||||
height="10.583336"
|
||||
x="39.6875"
|
||||
y="48.291664"
|
||||
ry="2.8421709e-014" />
|
||||
</g>
|
||||
<g
|
||||
id="g879"
|
||||
inkscape:export-filename="save.png"
|
||||
inkscape:export-xdpi="14"
|
||||
inkscape:export-ydpi="14">
|
||||
<path
|
||||
id="rect859"
|
||||
transform="scale(0.26458333)"
|
||||
d="M 130 152.51953 L 130 262.51953 L 240 262.51953 L 240 163.23047 L 229.28906 152.51953 L 130 152.51953 z "
|
||||
style="opacity:1;fill:#14008d;fill-opacity:1;stroke:none;stroke-width:3.77952766;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke" />
|
||||
<path
|
||||
id="rect861"
|
||||
transform="scale(0.26458333)"
|
||||
d="M 155 152.51953 L 155 192.51953 L 215 192.51953 L 215 152.51953 L 155 152.51953 z M 195 162.51953 L 205 162.51953 L 205 182.51953 L 195 182.51953 L 195 162.51953 z "
|
||||
style="opacity:1;fill:#afafaf;fill-opacity:1;stroke:none;stroke-width:4.04048538;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke" />
|
||||
<rect
|
||||
ry="2.6458347"
|
||||
y="53.583332"
|
||||
x="37.041668"
|
||||
height="14.552081"
|
||||
width="23.812498"
|
||||
id="rect874"
|
||||
style="opacity:1;fill:#afafaf;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 10 KiB |
BIN
addons/material_maker/icons/save.png
Normal file
BIN
addons/material_maker/icons/save.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 375 B |
@ -241,7 +241,6 @@ size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
size_flags_stretch_ratio = 3.0
|
||||
script = ExtResource( 4 )
|
||||
_sections_unfolded = [ "custom_styles" ]
|
||||
|
||||
[node name="Tabs" type="Tabs" parent="VBoxContainer/HBoxContainer/Projects" index="1"]
|
||||
|
||||
|
@ -18,6 +18,7 @@ class OutPort:
|
||||
var generated = false
|
||||
var generated_variants = []
|
||||
|
||||
var parameters = {}
|
||||
var property_widgets = []
|
||||
|
||||
const Types = preload("res://addons/material_maker/types/types.gd")
|
||||
@ -31,25 +32,25 @@ func initialize_properties(object_list):
|
||||
if o == null:
|
||||
print("error in node "+name)
|
||||
elif o is LineEdit:
|
||||
set(o.name, float(o.text))
|
||||
parameters[o.name] = float(o.text)
|
||||
o.connect("text_changed", self, "_on_text_changed", [ o.name ])
|
||||
elif o is SpinBox:
|
||||
set(o.name, o.value)
|
||||
parameters[o.name] = o.value
|
||||
o.connect("value_changed", self, "_on_value_changed", [ o.name ])
|
||||
elif o is HSlider:
|
||||
set(o.name, o.value)
|
||||
parameters[o.name] = o.value
|
||||
o.connect("value_changed", self, "_on_value_changed", [ o.name ])
|
||||
elif o is OptionButton:
|
||||
set(o.name, o.selected)
|
||||
parameters[o.name] = o.selected
|
||||
o.connect("item_selected", self, "_on_value_changed", [ o.name ])
|
||||
elif o is CheckBox:
|
||||
set(o.name, o.pressed)
|
||||
parameters[o.name] = o.pressed
|
||||
o.connect("toggled", self, "_on_value_changed", [ o.name ])
|
||||
elif o is ColorPickerButton:
|
||||
set(o.name, o.color)
|
||||
parameters[o.name] = o.color
|
||||
o.connect("color_changed", self, "_on_color_changed", [ o.name ])
|
||||
elif o is Control and o.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
|
||||
set(o.name, o.value)
|
||||
parameters[o.name] = o.value
|
||||
o.connect("updated", self, "_on_gradient_changed", [ o.name ])
|
||||
else:
|
||||
print("unsupported widget "+str(o))
|
||||
@ -59,40 +60,41 @@ func get_seed():
|
||||
|
||||
func update_property_widgets():
|
||||
for o in property_widgets:
|
||||
if o is LineEdit:
|
||||
o.text = str(get(o.name))
|
||||
elif o is SpinBox:
|
||||
o.value = get(o.name)
|
||||
elif o is HSlider:
|
||||
o.value = get(o.name)
|
||||
elif o is OptionButton:
|
||||
o.selected = get(o.name)
|
||||
elif o is CheckBox:
|
||||
o.pressed = get(o.name)
|
||||
elif o is ColorPickerButton:
|
||||
o.color = get(o.name)
|
||||
elif o is Control and o.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
|
||||
o.value = get(o.name)
|
||||
else:
|
||||
print("Failed to update "+o.name)
|
||||
if parameters.has(o.name) and parameters[o.name] != null:
|
||||
if o is LineEdit:
|
||||
o.text = str(parameters[o.name])
|
||||
elif o is SpinBox:
|
||||
o.value = parameters[o.name]
|
||||
elif o is HSlider:
|
||||
o.value = parameters[o.name]
|
||||
elif o is OptionButton:
|
||||
o.selected = parameters[o.name]
|
||||
elif o is CheckBox:
|
||||
o.pressed = parameters[o.name]
|
||||
elif o is ColorPickerButton:
|
||||
o.color = parameters[o.name]
|
||||
elif o is Control and o.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
|
||||
o.value = parameters[o.name]
|
||||
else:
|
||||
print("Failed to update "+o.name)
|
||||
|
||||
func update_shaders():
|
||||
get_parent().send_changed_signal()
|
||||
|
||||
func _on_text_changed(new_text, variable):
|
||||
set(variable, float(new_text))
|
||||
parameters[variable] = float(new_text)
|
||||
update_shaders()
|
||||
|
||||
func _on_value_changed(new_value, variable):
|
||||
set(variable, new_value)
|
||||
parameters[variable] = new_value
|
||||
update_shaders()
|
||||
|
||||
func _on_color_changed(new_color, variable):
|
||||
set(variable, new_color)
|
||||
parameters[variable] = new_color
|
||||
update_shaders()
|
||||
|
||||
func _on_gradient_changed(new_gradient, variable):
|
||||
set(variable, new_gradient)
|
||||
parameters[variable] = new_gradient
|
||||
update_shaders()
|
||||
|
||||
func get_source(index = 0):
|
||||
@ -187,8 +189,8 @@ func serialize():
|
||||
type = type.left(type.find_last("."))
|
||||
var data = { name=name, type=type, node_position={x=offset.x, y=offset.y} }
|
||||
for w in property_widgets:
|
||||
var v = w.name
|
||||
data[v] = Types.serialize_value(get(v)) # serialize_element(get(v))
|
||||
var variable = w.name
|
||||
data[variable] = Types.serialize_value(parameters[variable]) # serialize_element(get(v))
|
||||
return data
|
||||
|
||||
func deserialize(data):
|
||||
@ -198,7 +200,7 @@ func deserialize(data):
|
||||
var variable = w.name
|
||||
if data.has(variable):
|
||||
var value = Types.deserialize_value(data[variable]) #deserialize_element(data[variable])
|
||||
set(variable, value)
|
||||
parameters[variable] = value
|
||||
update_property_widgets()
|
||||
|
||||
# Render targets again for multipass filters
|
||||
|
@ -1,10 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var hue
|
||||
var saturation
|
||||
var value
|
||||
|
||||
func _ready():
|
||||
initialize_properties([ $HBoxContainer1/hue, $HBoxContainer2/saturation, $HBoxContainer3/value ])
|
||||
|
||||
@ -17,7 +13,7 @@ func _get_shader_code(uv, output = 0):
|
||||
src_code = src.get_shader_code(uv)
|
||||
if generated_variants.empty():
|
||||
rv.defs = src_code.defs;
|
||||
rv.defs += "vec3 %s_rgb(vec3 c) { vec3 hsv = rgb2hsv(c); return hsv2rgb(vec3(fract(hsv.x+%.9f), clamp(hsv.y*%.9f, 0.0, 1.0), clamp(hsv.z*%.9f, 0.0, 1.0))); }\n" % [ name, hue, saturation, value ]
|
||||
rv.defs += "vec3 %s_rgb(vec3 c) { vec3 hsv = rgb2hsv(c); return hsv2rgb(vec3(fract(hsv.x+%.9f), clamp(hsv.y*%.9f, 0.0, 1.0), clamp(hsv.z*%.9f, 0.0, 1.0))); }\n" % [ name, parameters.hue, parameters.saturation, parameters.value ]
|
||||
var variant_index = generated_variants.find(uv)
|
||||
if variant_index == -1:
|
||||
variant_index = generated_variants.size()
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
[ext_resource path="res://addons/material_maker/nodes/adjust_hsv/adjust_hsv.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[sub_resource type="Theme" id=1]
|
||||
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var blend_type = 0
|
||||
var amount = 0.0
|
||||
|
||||
const BLEND_TYPES = [
|
||||
{ name="Normal", shortname="normal" },
|
||||
{ name="Dissolve", shortname="dissolve" },
|
||||
@ -35,7 +32,7 @@ func _get_shader_code(uv):
|
||||
var src0_code = src0.get_shader_code(uv)
|
||||
var src1_code = src1.get_shader_code(uv)
|
||||
var src2_code = { defs="", code="" }
|
||||
var amount_str = "%.9f" % amount
|
||||
var amount_str = "%.9f" % parameters.amount
|
||||
if src2 != null:
|
||||
src2_code = src2.get_shader_code(uv)
|
||||
amount_str = src2_code.f
|
||||
@ -46,7 +43,7 @@ func _get_shader_code(uv):
|
||||
variant_index = generated_variants.size()
|
||||
generated_variants.append(uv)
|
||||
rv.code = src0_code.code+src1_code.code+src2_code.code
|
||||
rv.code += "vec3 %s_%d_rgb = blend_%s(%s, %s, %s, %s);\n" % [ name, variant_index, BLEND_TYPES[blend_type].shortname, uv, src0_code.rgb, src1_code.rgb, amount_str ]
|
||||
rv.code += "vec3 %s_%d_rgb = blend_%s(%s, %s, %s, %s);\n" % [ name, variant_index, BLEND_TYPES[parameters.blend_type].shortname, uv, src0_code.rgb, src1_code.rgb, amount_str ]
|
||||
rv.rgb = "%s_%d_rgb" % [ name, variant_index ]
|
||||
return rv
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var size = 5
|
||||
var direction = 0
|
||||
var sigma = 1.0
|
||||
|
||||
var input_shader = ""
|
||||
var saved_texture
|
||||
|
||||
@ -21,17 +17,17 @@ func _ready():
|
||||
$HBoxContainer1/size.clear()
|
||||
for i in range(7):
|
||||
$HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i)
|
||||
$HBoxContainer1/size.selected = size
|
||||
$HBoxContainer1/size.selected = 5
|
||||
# init direction widget
|
||||
$HBoxContainer2/direction.clear()
|
||||
for d in DIRECTIONS:
|
||||
$HBoxContainer2/direction.add_item(d.name)
|
||||
$HBoxContainer2/direction.selected = direction
|
||||
$HBoxContainer2/direction.selected = 0
|
||||
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/direction, $HBoxContainer3/sigma ])
|
||||
saved_texture = ImageTexture.new()
|
||||
|
||||
func get_gaussian_blur_shader(horizontal):
|
||||
var convolution = { x=0, y=0, kernel=[], epsilon=1.0/pow(2, 5+size) }
|
||||
var convolution = { x=0, y=0, kernel=[], epsilon=1.0/pow(2, 5+parameters.size) }
|
||||
var kernel_size = 50
|
||||
if horizontal:
|
||||
convolution.x = kernel_size
|
||||
@ -40,7 +36,7 @@ func get_gaussian_blur_shader(horizontal):
|
||||
convolution.kernel.resize(2*kernel_size+1)
|
||||
var sum = 0
|
||||
for x in range(-kernel_size, kernel_size+1):
|
||||
var coef = exp(-0.5*(pow((x)/sigma, 2.0))) / (2.0*PI*sigma*sigma)
|
||||
var coef = exp(-0.5*(pow((x)/parameters.sigma, 2.0))) / (2.0*PI*parameters.sigma*parameters.sigma)
|
||||
convolution.kernel[x+kernel_size] = coef
|
||||
sum += coef
|
||||
for x in range(-kernel_size, kernel_size+1):
|
||||
@ -48,20 +44,19 @@ func get_gaussian_blur_shader(horizontal):
|
||||
return get_convolution_shader(convolution)
|
||||
|
||||
func _rerender():
|
||||
if DIRECTIONS[direction].mask & DIRECTION_H != 0:
|
||||
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+size)), saved_texture, self, "pass_1", [])
|
||||
if DIRECTIONS[parameters.direction].mask & DIRECTION_H != 0:
|
||||
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), saved_texture, self, "pass_1", [])
|
||||
else:
|
||||
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+size)), saved_texture, self, "pass_2", [])
|
||||
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), saved_texture, self, "pass_2", [])
|
||||
|
||||
func pass_1():
|
||||
if DIRECTIONS[direction].mask & DIRECTION_V != 0:
|
||||
get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+size)), saved_texture, self, "pass_2", [])
|
||||
if DIRECTIONS[parameters.direction].mask & DIRECTION_V != 0:
|
||||
get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "pass_2", [])
|
||||
else:
|
||||
get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+size)), saved_texture, self, "rerender_targets", [])
|
||||
|
||||
get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "rerender_targets", [])
|
||||
|
||||
func pass_2():
|
||||
get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(false), { input=saved_texture }, int(pow(2, 5+size)), saved_texture, self, "rerender_targets", [])
|
||||
get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(false), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "rerender_targets", [])
|
||||
|
||||
func get_textures():
|
||||
var list = {}
|
||||
|
122
addons/material_maker/nodes/bricks.json
Normal file
122
addons/material_maker/nodes/bricks.json
Normal file
@ -0,0 +1,122 @@
|
||||
{
|
||||
"name":"Bricks",
|
||||
"parameters":[
|
||||
{ "name":"pattern", "label":"", "type":"enum", "values":[
|
||||
{ "name":"Running bond", "value":"rb" },
|
||||
{ "name":"Running bond (2)", "value":"rb2" },
|
||||
{ "name":"HerringBone", "value":"hb" },
|
||||
{ "name":"Basket weave", "value":"bw" },
|
||||
{ "name":"Spanish bond", "value":"sb" }
|
||||
] },
|
||||
{ "name":"repeat", "label":"Repeat:", "type":"float", "min":1, "max":8, "step":1, "default":1, "widget":"spinbox" },
|
||||
{ "name":"rows", "label":"Rows:", "type":"float", "min":1, "max":64, "step":1, "default":6, "widget":"spinbox" },
|
||||
{ "name":"columns", "label":"Columns:", "type":"float", "min":1, "max":64, "step":1, "default":3, "widget":"spinbox" },
|
||||
{ "name":"row_offset", "label":"Offset:", "type":"float", "min":0, "max":1, "default":0.5 },
|
||||
{ "name":"mortar", "label":"Mortar:", "type":"float", "min":0, "max":0.5, "default":0.1 },
|
||||
{ "name":"bevel", "label":"Bevel:", "type":"float", "min":0, "max":0.5, "default":0.1 }
|
||||
],
|
||||
"include":[ "noise" ],
|
||||
"global":"
|
||||
vec3 brick(vec2 uv, vec2 bmin, vec2 bmax, float mortar, float bevel) {
|
||||
float color = 0.5;
|
||||
vec2 c1 = (uv-bmin-vec2(mortar))/bevel;
|
||||
vec2 c2 = (bmax-uv-vec2(mortar))/bevel;
|
||||
vec2 c = min(c1, c2);
|
||||
color = clamp(min(c.x, c.y), 0.0, 1.0);
|
||||
return vec3(color, mod(bmin, vec2(1.0, 1.0)));
|
||||
}
|
||||
|
||||
vec3 bricks_rb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
count *= repeat;
|
||||
mortar /= max(count.x, count.y);
|
||||
bevel /= max(count.x, count.y);
|
||||
float x_offset = offset*step(0.5, fract(uv.y*count.y*0.5));
|
||||
vec2 bmin = floor(vec2(uv.x*count.x-x_offset, uv.y*count.y));
|
||||
bmin.x += x_offset;
|
||||
bmin /= count;
|
||||
return brick(uv, bmin, bmin+vec2(1.0)/count, mortar, bevel);
|
||||
}
|
||||
|
||||
vec3 bricks_rb2(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
count *= repeat;
|
||||
mortar /= max(2.0*count.x, count.y);
|
||||
bevel /= max(2.0*count.x, count.y);
|
||||
float x_offset = offset*step(0.5, fract(uv.y*count.y*0.5));
|
||||
count.x = count.x*(1.0+step(0.5, fract(uv.y*count.y*0.5)));
|
||||
vec2 bmin = floor(vec2(uv.x*count.x-x_offset, uv.y*count.y));
|
||||
bmin.x += x_offset;
|
||||
bmin /= count;
|
||||
return brick(uv, bmin, bmin+vec2(1.0)/count, mortar, bevel);
|
||||
}
|
||||
|
||||
vec3 bricks_hb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
float pc = count.x+count.y;
|
||||
float c = pc*repeat;
|
||||
mortar /= c;
|
||||
bevel /= c;
|
||||
vec2 corner = floor(uv*c);
|
||||
float cdiff = mod(corner.x-corner.y, pc);
|
||||
if (cdiff < count.x) {
|
||||
return brick(uv, (corner-vec2(cdiff, 0.0))/c, (corner-vec2(cdiff, 0.0)+vec2(count.x, 1.0))/c, mortar, bevel);
|
||||
} else {
|
||||
return brick(uv, (corner-vec2(0.0, pc-cdiff-1.0))/c, (corner-vec2(0.0, pc-cdiff-1.0)+vec2(1.0, count.y))/c, mortar, bevel);
|
||||
}
|
||||
}
|
||||
|
||||
vec3 bricks_bw(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
vec2 c = 2.0*count*repeat;
|
||||
float mc = max(c.x, c.y);
|
||||
mortar /= mc;
|
||||
bevel /= mc;
|
||||
vec2 corner1 = floor(uv*c);
|
||||
vec2 corner2 = count*floor(repeat*2.0*uv);
|
||||
float cdiff = mod(dot(floor(repeat*2.0*uv), vec2(1.0)), 2.0);
|
||||
vec2 corner;
|
||||
vec2 size;
|
||||
if (cdiff == 0.0) {
|
||||
corner = vec2(corner1.x, corner2.y);
|
||||
size = vec2(1.0, count.y);
|
||||
} else {
|
||||
corner = vec2(corner2.x, corner1.y);
|
||||
size = vec2(count.x, 1.0);
|
||||
}
|
||||
return brick(uv, corner/c, (corner+size)/c, mortar, bevel);
|
||||
}
|
||||
|
||||
vec3 bricks_sb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
vec2 c = (count+vec2(1.0))*repeat;
|
||||
float mc = max(c.x, c.y);
|
||||
mortar /= mc;
|
||||
bevel /= mc;
|
||||
vec2 corner1 = floor(uv*c);
|
||||
vec2 corner2 = (count+vec2(1.0))*floor(repeat*uv);
|
||||
vec2 rcorner = corner1 - corner2;
|
||||
vec2 corner;
|
||||
vec2 size;
|
||||
if (rcorner.x == 0.0 && rcorner.y < count.y) {
|
||||
corner = corner2;
|
||||
size = vec2(1.0, count.y);
|
||||
} else if (rcorner.y == 0.0) {
|
||||
corner = corner2+vec2(1.0, 0.0);
|
||||
size = vec2(count.x, 1.0);
|
||||
} else if (rcorner.x == count.x) {
|
||||
corner = corner2+vec2(count.x, 1.0);
|
||||
size = vec2(1.0, count.y);
|
||||
} else if (rcorner.y == count.y) {
|
||||
corner = corner2+vec2(0.0, count.y);
|
||||
size = vec2(count.x, 1.0);
|
||||
} else {
|
||||
corner = corner2+vec2(1.0);
|
||||
size = vec2(count.x-1.0, count.y-1.0);
|
||||
}
|
||||
return brick(uv, corner/c, (corner+size)/c, mortar, bevel);
|
||||
}",
|
||||
"instance":"
|
||||
vec3 $(name)_xyz(vec2 uv) {
|
||||
return bricks_$(pattern)(uv, vec2($(columns), $(rows)), $(repeat), $(row_offset), $(mortar), max(0.001, $(bevel)));
|
||||
}",
|
||||
"outputs":[
|
||||
{ "f":"$(name)_xyz($(uv)).x" },
|
||||
{ "rgb":"rand3($(name)_xyz($(uv)).yz+vec2($(seed)))" }
|
||||
]
|
||||
}
|
@ -1,14 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var pattern = 0
|
||||
var repeat
|
||||
var rows
|
||||
var columns
|
||||
var row_offset
|
||||
var mortar
|
||||
var bevel
|
||||
|
||||
const BRICK_PATTERNS = [
|
||||
{ name="Running bond", suffix="rb", has_offset=true, has_repeat=false },
|
||||
{ name="Running bond (2)", suffix="rb2", has_offset=true, has_repeat=false },
|
||||
@ -26,7 +18,7 @@ func _ready():
|
||||
func _get_shader_code(uv, slot = 0):
|
||||
var rv = { defs="", code="" }
|
||||
if generated_variants.empty():
|
||||
rv.defs = "vec3 %s_xyz(vec2 uv) { return bricks_%s(uv, vec2(%d, %d), %.9f, %.9f, %.9f, %.9f); }\n" % [ name, BRICK_PATTERNS[pattern].suffix, columns, rows, repeat, row_offset, mortar, max(0.001, bevel) ]
|
||||
rv.defs = "vec3 %s_xyz(vec2 uv) { return bricks_%s(uv, vec2(%d, %d), %.9f, %.9f, %.9f, %.9f); }\n" % [ name, BRICK_PATTERNS[parameters.pattern].suffix, parameters.columns, parameters.rows, parameters.repeat, parameters.row_offset, parameters.mortar, max(0.001, parameters.bevel) ]
|
||||
var variant_index = generated_variants.find(uv)
|
||||
if variant_index == -1:
|
||||
variant_index = generated_variants.size()
|
||||
|
@ -1,8 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var gradient
|
||||
|
||||
func _ready():
|
||||
initialize_properties([ $gradient ])
|
||||
|
||||
@ -13,7 +11,7 @@ func _get_shader_code(uv):
|
||||
return rv
|
||||
var src_code = src.get_shader_code(uv)
|
||||
if generated_variants.empty():
|
||||
rv.defs = src_code.defs+gradient.get_shader("%s_gradient" % name);
|
||||
rv.defs = src_code.defs+parameters.gradient.get_shader("%s_gradient" % name);
|
||||
var variant_index = generated_variants.find(uv)
|
||||
if variant_index == -1:
|
||||
variant_index = generated_variants.size()
|
||||
@ -23,5 +21,5 @@ func _get_shader_code(uv):
|
||||
return rv
|
||||
|
||||
func _on_Control_updated(v):
|
||||
gradient = v
|
||||
parameters.gradient = v
|
||||
update_shaders()
|
||||
|
8
addons/material_maker/nodes/custom/custom.gd
Normal file
8
addons/material_maker/nodes/custom/custom.gd
Normal file
@ -0,0 +1,8 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/nodes/node_generic.gd"
|
||||
|
||||
func _on_Edit_pressed():
|
||||
pass # replace with function body
|
||||
|
||||
func _on_Save_pressed():
|
||||
pass # replace with function body
|
107
addons/material_maker/nodes/custom/custom.tscn
Normal file
107
addons/material_maker/nodes/custom/custom.tscn
Normal file
@ -0,0 +1,107 @@
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://addons/material_maker/nodes/custom/custom.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/material_maker/icons/edit.png" type="Texture" id=2]
|
||||
[ext_resource path="res://addons/material_maker/icons/save.png" type="Texture" id=3]
|
||||
|
||||
[node name="Custom" type="GraphNode" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 385.0
|
||||
margin_top = 287.0
|
||||
margin_right = 479.0
|
||||
margin_bottom = 338.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
title = "Custom"
|
||||
offset = Vector2( 0, 0 )
|
||||
show_close = true
|
||||
resizable = false
|
||||
selected = false
|
||||
comment = false
|
||||
overlay = 0
|
||||
slot/0/left_enabled = false
|
||||
slot/0/left_type = 0
|
||||
slot/0/left_color = Color( 1, 1, 1, 1 )
|
||||
slot/0/right_enabled = false
|
||||
slot/0/right_type = 0
|
||||
slot/0/right_color = Color( 1, 1, 1, 1 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="CustomNodeButtons" type="HBoxContainer" parent="." index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 16.0
|
||||
margin_top = 24.0
|
||||
margin_right = 78.0
|
||||
margin_bottom = 46.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
alignment = 0
|
||||
|
||||
[node name="Edit" type="Button" parent="CustomNodeButtons" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_right = 27.0
|
||||
margin_bottom = 22.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
toggle_mode = false
|
||||
enabled_focus_mode = 2
|
||||
shortcut = null
|
||||
group = null
|
||||
icon = ExtResource( 2 )
|
||||
flat = true
|
||||
align = 1
|
||||
|
||||
[node name="Save" type="Button" parent="CustomNodeButtons" index="1"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 31.0
|
||||
margin_right = 59.0
|
||||
margin_bottom = 22.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
toggle_mode = false
|
||||
enabled_focus_mode = 2
|
||||
shortcut = null
|
||||
group = null
|
||||
icon = ExtResource( 3 )
|
||||
flat = true
|
||||
align = 1
|
||||
|
||||
[connection signal="pressed" from="CustomNodeButtons/Edit" to="." method="_on_Edit_pressed"]
|
||||
|
||||
[connection signal="pressed" from="CustomNodeButtons/Save" to="." method="_on_Save_pressed"]
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var size = 5
|
||||
var direction = 0
|
||||
|
||||
var input_shader = ""
|
||||
var input_texture
|
||||
var final_texture
|
||||
@ -28,20 +25,20 @@ func _ready():
|
||||
$HBoxContainer1/size.clear()
|
||||
for i in range(7):
|
||||
$HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i)
|
||||
$HBoxContainer1/size.selected = size
|
||||
$HBoxContainer1/size.selected = 5
|
||||
input_texture = ImageTexture.new()
|
||||
final_texture = ImageTexture.new()
|
||||
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/direction ])
|
||||
|
||||
func _rerender():
|
||||
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+size)), input_texture, self, "pass_1", [])
|
||||
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), input_texture, self, "pass_1", [])
|
||||
|
||||
func pass_1():
|
||||
var convolution = CONVOLUTION
|
||||
convolution.epsilon=1.0/pow(2, 5+size)
|
||||
convolution.epsilon=1.0/pow(2, 5+parameters.size)
|
||||
for i in range(8):
|
||||
convolution.kernel[INDICES[i]] = COEFS[(i+8-int(direction))%8]
|
||||
get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), {input=input_texture}, int(pow(2, 5+size)), final_texture, self, "rerender_targets", [])
|
||||
convolution.kernel[INDICES[i]] = COEFS[(i+8-int(parameters.direction))%8]
|
||||
get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), {input=input_texture}, int(pow(2, 5+parameters.size)), final_texture, self, "rerender_targets", [])
|
||||
|
||||
func get_textures():
|
||||
var list = {}
|
||||
|
@ -1,7 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var resolution = 1
|
||||
var suffix = "suffix"
|
||||
|
||||
func _ready():
|
||||
@ -18,7 +17,7 @@ func export_textures(prefix, size = null):
|
||||
var suffix = $Suffix.text
|
||||
if suffix != "":
|
||||
if size == null:
|
||||
size = int(pow(2, 8+resolution))
|
||||
size = int(pow(2, 8+parameters.resolution))
|
||||
get_parent().renderer.export_texture(get_source(), "%s_%s.png" % [ prefix, suffix ], size)
|
||||
|
||||
func serialize():
|
||||
|
@ -1,15 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var resolution = 1
|
||||
var albedo_color
|
||||
var metallic
|
||||
var roughness
|
||||
var emission_energy
|
||||
var normal_scale
|
||||
var ao_light_affect
|
||||
var depth_scale
|
||||
|
||||
var texture_list
|
||||
|
||||
var current_material_list = []
|
||||
@ -42,7 +33,7 @@ func _ready():
|
||||
initialize_properties([ $resolution, $Albedo/albedo_color, $Metallic/metallic, $Roughness/roughness, $Emission/emission_energy, $NormalMap/normal_scale, $AmbientOcclusion/ao_light_affect, $DepthMap/depth_scale ])
|
||||
|
||||
func _rerender():
|
||||
var size = int(pow(2, 8+resolution))
|
||||
var size = int(pow(2, 8+parameters.resolution))
|
||||
var has_textures = false
|
||||
for t in texture_list:
|
||||
var shader = generated_textures[t.texture].shader
|
||||
@ -116,10 +107,10 @@ func get_generated_texture(slot, file_prefix = null):
|
||||
|
||||
func update_spatial_material(m, file_prefix = null):
|
||||
var texture
|
||||
m.albedo_color = albedo_color
|
||||
m.albedo_color = parameters.albedo_color
|
||||
m.albedo_texture = get_generated_texture("albedo", file_prefix)
|
||||
m.metallic = metallic
|
||||
m.roughness = roughness
|
||||
m.metallic = parameters.metallic
|
||||
m.roughness = parameters.roughness
|
||||
if Engine.editor_hint:
|
||||
texture = get_generated_texture("mrao", file_prefix)
|
||||
m.metallic_texture = texture
|
||||
@ -132,7 +123,7 @@ func update_spatial_material(m, file_prefix = null):
|
||||
texture = get_generated_texture("emission", file_prefix)
|
||||
if texture != null:
|
||||
m.emission_enabled = true
|
||||
m.emission_energy = emission_energy
|
||||
m.emission_energy = parameters.emission_energy
|
||||
m.emission_texture = texture
|
||||
else:
|
||||
m.emission_enabled = false
|
||||
@ -145,7 +136,7 @@ func update_spatial_material(m, file_prefix = null):
|
||||
if Engine.editor_hint:
|
||||
if (generated_textures.mrao.mask & (1 << 2)) != 0:
|
||||
m.ao_enabled = true
|
||||
m.ao_light_affect = ao_light_affect
|
||||
m.ao_light_affect = parameters.ao_light_affect
|
||||
m.ao_texture = m.metallic_texture
|
||||
m.ao_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_BLUE
|
||||
else:
|
||||
@ -154,14 +145,14 @@ func update_spatial_material(m, file_prefix = null):
|
||||
texture = get_generated_texture("ambient_occlusion", file_prefix)
|
||||
if texture != null:
|
||||
m.ao_enabled = true
|
||||
m.ao_light_affect = ao_light_affect
|
||||
m.ao_light_affect = parameters.ao_light_affect
|
||||
m.ao_texture = texture
|
||||
else:
|
||||
m.ao_enabled = false
|
||||
texture = get_generated_texture("depth_map", file_prefix)
|
||||
if texture != null:
|
||||
m.depth_enabled = true
|
||||
m.depth_scale = depth_scale
|
||||
m.depth_scale = parameters.depth_scale
|
||||
m.depth_texture = texture
|
||||
else:
|
||||
m.depth_enabled = false
|
||||
@ -173,7 +164,7 @@ func do_update_materials(material_list):
|
||||
|
||||
func export_textures(prefix, size = null):
|
||||
if size == null:
|
||||
size = int(pow(2, 8+resolution))
|
||||
size = int(pow(2, 8+parameters.resolution))
|
||||
for t in texture_list:
|
||||
var texture = generated_textures[t.texture].texture
|
||||
if texture != null:
|
||||
|
149
addons/material_maker/nodes/node_generic.gd
Normal file
149
addons/material_maker/nodes/node_generic.gd
Normal file
@ -0,0 +1,149 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
export(String) var model = null setget set_model
|
||||
var model_data = null
|
||||
var uses_seed = false
|
||||
|
||||
func _ready():
|
||||
show_close = true
|
||||
connect("offset_changed", self, "_on_offset_changed")
|
||||
|
||||
func set_model(m):
|
||||
if m != null and typeof(m) == TYPE_STRING:
|
||||
var file = File.new()
|
||||
var file_name = m
|
||||
if !file.file_exists(file_name):
|
||||
file_name = "res://addons/material_maker/nodes/%s.json" % [ m ]
|
||||
if file.file_exists(file_name):
|
||||
if file.open(file_name, File.READ) != OK:
|
||||
return
|
||||
var data = file.get_as_text()
|
||||
var status = validate_json(data)
|
||||
file.close()
|
||||
if status != "":
|
||||
print("Incorrect node description (%s)" % status)
|
||||
return
|
||||
data = parse_json(data)
|
||||
model = m
|
||||
update_node(data)
|
||||
|
||||
func update_node(data):
|
||||
if typeof(data) != TYPE_DICTIONARY:
|
||||
return
|
||||
if !data.has("name"):
|
||||
return
|
||||
title = data.name
|
||||
model_data = data
|
||||
uses_seed = false
|
||||
if model_data.has("instance") and model_data.instance.find("$(seed)"):
|
||||
uses_seed = true
|
||||
if model_data.has("parameters") and typeof(model_data.parameters) == TYPE_ARRAY:
|
||||
var control_list = []
|
||||
for p in model_data.parameters:
|
||||
if !p.has("name") or !p.has("type"):
|
||||
continue
|
||||
var control = null
|
||||
if p.type == "float":
|
||||
if p.has("widget") and p.widget == "spinbox":
|
||||
control = SpinBox.new()
|
||||
else:
|
||||
control = HSlider.new()
|
||||
control.min_value = p.min
|
||||
control.max_value = p.max
|
||||
control.step = 0 if !p.has("step") else p.step
|
||||
control.rect_min_size.x = 80
|
||||
parameters[p.name] = 0.5*(p.min+p.max)
|
||||
elif p.type == "size":
|
||||
control = OptionButton.new()
|
||||
for i in range(p.first, p.last):
|
||||
var s = pow(2, i)
|
||||
control.add_item("%dx%d" % [ s, s ])
|
||||
control.selected = 0 if !p.has("default") else p.default
|
||||
elif p.type == "enum":
|
||||
control = OptionButton.new()
|
||||
for i in p.values.size():
|
||||
var value = p.values[i]
|
||||
control.add_item(value.name)
|
||||
control.selected = 0 if !p.has("default") else p.default
|
||||
if control != null:
|
||||
var label = p.name
|
||||
control.name = label
|
||||
control_list.append(control)
|
||||
var sizer = HBoxContainer.new()
|
||||
sizer.size_flags_horizontal = SIZE_EXPAND | SIZE_FILL
|
||||
if p.has("label"):
|
||||
label = p.label
|
||||
if label != "":
|
||||
var label_widget = Label.new()
|
||||
label_widget.text = label
|
||||
label_widget.size_flags_horizontal = SIZE_EXPAND | SIZE_FILL
|
||||
sizer.add_child(label_widget)
|
||||
control.size_flags_horizontal = SIZE_EXPAND | SIZE_FILL
|
||||
sizer.add_child(control)
|
||||
add_child(sizer)
|
||||
initialize_properties(control_list)
|
||||
else:
|
||||
model_data.parameters = []
|
||||
if model_data.has("outputs") and typeof(model_data.outputs) == TYPE_ARRAY:
|
||||
for i in model_data.outputs.size():
|
||||
var output = model_data.outputs[i]
|
||||
var enable_right = false
|
||||
var color_right = Color(0.5, 0.5, 0.5)
|
||||
if typeof(output) == TYPE_DICTIONARY:
|
||||
if output.has("rgb"):
|
||||
enable_right = true
|
||||
color_right = Color(0.5, 0.5, 1.0)
|
||||
elif output.has("f"):
|
||||
enable_right = true
|
||||
set_slot(i, false, 0, color_right, enable_right, 0, color_right)
|
||||
else:
|
||||
model_data.outputs = []
|
||||
|
||||
func subst(string, uv = ""):
|
||||
string = string.replace("$(name)", name)
|
||||
string = string.replace("$(seed)", str(get_seed()))
|
||||
string = string.replace("$(uv)", uv)
|
||||
if model_data.has("parameters") and typeof(model_data.parameters) == TYPE_ARRAY:
|
||||
for p in model_data.parameters:
|
||||
if !p.has("name") or !p.has("type"):
|
||||
continue
|
||||
var value = parameters[p.name]
|
||||
var value_string = null
|
||||
if p.type == "float":
|
||||
value_string = "%.9f" % value
|
||||
elif p.type == "size":
|
||||
value_string = "%.9f" % pow(2, value+p.first)
|
||||
elif p.type == "enum":
|
||||
value_string = p.values[value].value
|
||||
if value_string != null:
|
||||
string = string.replace("$(%s)" % p.name, value_string)
|
||||
return string
|
||||
|
||||
func _get_shader_code(uv, slot = 0):
|
||||
var rv = { defs="", code="", f="0.0" }
|
||||
if model_data != null and model_data.has("outputs") and model_data.outputs.size() > slot:
|
||||
var output = model_data.outputs[slot]
|
||||
if model_data.has("instance") && generated_variants.empty():
|
||||
rv.defs = subst(model_data.instance)
|
||||
var variant_index = generated_variants.find(uv)
|
||||
if variant_index == -1:
|
||||
variant_index = generated_variants.size()
|
||||
generated_variants.append(uv)
|
||||
if output.has("rgb"):
|
||||
rv.code += "vec3 %s_%d_rgb = %s;\n" % [ name, variant_index, subst(output.rgb, uv) ]
|
||||
if output.has("f"):
|
||||
rv.code += "float %s_%d_f = %s;\n" % [ name, variant_index, subst(output.f, uv) ]
|
||||
if output.has("rgb"):
|
||||
rv.rgb = "%s_%d_rgb" % [ name, variant_index ]
|
||||
if output.has("f"):
|
||||
rv.f = "%s_%d_f" % [ name, variant_index ]
|
||||
return rv
|
||||
|
||||
func _on_offset_changed():
|
||||
update_shaders()
|
||||
|
||||
func serialize():
|
||||
var return_value = .serialize()
|
||||
return_value.type = model
|
||||
return return_value
|
27
addons/material_maker/nodes/noise.json
Normal file
27
addons/material_maker/nodes/noise.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name":"Noise",
|
||||
"parameters":[
|
||||
{ "name":"size", "label":"Grid Size:", "type":"size", "first":2, "last":12, "default":8 },
|
||||
{ "name":"density", "label":"Density:", "type":"float", "min":0.0, "max":1.0 }
|
||||
],
|
||||
"global":"
|
||||
float rand(vec2 x) {
|
||||
return fract(cos(dot(x, vec2(13.9898, 8.141))) * 43758.5453);
|
||||
}
|
||||
vec2 rand2(vec2 x) {
|
||||
return fract(cos(vec2(dot(x, vec2(13.9898, 8.141)),
|
||||
dot(x, vec2(3.4562, 17.398)))) * 43758.5453);
|
||||
}
|
||||
vec3 rand3(vec2 x) {
|
||||
return fract(cos(vec3(dot(x, vec2(13.9898, 8.141)),
|
||||
dot(x, vec2(3.4562, 17.398)),
|
||||
dot(x, vec2(13.254, 5.867)))) * 43758.5453);
|
||||
}",
|
||||
"instance":"
|
||||
float $(name)_f(vec2 uv) {
|
||||
return dots(uv, 1.0/$(size), $(density), $(seed));
|
||||
}",
|
||||
"outputs":[
|
||||
{ "f":"$(name)_f($(uv))" }
|
||||
]
|
||||
}
|
@ -1,20 +1,17 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var size = 4
|
||||
var density = 0.5
|
||||
|
||||
func _ready():
|
||||
$HBoxContainer1/size.clear()
|
||||
for i in range(7):
|
||||
$HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i)
|
||||
$HBoxContainer1/size.selected = size
|
||||
$HBoxContainer1/size.selected = 4
|
||||
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/density ])
|
||||
|
||||
func _get_shader_code(uv):
|
||||
var rv = { defs="", code="" }
|
||||
if generated_variants.empty():
|
||||
rv.defs = "float %s_f(vec2 uv) { return dots(uv, %.9f, %.9f, %d); }\n" % [ name, 1.0/pow(2.0, 5.0+size), density, get_seed() ]
|
||||
rv.defs = "float %s_f(vec2 uv) { return dots(uv, %.9f, %.9f, %d); }\n" % [ name, 1.0/pow(2.0, 5.0+parameters.size), parameters.density, get_seed() ]
|
||||
var variant_index = generated_variants.find(uv)
|
||||
if variant_index == -1:
|
||||
variant_index = generated_variants.size()
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
[ext_resource path="res://addons/material_maker/nodes/noise/noise.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[sub_resource type="Theme" id=1]
|
||||
|
||||
|
||||
[node name="Dots" type="GraphNode" index="0"]
|
||||
[node name="Dots" type="GraphNode"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
|
@ -1,9 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var size = 5
|
||||
var amount = 0.0
|
||||
|
||||
var input_shader = ""
|
||||
var input_texture
|
||||
var final_texture
|
||||
@ -29,19 +26,20 @@ func _ready():
|
||||
$HBoxContainer1/size.clear()
|
||||
for i in range(7):
|
||||
$HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i)
|
||||
$HBoxContainer1/size.selected = size
|
||||
parameters.size = 2
|
||||
$HBoxContainer1/size.selected = parameters.size
|
||||
input_texture = ImageTexture.new()
|
||||
final_texture = ImageTexture.new()
|
||||
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/amount ])
|
||||
|
||||
func _rerender():
|
||||
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+size)), input_texture, self, "pass_1", [])
|
||||
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), input_texture, self, "pass_1", [])
|
||||
|
||||
func pass_1():
|
||||
var convolution = CONVOLUTION
|
||||
convolution.epsilon=1.0/pow(2, 5+size)
|
||||
convolution.scale_before_normalize = pow(2, size-1)*amount
|
||||
get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), { input=input_texture}, int(pow(2, 5+size)), final_texture, self, "rerender_targets", [])
|
||||
convolution.epsilon=1.0/pow(2, 5+parameters.size)
|
||||
convolution.scale_before_normalize = pow(2, parameters.size-1)*parameters.amount
|
||||
get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), { input=input_texture}, int(pow(2, 5+parameters.size)), final_texture, self, "rerender_targets", [])
|
||||
|
||||
func get_textures():
|
||||
var list = {}
|
||||
|
@ -1,12 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var mix = 0;
|
||||
var x_wave = 0
|
||||
var x_scale = 4.0
|
||||
var y_wave = 0
|
||||
var y_scale = 4.0
|
||||
|
||||
const WAVE_FCT = [ "wave_sin", "wave_triangle", "wave_square", "fract", "wave_constant" ]
|
||||
const MIX_FCT = [ "mix_multiply", "mix_add", "mix_max", "mix_min", "mix_xor", "mix_pow" ]
|
||||
|
||||
@ -16,7 +10,7 @@ func _ready():
|
||||
func _get_shader_code(uv):
|
||||
var rv = { defs="", code="" }
|
||||
if generated_variants.empty():
|
||||
rv.defs = "float %s_f(vec2 uv) { uv *= vec2(%.9f, %.9f); return %s(%s(uv.x), %s(uv.y)); }\n" % [ name, x_scale, y_scale, MIX_FCT[mix], WAVE_FCT[x_wave], WAVE_FCT[y_wave] ]
|
||||
rv.defs = "float %s_f(vec2 uv) { uv *= vec2(%.9f, %.9f); return %s(%s(uv.x), %s(uv.y)); }\n" % [ name, parameters.x_scale, parameters.y_scale, MIX_FCT[parameters.mix], WAVE_FCT[parameters.x_wave], WAVE_FCT[parameters.y_wave] ]
|
||||
var variant_index = generated_variants.find(uv)
|
||||
if variant_index == -1:
|
||||
variant_index = generated_variants.size()
|
||||
|
@ -1,11 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var scale_x
|
||||
var scale_y
|
||||
var iterations
|
||||
var persistence
|
||||
|
||||
func _ready():
|
||||
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
|
||||
initialize_properties([ $GridContainer/scale_x, $GridContainer/scale_y, $GridContainer/iterations, $GridContainer/persistence ])
|
||||
@ -13,7 +8,7 @@ func _ready():
|
||||
func _get_shader_code(uv):
|
||||
var rv = { defs="", code="" }
|
||||
if generated_variants.empty():
|
||||
rv.defs = "float %s_f(vec2 uv) { return perlin(uv, vec2(%f, %f), %d, %.9f, %d); }\n" % [ name, scale_x, scale_y, iterations, persistence, get_seed() ]
|
||||
rv.defs = "float %s_f(vec2 uv) { return perlin(uv, vec2(%f, %f), %d, %.9f, %d); }\n" % [ name, parameters.scale_x, parameters.scale_y, parameters.iterations, parameters.persistence, get_seed() ]
|
||||
var variant_index = generated_variants.find(uv)
|
||||
if variant_index == -1:
|
||||
variant_index = generated_variants.size()
|
||||
|
@ -1,11 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var shape
|
||||
var sides
|
||||
var radius
|
||||
var edge
|
||||
|
||||
const SHAPES = [ "circle", "polygon", "star", "curved_star", "rays" ]
|
||||
|
||||
func _ready():
|
||||
@ -13,5 +8,5 @@ func _ready():
|
||||
|
||||
func _get_shader_code(uv):
|
||||
var rv = { defs="", code="" }
|
||||
rv.f = "%s(%s, %d, %f, %f)" % [ SHAPES[shape], uv, sides, radius, edge ]
|
||||
rv.f = "%s(%s, %d, %f, %f)" % [ SHAPES[parameters.shape], uv, parameters.sides, parameters.radius, parameters.edge ]
|
||||
return rv
|
||||
|
@ -1,8 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var source = 0
|
||||
|
||||
func _ready():
|
||||
initialize_properties([ $source ])
|
||||
|
||||
@ -12,7 +10,7 @@ func reset():
|
||||
|
||||
func _get_shader_code(uv, index = 0):
|
||||
var rv = { defs="", code="" }
|
||||
var src = get_source(2*source+index)
|
||||
var src = get_source(2*parameters.source+index)
|
||||
var src_code = { defs="", code="", rgb="0.0" }
|
||||
if src != null:
|
||||
src_code = src.get_shader_code(uv)
|
||||
|
@ -1,13 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var translate_x = 0.0
|
||||
var translate_y = 0.0
|
||||
var rotate = 0.0
|
||||
var scale_x = 1.0
|
||||
var scale_y = 1.0
|
||||
var repeat = true
|
||||
|
||||
func _ready():
|
||||
set_slot(0, true, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
|
||||
initialize_properties([ $HBoxContainer1/translate_x, $HBoxContainer2/translate_y, $HBoxContainer3/rotate, $HBoxContainer4/scale_x, $HBoxContainer5/scale_y, $repeat ])
|
||||
@ -30,7 +23,7 @@ func _get_shader_code(uv):
|
||||
rv.defs += tsrc_code.defs
|
||||
rv.code += tsrc_code.code
|
||||
inputs[i] = "*(2.0*(%s)-1.0)" % tsrc_code.f
|
||||
rv.code += "vec2 %s_%d_uv = %s(%s, vec2(%.9f%s, %.9f%s), %.9f%s, vec2(%.9f%s, %.9f%s));\n" % [ name, variant_index, "transform_repeat" if repeat else "transform_norepeat", uv, translate_x, inputs[0], translate_y, inputs[1], PI*rotate/180.0, inputs[2], scale_x, inputs[3], scale_y, inputs[4] ]
|
||||
rv.code += "vec2 %s_%d_uv = %s(%s, vec2(%.9f%s, %.9f%s), %.9f%s, vec2(%.9f%s, %.9f%s));\n" % [ name, variant_index, "transform_repeat" if parameters.repeat else "transform_norepeat", uv, parameters.translate_x, inputs[0], parameters.translate_y, inputs[1], PI*parameters.rotate/180.0, inputs[2], parameters.scale_x, inputs[3], parameters.scale_y, inputs[4] ]
|
||||
var src_code = src.get_shader_code("%s_%d_uv" % [ name, variant_index ])
|
||||
if rv.code != "":
|
||||
if generated_variants.size() == 1:
|
||||
@ -41,6 +34,6 @@ func _get_shader_code(uv):
|
||||
|
||||
func deserialize(data):
|
||||
if data.has("scale"):
|
||||
scale_x = data.scale
|
||||
scale_y = data.scale
|
||||
parameters.scale_x = data.scale
|
||||
parameters.scale_y = data.scale
|
||||
.deserialize(data)
|
||||
|
@ -1,12 +1,10 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var color = Color(0.0, 0.0, 0.0)
|
||||
|
||||
func _ready():
|
||||
initialize_properties([ $color ])
|
||||
|
||||
func _get_shader_code(uv):
|
||||
var rv = { defs="", code="" }
|
||||
rv.rgb = "vec3(%.9f, %.9f, %.9f)" % [ color.r, color.g, color.b ]
|
||||
rv.rgb = "vec3(%.9f, %.9f, %.9f)" % [ parameters.color.r, parameters.color.g, parameters.color.b ]
|
||||
return rv
|
||||
|
@ -1,10 +1,6 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var scale_x
|
||||
var scale_y
|
||||
var intensity
|
||||
|
||||
func _ready():
|
||||
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
|
||||
initialize_properties([ $HBoxContainer1/scale_x, $HBoxContainer2/scale_y, $HBoxContainer3/intensity ])
|
||||
@ -12,7 +8,7 @@ func _ready():
|
||||
func _get_shader_code(uv, slot = 0):
|
||||
var rv = { defs="", code="" }
|
||||
if generated_variants.empty():
|
||||
rv.defs = "vec4 %s_xyzw(vec2 uv) { return voronoi(uv, vec2(%f, %f), %.9f, %d); }\n" % [ name, scale_x, scale_y, intensity, get_seed() ]
|
||||
rv.defs = "vec4 %s_xyzw(vec2 uv) { return voronoi(uv, vec2(%f, %f), %.9f, %d); }\n" % [ name, parameters.scale_x, parameters.scale_y, parameters.intensity, get_seed() ]
|
||||
var variant_index = generated_variants.find(uv)
|
||||
if variant_index == -1:
|
||||
variant_index = generated_variants.size()
|
||||
|
@ -1,11 +1,7 @@
|
||||
tool
|
||||
extends "res://addons/material_maker/node_base.gd"
|
||||
|
||||
var amount = 0.0
|
||||
|
||||
func _ready():
|
||||
set_slot(0, true, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
|
||||
set_slot(1, true, 0, Color(0.5, 0.5, 1), false, 0, Color(0.5, 0.5, 1))
|
||||
initialize_properties([ $amount ])
|
||||
|
||||
func _get_shader_code(uv):
|
||||
@ -25,7 +21,7 @@ func _get_shader_code(uv):
|
||||
var src1_code3 = src1.get_shader_code("fract(%s-vec2(0.0, %.9f))" % [ uv, epsilon ])
|
||||
rv.defs = src1_code0.defs
|
||||
rv.code = src1_code0.code+src1_code1.code+src1_code2.code+src1_code3.code
|
||||
rv.code += "vec2 %s_%d_uv = %s+%.9f*vec2((%s)-(%s), (%s)-(%s));\n" % [ name, variant_index, uv, amount, src1_code0.f, src1_code1.f, src1_code2.f, src1_code3.f ]
|
||||
rv.code += "vec2 %s_%d_uv = %s+%.9f*vec2((%s)-(%s), (%s)-(%s));\n" % [ name, variant_index, uv, parameters.amount, src1_code0.f, src1_code1.f, src1_code2.f, src1_code3.f ]
|
||||
var src0_code = src0.get_shader_code("%s_%d_uv" % [ name, variant_index ])
|
||||
rv.defs += src0_code.defs
|
||||
rv.code += src0_code.code
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
[ext_resource path="res://addons/material_maker/nodes/warp/warp.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[sub_resource type="Theme" id=1]
|
||||
|
||||
|
||||
|
@ -52,7 +52,7 @@ func apply_configuration(c):
|
||||
for w in configurations[c]:
|
||||
var value = duplicate_value(w.value)
|
||||
w.widget.set(WIDGETS[get_widget_type(w.widget)].value_attr, value)
|
||||
w.node.set(w.widget.name, value)
|
||||
w.node.parameters[w.widget.name] = value
|
||||
var graph_node = get_parent()
|
||||
while !(graph_node is GraphNode):
|
||||
graph_node = graph_node.get_parent()
|
||||
@ -61,7 +61,7 @@ func apply_configuration(c):
|
||||
func do_update_configuration(name):
|
||||
var configuration = []
|
||||
for w in linked_widgets:
|
||||
configuration.append({ node=w.node, widget=w.widget, value=duplicate_value(w.node.get(w.widget.name)) })
|
||||
configuration.append({ node=w.node, widget=w.widget, value=duplicate_value(w.node.parameters[w.widget.name]) })
|
||||
configurations[name] = configuration
|
||||
current = name
|
||||
update_options()
|
||||
|
@ -68,24 +68,25 @@ func update_shaders():
|
||||
func _on_value_changed(v):
|
||||
for l in linked_widgets:
|
||||
l.widget.value = v
|
||||
l.node.set(l.widget.name, v)
|
||||
l.node.parameters[l.widget.name] = v
|
||||
update_shaders()
|
||||
|
||||
func _on_color_changed(c):
|
||||
for l in linked_widgets:
|
||||
l.widget.color = c
|
||||
l.node.set(l.widget.name, c)
|
||||
l.node.parameters[l.widget.name] = c
|
||||
update_shaders()
|
||||
|
||||
func _on_item_selected(i):
|
||||
for l in linked_widgets:
|
||||
l.widget.selected = i
|
||||
l.node.set(l.widget.name, i)
|
||||
l.node.parameters[l.widget.name] = i
|
||||
update_shaders()
|
||||
|
||||
func _on_gradient_updated(g):
|
||||
for l in linked_widgets:
|
||||
l.widget.value = g
|
||||
l.node.parameters[l.widget.name] = g
|
||||
update_shaders()
|
||||
|
||||
func serialize():
|
||||
|
187
addons/material_maker/widgets/node_editor.tscn
Normal file
187
addons/material_maker/widgets/node_editor.tscn
Normal file
@ -0,0 +1,187 @@
|
||||
[gd_scene format=2]
|
||||
|
||||
[node name="WindowDialog" type="WindowDialog" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_right = 666.0
|
||||
margin_bottom = 592.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
popup_exclusive = false
|
||||
window_title = "Custom node"
|
||||
resizable = true
|
||||
|
||||
[node name="TabContainer" type="TabContainer" parent="." index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_right = -89.0
|
||||
margin_bottom = -41.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
tab_align = 1
|
||||
tabs_visible = true
|
||||
|
||||
[node name="General" type="VBoxContainer" parent="TabContainer" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_top = 26.0
|
||||
margin_bottom = 26.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
alignment = 0
|
||||
_sections_unfolded = [ "Anchor", "Grow Direction", "Margin", "Size Flags" ]
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/General" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_right = 577.0
|
||||
margin_bottom = 24.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
alignment = 0
|
||||
_sections_unfolded = [ "Size Flags" ]
|
||||
|
||||
[node name="Label" type="Label" parent="TabContainer/General/HBoxContainer" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_top = 5.0
|
||||
margin_right = 42.0
|
||||
margin_bottom = 19.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 4
|
||||
text = "Name:"
|
||||
percent_visible = 1.0
|
||||
lines_skipped = 0
|
||||
max_lines_visible = -1
|
||||
|
||||
[node name="LineEdit" type="LineEdit" parent="TabContainer/General/HBoxContainer" index="1"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 46.0
|
||||
margin_right = 577.0
|
||||
margin_bottom = 24.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 1
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
focus_mode = 2
|
||||
context_menu_enabled = true
|
||||
placeholder_alpha = 0.6
|
||||
caret_blink = false
|
||||
caret_blink_speed = 0.65
|
||||
caret_position = 0
|
||||
_sections_unfolded = [ "Size Flags" ]
|
||||
|
||||
[node name="Global functions" type="TextEdit" parent="TabContainer" index="1"]
|
||||
|
||||
visible = false
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_top = 72.0
|
||||
margin_right = -8.0
|
||||
margin_bottom = 36.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = ""
|
||||
readonly = false
|
||||
highlight_current_line = false
|
||||
syntax_highlighting = false
|
||||
show_line_numbers = false
|
||||
highlight_all_occurrences = false
|
||||
override_selected_font_color = false
|
||||
context_menu_enabled = true
|
||||
smooth_scrolling = false
|
||||
v_scroll_speed = 80.0
|
||||
hiding_enabled = 0
|
||||
wrap_lines = false
|
||||
caret_block_mode = false
|
||||
caret_blink = false
|
||||
caret_blink_speed = 0.65
|
||||
caret_moving_by_right_click = true
|
||||
_sections_unfolded = [ "Size Flags" ]
|
||||
|
||||
[node name="Instance functions" type="TextEdit" parent="TabContainer" index="2"]
|
||||
|
||||
visible = false
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 4.0
|
||||
margin_top = 32.0
|
||||
margin_right = -4.0
|
||||
margin_bottom = -4.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = ""
|
||||
readonly = false
|
||||
highlight_current_line = false
|
||||
syntax_highlighting = false
|
||||
show_line_numbers = false
|
||||
highlight_all_occurrences = false
|
||||
override_selected_font_color = false
|
||||
context_menu_enabled = true
|
||||
smooth_scrolling = false
|
||||
v_scroll_speed = 80.0
|
||||
hiding_enabled = 0
|
||||
wrap_lines = false
|
||||
caret_block_mode = false
|
||||
caret_blink = false
|
||||
caret_blink_speed = 0.65
|
||||
caret_moving_by_right_click = true
|
||||
_sections_unfolded = [ "Size Flags" ]
|
||||
|
||||
|
16
addons/material_maker/widgets/node_editor/node_editor.gd
Normal file
16
addons/material_maker/widgets/node_editor/node_editor.gd
Normal file
@ -0,0 +1,16 @@
|
||||
extends WindowDialog
|
||||
|
||||
var model_data
|
||||
|
||||
func _init(data):
|
||||
model_data = data
|
||||
|
||||
func _ready():
|
||||
# Called when the node is added to the scene for the first time.
|
||||
# Initialization here
|
||||
pass
|
||||
|
||||
#func _process(delta):
|
||||
# # Called every frame. Delta is time since last frame.
|
||||
# # Update game logic here.
|
||||
# pass
|
73
addons/material_maker/widgets/node_editor/node_editor.tscn
Normal file
73
addons/material_maker/widgets/node_editor/node_editor.tscn
Normal file
@ -0,0 +1,73 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/material_maker/widgets/node_editor/node_editor.gd" type="Script" id=1]
|
||||
|
||||
[node name="NodeEditor" type="WindowDialog" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_right = 469.0
|
||||
margin_bottom = 373.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
popup_exclusive = false
|
||||
window_title = "Node Editor"
|
||||
resizable = false
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Tabs" type="TabContainer" parent="." index="1"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
tab_align = 0
|
||||
tabs_visible = true
|
||||
|
||||
[node name="Global" type="TextEdit" parent="Tabs" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 4.0
|
||||
margin_top = 32.0
|
||||
margin_right = -4.0
|
||||
margin_bottom = -4.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
text = ""
|
||||
readonly = false
|
||||
highlight_current_line = false
|
||||
syntax_highlighting = false
|
||||
show_line_numbers = false
|
||||
highlight_all_occurrences = false
|
||||
override_selected_font_color = false
|
||||
context_menu_enabled = true
|
||||
smooth_scrolling = false
|
||||
v_scroll_speed = 80.0
|
||||
hiding_enabled = 0
|
||||
wrap_lines = false
|
||||
caret_block_mode = false
|
||||
caret_blink = false
|
||||
caret_blink_speed = 0.65
|
||||
caret_moving_by_right_click = true
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user