More progress on refactoring and more

Basic import plugin works.
Added gradient parameter to custom node.
hsv_adjust now supports alpha channel.
Remove deprecated scenes.
This commit is contained in:
Rodolphe Suescun 2019-08-09 08:16:24 +02:00
parent 66f88f3f46
commit bcdac09cd7
28 changed files with 290 additions and 751 deletions

View File

@ -13,10 +13,14 @@ class OutputPort:
func get_shader():
return generator.get_shader(output_index)
func get_shader_code(uv):
return generator.get_shader_code(uv, output_index)
func get_globals():
return generator.get_globals()
var parameters = null
func to_str():
return generator.name+"("+str(output_index)+")"
func get_seed():
return 0

View File

@ -2,9 +2,11 @@ tool
extends MMGenBase
class_name MMGenMaterial
var parameters = {}
var texture_list
var material
var material : SpatialMaterial
var generated_textures = {}
const TEXTURE_LIST = [
@ -33,9 +35,15 @@ func _ready():
generated_textures[t.texture] = { shader=null, source=null, texture=null }
material = SpatialMaterial.new()
func generate_material():
print("Generating material")
print(get_source(0).get_shader())
func generate_material(renderer : MMGenRenderer):
var source = get_source(0)
if source != null:
var shader : String = renderer.generate_shader(source)
var status = renderer.render_shader(shader, {}, 512)
while status is GDScriptFunctionState:
status = yield(status, "completed")
renderer.get_texture().get_data().save_png("res://test.png")
material.albedo_texture = load("res://test.png")
return material
func initialize(data: Dictionary):

View File

@ -3,6 +3,7 @@ extends MMGenBase
class_name MMGenShader
var model_data = null
var parameters = {}
var generated_variants = []
func set_model_data(data: Dictionary):
@ -94,6 +95,8 @@ func subst(string, uv = ""):
value_string = p.values[value].value
elif p.type == "color":
value_string = "vec4(%.9f, %.9f, %.9f, %.9f)" % [ value.r, value.g, value.b, value.a ]
elif p.type == "gradient":
value_string = p.name+"_gradient_fct"
if value_string != null:
string = replace_variable(string, p.name, value_string)
if model_data.has("inputs") and typeof(model_data.inputs) == TYPE_ARRAY:
@ -112,8 +115,16 @@ func _get_shader_code(uv, slot = 0):
var variant_string = uv+","+str(slot)
if model_data != null and model_data.has("outputs") and model_data.outputs.size() > slot:
var output = model_data.outputs[slot]
rv.defs = ""
if model_data.has("instance") && generated_variants.empty():
rv.defs = subst(model_data.instance).string
rv.defs += subst(model_data.instance).string
for p in model_data.parameters:
if p.type == "gradient":
var g = parameters[p.name]
if !(g is MMGradient):
g = MMGradient.new()
g.deserialize(parameters[p.name])
rv.defs += g.get_shader(p.name+"_gradient_fct")
var variant_index = generated_variants.find(variant_string)
if variant_index == -1:
variant_index = generated_variants.size()

View File

@ -24,15 +24,18 @@ func create_gen(data) -> MMGenBase:
else:
generator = MMGenShader.new()
if data.type == "custom":
pass
generator.set_model_data(data.model_data)
else:
var file = File.new()
if file.open("res://addons/material_maker/nodes/"+data.type+".mmn", File.READ) == OK:
var model_data = parse_json(file.get_as_text())
print("loaded description "+data.type+".mmn")
generator.set_model_data(model_data)
file.close()
else:
print("Cannot find description for "+data.type)
else:
print(data)
if generator != null and data.has("parameters"):
generator.initialize(data)
return generator

View File

@ -0,0 +1,92 @@
tool
extends Viewport
class_name MMGenRenderer
export(String) var debug_path = null
var debug_file_index : int = 0
var rendering : bool = false
func _ready():
$ColorRect.material = $ColorRect.material.duplicate(true)
static func generate_shader(src_code):
var code
code = "shader_type canvas_item;\n"
code += "render_mode blend_disabled;\n"
var file = File.new()
file.open("res://addons/material_maker/common.shader", File.READ)
code += file.get_as_text()
code += "\n"
if src_code.has("globals"):
for g in src_code.globals:
code += g
var shader_code = src_code.defs
shader_code += "void fragment() {\n"
shader_code += src_code.code
shader_code += "COLOR = "+src_code.rgba+";\n"
shader_code += "}\n"
#print("GENERATED SHADER:\n"+shader_code)
code += shader_code
return code
static func generate_combined_shader(red_code, green_code, blue_code):
var code
code = "shader_type canvas_item;\n"
code += "render_mode blend_disabled;\n"
var file = File.new()
file.open("res://addons/material_maker/common.shader", File.READ)
code += file.get_as_text()
code += "\n"
if red_code.has("globals"):
for g in red_code.globals:
code += g
if green_code.has("globals"):
for g in green_code.globals:
code += g
if blue_code.has("globals"):
for g in blue_code.globals:
code += g
var shader_code = ""
shader_code += red_code.defs
shader_code += green_code.defs
shader_code += blue_code.defs
shader_code += "void fragment() {\n"
shader_code += red_code.code
shader_code += green_code.code
shader_code += blue_code.code
shader_code += "COLOR = vec4("+red_code.f+", "+green_code.f+", "+blue_code.f+", 1.0);\n"
shader_code += "}\n"
#print("GENERATED COMBINED SHADER:\n"+shader_code)
code += shader_code
return code
func setup_material(shader_material, textures, shader_code):
for k in textures.keys():
shader_material.set_shader_param(k+"_tex", textures[k])
shader_material.shader.code = shader_code
func render_shader(shader, textures, render_size):
if rendering:
return false
rendering = true
if debug_path != null and debug_path != "":
var f = File.new()
f.open(debug_path+str(debug_file_index)+".shader", File.WRITE)
f.store_string(shader)
f.close()
debug_file_index += 1
size = Vector2(render_size, render_size)
$ColorRect.rect_position = Vector2(0, 0)
$ColorRect.rect_size = size
var shader_material = $ColorRect.material
shader_material.shader.code = shader
if textures != null:
for k in textures.keys():
shader_material.set_shader_param(k+"_tex", textures[k])
render_target_update_mode = Viewport.UPDATE_ONCE
update_worlds()
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
rendering = false
return true

View File

@ -0,0 +1,34 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://addons/material_maker/engine/renderer.gd" type="Script" id=1]
[sub_resource type="Shader" id=1]
code = "shader_type canvas_item;
void fragment() {
COLOR = vec4(1.0);
}
"
[sub_resource type="ShaderMaterial" id=2]
shader = SubResource( 1 )
[node name="Renderer" type="Viewport"]
own_world = true
transparent_bg = true
hdr = false
usage = 0
render_target_v_flip = true
render_target_update_mode = 1
gui_disable_input = true
script = ExtResource( 1 )
debug_path = null
[node name="ColorRect" type="ColorRect" parent="."]
material = SubResource( 2 )
margin_right = 40.0
margin_bottom = 40.0
[node name="Timer" type="Timer" parent="."]
wait_time = 0.1
one_shot = true

View File

@ -159,7 +159,7 @@ func do_load_file(filename):
file.close()
clear_material()
for n in data.nodes:
var node = create_nodes(n)
create_nodes(n)
for c in data.connections:
connect_node(c.from, c.from_port, c.to, c.to_port)
set_save_path(filename)

View File

@ -42,7 +42,9 @@ func get_visible_name():
return "Material Maker Importer"
func import(source_file: String, save_path: String, options: Dictionary, platform_variants: Array, gen_files: Array) -> int:
var material = SpatialMaterial.new()
var filename = save_path + "." + get_save_extension()
ResourceSaver.save(filename, plugin.generate_material(source_file))
var material = plugin.generate_material(source_file)
while material is GDScriptFunctionState:
material = yield(material, "completed")
ResourceSaver.save(filename, material)
return OK

View File

@ -77,6 +77,7 @@ func update_property_widgets():
elif o is ColorPickerButton:
o.color = parameters[o.name]
elif o is Control and o.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
print("Updating "+o.name+" = "+str(parameters[o.name].to_string()))
o.value = parameters[o.name]
else:
print("Failed to update "+o.name)

View File

@ -1 +1 @@
{"global":"vec3 rgb_to_hsv(vec3 c) {\n\tvec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n\tvec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);\n\tvec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);\n\n\tfloat d = q.x - min(q.w, q.y);\n\tfloat e = 1.0e-10;\n\treturn vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\n\nvec3 hsv_to_rgb(vec3 c) {\n\tvec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n\tvec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n\treturn c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n","inputs":[{"default":"vec3($uv.x, $uv.y, 0.0)","label":"","name":"in","type":"rgb"}],"instance":"vec3 $(name)_f(vec3 c) {\n\tvec3 hsv = rgb_to_hsv(c);\n\treturn hsv_to_rgb(vec3(fract(hsv.x+$(hue)), clamp(hsv.y*$(saturation), 0.0, 1.0), clamp(hsv.z*$(value), 0.0, 1.0)));\n}","name":"AdjustHSV","outputs":[{"rgb":"$(name)_f($in($(uv)))"}],"parameters":[{"default":0,"label":"Hue","max":0.5,"min":-0.5,"name":"hue","step":0,"type":"float"},{"default":1,"label":"Saturation","max":2,"min":0,"name":"saturation","step":0,"type":"float"},{"default":1,"label":"Value","max":2,"min":0,"name":"value","step":0,"type":"float"}]}
{"global":"vec3 rgb_to_hsv(vec3 c) {\n\tvec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n\tvec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);\n\tvec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);\n\n\tfloat d = q.x - min(q.w, q.y);\n\tfloat e = 1.0e-10;\n\treturn vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\n\nvec3 hsv_to_rgb(vec3 c) {\n\tvec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n\tvec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n\treturn c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n","inputs":[{"default":"vec4($uv.x, $uv.y, 0.0, 1.0)","label":"","name":"in","type":"rgba"}],"instance":"vec4 $(name)_f(vec4 c) {\n\tvec3 hsv = rgb_to_hsv(c.rgb);\n\treturn vec4(hsv_to_rgb(vec3(fract(hsv.x+$(hue)), clamp(hsv.y*$(saturation), 0.0, 1.0), clamp(hsv.z*$(value), 0.0, 1.0))), c.a);\n}","name":"AdjustHSV","outputs":[{"rgba":"$(name)_f($in($(uv)))"}],"parameters":[{"default":0,"label":"Hue","max":0.5,"min":-0.5,"name":"hue","step":0,"type":"float"},{"default":1,"label":"Saturation","max":2,"min":0,"name":"saturation","step":0,"type":"float"},{"default":1,"label":"Value","max":2,"min":0,"name":"value","step":0,"type":"float"}]}

View File

@ -1,24 +0,0 @@
tool
extends "res://addons/material_maker/node_base.gd"
func _ready():
initialize_properties([ $HBoxContainer1/hue, $HBoxContainer2/saturation, $HBoxContainer3/value ])
func _get_shader_code(uv, output = 0):
var rv = { defs="", code="" }
var src = get_source()
var src_code = { defs="", code="", rgb="vec3(0.0)" }
if src == null:
return rv
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, parameters.hue, parameters.saturation, parameters.value ]
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
generated_variants.append(uv)
rv.code = src_code.code
rv.code += "vec3 %s_%d_rgb = %s_rgb(%s);\n" % [ name, variant_index, name, src_code.rgb ]
rv.rgb = "%s_%d_rgb" % [ name, variant_index ]
return rv

View File

@ -1,256 +0,0 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/material_maker/nodes/adjust_hsv/adjust_hsv.gd" type="Script" id=1]
[sub_resource type="Theme" id=1]
[node name="AdjustHSV" 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 = 111.0
margin_bottom = 74.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 = "AdjustHSV"
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.498039, 0.498039, 1, 1 )
slot/0/right_enabled = true
slot/0/right_type = 0
slot/0/right_color = Color( 0.494118, 0.494118, 1, 1 )
slot/1/left_enabled = false
slot/1/left_type = 0
slot/1/left_color = Color( 0.756863, 0.756863, 0.756863, 1 )
slot/1/right_enabled = false
slot/1/right_type = 0
slot/1/right_color = Color( 0.756863, 0.756863, 0.756863, 1 )
slot/2/left_enabled = false
slot/2/left_type = 0
slot/2/left_color = Color( 0.756863, 0.756863, 0.756863, 1 )
slot/2/right_enabled = false
slot/2/right_type = 0
slot/2/right_color = Color( 0.756863, 0.756863, 0.756863, 1 )
script = ExtResource( 1 )
_sections_unfolded = [ "Theme", "slot", "slot/0", "slot/1", "slot/2" ]
[node name="HBoxContainer1" 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 = 184.0
margin_bottom = 40.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="Label" type="Label" parent="HBoxContainer1" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 1.0
margin_right = 64.0
margin_bottom = 15.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 4
text = "Hue"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="hue" type="HSlider" parent="HBoxContainer1" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 68.0
margin_right = 168.0
margin_bottom = 16.0
rect_min_size = Vector2( 100, 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 = 0
min_value = -0.5
max_value = 0.5
step = 0.02
page = 0.0
value = 0.0
exp_edit = false
rounded = false
editable = true
tick_count = 0
ticks_on_borders = false
focus_mode = 2
_sections_unfolded = [ "Rect" ]
[node name="HBoxContainer2" type="HBoxContainer" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0
margin_top = 40.0
margin_right = 184.0
margin_bottom = 56.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="Label" type="Label" parent="HBoxContainer2" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 1.0
margin_right = 64.0
margin_bottom = 15.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 4
text = "Saturation"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="saturation" type="HSlider" parent="HBoxContainer2" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 68.0
margin_right = 168.0
margin_bottom = 16.0
rect_min_size = Vector2( 100, 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 = 0
min_value = 0.0
max_value = 2.0
step = 0.1
page = 0.0
value = 1.0
exp_edit = false
rounded = false
editable = true
tick_count = 0
ticks_on_borders = false
focus_mode = 2
_sections_unfolded = [ "Rect" ]
[node name="HBoxContainer3" type="HBoxContainer" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0
margin_top = 57.0
margin_right = 184.0
margin_bottom = 73.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="Label" type="Label" parent="HBoxContainer3" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 1.0
margin_right = 64.0
margin_bottom = 15.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 4
text = "Value"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="value" type="HSlider" parent="HBoxContainer3" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 68.0
margin_right = 168.0
margin_bottom = 16.0
rect_min_size = Vector2( 100, 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 = 0
min_value = 0.0
max_value = 2.0
step = 0.1
page = 0.0
value = 1.0
exp_edit = false
rounded = false
editable = true
tick_count = 0
ticks_on_borders = false
focus_mode = 2
_sections_unfolded = [ "Rect" ]

View File

@ -4,30 +4,14 @@
[sub_resource type="Theme" id=1]
[node name="Blend" type="GraphNode" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Blend" type="GraphNode"]
margin_left = 1.0
margin_right = 160.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
theme = SubResource( 1 )
title = "Blend"
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 )
@ -53,140 +37,46 @@ slot/3/right_enabled = false
slot/3/right_type = 0
slot/3/right_color = Color( 1, 1, 1, 0.501961 )
script = ExtResource( 1 )
_sections_unfolded = [ "Mouse", "Theme", "slot", "slot/0", "slot/1", "slot/2", "slot/3" ]
[node name="blend_type" type="OptionButton" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="blend_type" type="OptionButton" parent="."]
margin_left = 16.0
margin_top = 24.0
margin_right = 143.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
text = "Normal"
flat = false
align = 0
items = [ "Normal", null, false, 0, null, "Dissolve", null, false, 1, null, "Multiply", null, false, 2, null, "Screen", null, false, 3, null, "Overlay", null, false, 4, null, "Hard Light", null, false, 5, null, "Soft Light", null, false, 6, null, "Burn", null, false, 7, null, "Dodge", null, false, 8, null, "Lighten", null, false, 9, null, "Darken", null, false, 10, null, "Difference", null, false, 11, null ]
selected = 0
[node name="Label1" type="Label" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Label1" type="Label" parent="."]
margin_left = 16.0
margin_top = 44.0
margin_right = 143.0
margin_bottom = 58.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 = "Source 1"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Label2" type="Label" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Label2" type="Label" parent="."]
margin_left = 16.0
margin_top = 59.0
margin_right = 143.0
margin_bottom = 73.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 = "Source 2"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HBoxContainer" type="HBoxContainer" parent="." index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="HBoxContainer" type="HBoxContainer" parent="."]
margin_left = 16.0
margin_top = 74.0
margin_right = 143.0
margin_bottom = 98.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
alignment = 0
[node name="Label3" type="Label" parent="HBoxContainer" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Label3" type="Label" parent="HBoxContainer"]
margin_top = 5.0
margin_right = 49.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 = "Opacity"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="amount" type="SpinBox" parent="HBoxContainer" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="amount" type="SpinBox" parent="HBoxContainer"]
margin_left = 53.0
margin_right = 127.0
margin_bottom = 24.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
min_value = 0.0
max_value = 1.0
step = 0.05
page = 0.0
value = 0.5
exp_edit = false
rounded = false
editable = true
prefix = ""
suffix = ""

View File

@ -0,0 +1 @@
{"global":"","inputs":[{"default":"0.0","label":"Input","name":"input","type":"f"}],"instance":"","name":"Colorize","outputs":[{"rgba":"$gradient($input($uv))"}],"parameters":[{"default":{"points":[{"a":1,"b":0,"g":0,"pos":0,"r":0},{"a":1,"b":1,"g":1,"pos":1,"r":1}],"type":"Gradient"},"label":"","name":"gradient","type":"gradient"}]}

View File

@ -1,25 +0,0 @@
tool
extends "res://addons/material_maker/node_base.gd"
func _ready():
initialize_properties([ $gradient ])
func _get_shader_code(uv, slot = 0):
var rv = { defs="", code="" }
var src = get_source()
if src == null:
return rv
var src_code = src.get_shader_code(uv)
if generated_variants.empty():
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()
generated_variants.append(uv)
rv.code = src_code.code+"vec4 %s_%d_rgba = %s_gradient(%s);\n" % [ name, variant_index, name, src_code.f ]
rv.rgba = "%s_%d_rgba" % [ name, variant_index ]
return rv
func _on_Control_updated(v):
parameters.gradient = v
update_shaders()

View File

@ -1,51 +0,0 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://addons/material_maker/nodes/colorize/colorize.gd" type="Script" id=1]
[ext_resource path="res://addons/material_maker/widgets/gradient_editor.tscn" type="PackedScene" id=2]
[sub_resource type="Theme" id=1]
[node name="Colorize" 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 = 4.0
margin_right = 133.0
margin_bottom = 72.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = SubResource( 1 )
title = "Colorize"
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.756863, 0.756863, 0.756863, 1 )
slot/0/right_enabled = true
slot/0/right_type = 0
slot/0/right_color = Color( 0, 1, 0, 0.502745 )
script = ExtResource( 1 )
_sections_unfolded = [ "Theme", "slot", "slot/0" ]
[node name="gradient" parent="." index="0" instance=ExtResource( 2 )]
margin_left = 16.0
margin_top = 24.0
margin_right = 136.0
margin_bottom = 54.0
[connection signal="updated" from="gradient" to="." method="_on_Control_updated"]

View File

@ -6,28 +6,13 @@
[ext_resource path="res://addons/material_maker/icons/save.png" type="Texture" id=4]
[node name="Custom" type="GraphNode"]
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 = 95.0
margin_bottom = 53.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 )
@ -37,99 +22,31 @@ slot/0/right_color = Color( 1, 1, 1, 1 )
script = ExtResource( 1 )
model = null
[node name="CustomNodeButtons" type="HBoxContainer" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="CustomNodeButtons" type="HBoxContainer" parent="."]
margin_left = 16.0
margin_top = 24.0
margin_right = 107.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
[node name="Edit" type="Button" parent="CustomNodeButtons"]
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="Load" type="Button" parent="CustomNodeButtons" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Load" type="Button" parent="CustomNodeButtons"]
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
[node name="Save" type="Button" parent="CustomNodeButtons" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Save" type="Button" parent="CustomNodeButtons"]
margin_left = 63.0
margin_right = 91.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( 4 )
flat = true
align = 1
[connection signal="pressed" from="CustomNodeButtons/Edit" to="." method="_on_Edit_pressed"]
[connection signal="pressed" from="CustomNodeButtons/Load" to="." method="_on_Load_pressed"]
[connection signal="pressed" from="CustomNodeButtons/Save" to="." method="_on_Save_pressed"]

View File

@ -31,6 +31,7 @@ func set_model(m):
print("set_model error "+str(m))
func update_node(data):
print("node_generic.update_node")
if typeof(data) != TYPE_DICTIONARY:
return
if !data.has("name"):
@ -85,6 +86,8 @@ func update_node(data):
control = CheckBox.new()
elif p.type == "color":
control = ColorPickerButton.new()
elif p.type == "gradient":
control = preload("res://addons/material_maker/widgets/gradient_editor.tscn").instance()
if control != null:
var label = p.name
control.name = label
@ -222,6 +225,8 @@ func subst(string, uv = ""):
value_string = p.values[value].value
elif p.type == "color":
value_string = "vec4(%.9f, %.9f, %.9f, %.9f)" % [ value.r, value.g, value.b, value.a ]
elif p.type == "gradient":
value_string = p.name+"_gradient_fct"
if value_string != null:
string = replace_variable(string, p.name, value_string)
if model_data.has("inputs") and typeof(model_data.inputs) == TYPE_ARRAY:
@ -240,8 +245,12 @@ func _get_shader_code(uv, slot = 0):
var variant_string = uv+","+str(slot)
if model_data != null and model_data.has("outputs") and model_data.outputs.size() > slot:
var output = model_data.outputs[slot]
rv.defs = ""
if model_data.has("instance") && generated_variants.empty():
rv.defs = subst(model_data.instance).string
rv.defs += subst(model_data.instance).string
for p in model_data.parameters:
if p.type == "gradient":
rv.defs += parameters[p.name].get_shader(p.name+"_gradient_fct")
var variant_index = generated_variants.find(variant_string)
if variant_index == -1:
variant_index = generated_variants.size()

View File

@ -3,5 +3,5 @@
name="MaterialMaker"
description="Procedural Material creation tool"
author="RodZilla"
version="0.5"
version="0.6"
script="plugin.gd"

View File

@ -4,11 +4,14 @@ extends EditorPlugin
var mm_button = null
var material_maker = null
var importer = null
var renderer = null
func _enter_tree():
add_tool_menu_item("Material Maker", self, "open_material_maker")
importer = preload("res://addons/material_maker/import_plugin/ptex_import.gd").new(self)
add_import_plugin(importer)
renderer = preload("res://addons/material_maker/engine/renderer.tscn").instance()
add_child(renderer)
func _exit_tree():
remove_tool_menu_item("Material Maker")
@ -48,4 +51,4 @@ func generate_material(ptex_filename: String) -> Material:
var generator = loader.load_gen(ptex_filename)
add_child(generator)
var material = generator.get_node("Material")
return material.generate_material()
return material.generate_material(renderer)

View File

@ -3,7 +3,6 @@
[ext_resource path="res://addons/material_maker/renderer.gd" type="Script" id=1]
[sub_resource type="Shader" id=1]
code = "shader_type canvas_item;
void fragment() {
@ -12,61 +11,24 @@ void fragment() {
"
[sub_resource type="ShaderMaterial" id=2]
render_priority = 0
shader = SubResource( 1 )
[node name="Renderer" type="Viewport" index="0"]
arvr = false
size = Vector2( 0, 0 )
[node name="Renderer" type="Viewport"]
own_world = true
world = null
transparent_bg = true
msaa = 2
hdr = false
disable_3d = false
usage = 2
debug_draw = 0
render_target_v_flip = true
render_target_clear_mode = 0
render_target_update_mode = 1
audio_listener_enable_2d = false
audio_listener_enable_3d = false
physics_object_picking = false
gui_disable_input = true
gui_snap_controls_to_pixels = true
shadow_atlas_size = 0
shadow_atlas_quad_0 = 2
shadow_atlas_quad_1 = 2
shadow_atlas_quad_2 = 3
shadow_atlas_quad_3 = 4
script = ExtResource( 1 )
_sections_unfolded = [ "GUI", "Render Target", "Rendering" ]
[node name="ColorRect" type="ColorRect" parent="." index="0"]
debug_path = null
[node name="ColorRect" type="ColorRect" parent="."]
material = SubResource( 2 )
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 40.0
margin_bottom = 40.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
color = Color( 1, 1, 1, 1 )
_sections_unfolded = [ "Material", "Rect" ]
[node name="Timer" type="Timer" parent="." index="1"]
process_mode = 1
[node name="Timer" type="Timer" parent="."]
wait_time = 0.1
one_shot = true
autostart = false

View File

@ -1,4 +1,5 @@
extends Object
class_name MMGradient
class CustomSorter:
static func compare(a, b):
@ -10,6 +11,12 @@ var sorted = true
func _ready():
pass
func to_string():
var rv = PoolStringArray()
for p in points:
rv.append("("+str(p.v)+","+str(p.c)+")")
return rv.join(",")
func duplicate():
var copy = get_script().new()
copy.clear()

View File

@ -43,13 +43,11 @@ class GradientCursor:
var value = null setget set_value
const Gradient = preload("res://addons/material_maker/types/gradient.gd")
signal updated
signal updated(value)
func _ready():
$Gradient.material = $Gradient.material.duplicate(true)
set_value(Gradient.new())
set_value(MMGradient.new())
func set_value(v):
value = v
@ -58,6 +56,7 @@ func set_value(v):
remove_child(c)
c.free()
for p in value.points:
print(p)
add_cursor(p.v*(rect_size.x-GradientCursor.WIDTH), p.c)
update_shader()

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=2]
[gd_scene load_steps=9 format=2]
[ext_resource path="res://addons/material_maker/widgets/node_editor/parameter.gd" type="Script" id=1]
[ext_resource path="res://addons/material_maker/icons/minus.png" type="Texture" id=2]
@ -7,172 +7,72 @@
[ext_resource path="res://addons/material_maker/widgets/node_editor/parameter_enum.tscn" type="PackedScene" id=5]
[ext_resource path="res://addons/material_maker/widgets/node_editor/parameter_boolean.tscn" type="PackedScene" id=6]
[ext_resource path="res://addons/material_maker/widgets/node_editor/parameter_color.tscn" type="PackedScene" id=7]
[ext_resource path="res://addons/material_maker/widgets/node_editor/parameter_gradient.tscn" type="PackedScene" id=8]
[node name="Parameter" type="HBoxContainer" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Parameter" type="HBoxContainer"]
margin_right = 201.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 = 1
size_flags_vertical = 1
alignment = 0
script = ExtResource( 1 )
[node name="Delete" type="Button" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Delete" type="Button" parent="."]
margin_right = 28.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 = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
margin_bottom = 30.0
icon = ExtResource( 2 )
flat = true
align = 1
[node name="Name" type="LineEdit" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Name" type="LineEdit" parent="."]
margin_left = 32.0
margin_right = 102.0
margin_bottom = 24.0
margin_bottom = 30.0
rect_min_size = Vector2( 70, 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 = "name"
focus_mode = 2
context_menu_enabled = true
placeholder_alpha = 0.6
caret_blink = false
caret_blink_speed = 0.65
caret_position = 0
_sections_unfolded = [ "Rect" ]
[node name="Label" type="LineEdit" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Label" type="LineEdit" parent="."]
margin_left = 106.0
margin_right = 176.0
margin_bottom = 24.0
margin_bottom = 30.0
rect_min_size = Vector2( 70, 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 = "Label"
focus_mode = 2
context_menu_enabled = true
placeholder_alpha = 0.6
caret_blink = false
caret_blink_speed = 0.65
caret_position = 0
_sections_unfolded = [ "Rect" ]
[node name="Type" type="OptionButton" parent="." index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Type" type="OptionButton" parent="."]
margin_left = 180.0
margin_right = 247.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 = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
action_mode = 0
enabled_focus_mode = 2
shortcut = null
group = null
margin_right = 249.0
margin_bottom = 30.0
text = "float"
flat = false
align = 0
items = [ "float", null, false, -1, null, "size", null, false, -1, null, "enum", null, false, -1, null, "boolean", null, false, -1, null ]
items = [ "float", null, false, -1, null, "size", null, false, -1, null, "enum", null, false, -1, null, "boolean", null, false, -1, null, "color", null, false, -1, null ]
selected = 0
[node name="Types" type="HBoxContainer" parent="." index="4"]
[node name="Types" type="HBoxContainer" parent="."]
margin_left = 253.0
margin_right = 800.0
margin_bottom = 30.0
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 251.0
margin_right = 251.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 = 1
size_flags_vertical = 1
alignment = 0
[node name="float" parent="Types" index="0" instance=ExtResource( 3 )]
visible = false
[node name="size" parent="Types" index="1" instance=ExtResource( 4 )]
[node name="float" parent="Types" instance=ExtResource( 3 )]
margin_bottom = 30.0
[node name="size" parent="Types" instance=ExtResource( 4 )]
visible = false
margin_left = 551.0
margin_right = 796.0
[node name="enum" parent="Types" index="2" instance=ExtResource( 5 )]
[node name="enum" parent="Types" instance=ExtResource( 5 )]
visible = false
margin_left = 800.0
margin_right = 839.0
[node name="boolean" parent="Types" index="3" instance=ExtResource( 6 )]
[node name="boolean" parent="Types" instance=ExtResource( 6 )]
margin_left = 843.0
margin_right = 917.0
[node name="color" parent="Types" index="4" instance=ExtResource( 7 )]
[node name="color" parent="Types" instance=ExtResource( 7 )]
visible = false
margin_left = 551.0
margin_right = 563.0
[node name="gradient" parent="Types" instance=ExtResource( 8 )]
visible = false
margin_left = 551.0
margin_right = 725.0
margin_bottom = 30.0
[connection signal="pressed" from="Delete" to="." method="_on_Delete_pressed"]
[connection signal="item_selected" from="Type" to="." method="_on_Type_item_selected"]

View File

@ -21,7 +21,10 @@ func get_model_data():
func set_model_data(data):
enum_values = data.values.duplicate()
if data.has("default"):
enum_current = data.default
else:
enum_current = 0
update_enum_list()
func update_enum_list():

View File

@ -0,0 +1,18 @@
tool
extends HBoxContainer
onready var default = $Default
func _ready():
pass
func get_model_data():
var data = {}
data.default = default.value.serialize()
return data
func set_model_data(data):
if data.has("default"):
var v = MMGradient.new()
v.deserialize(data.default)
default.value = v

View File

@ -0,0 +1,19 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/material_maker/widgets/node_editor/parameter_gradient.gd" type="Script" id=1]
[ext_resource path="res://addons/material_maker/widgets/gradient_editor.tscn" type="PackedScene" id=2]
[node name="gradient" type="HBoxContainer"]
margin_right = 148.0
margin_bottom = 24.0
script = ExtResource( 1 )
[node name="LabelDefault" type="Label" parent="."]
margin_top = 8.0
margin_right = 50.0
margin_bottom = 22.0
text = "Default:"
[node name="Default" parent="." instance=ExtResource( 2 )]
margin_left = 54.0
margin_right = 174.0

View File

@ -39,10 +39,20 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://addons/material_maker/engine/gen_material.gd"
}, {
"base": "Viewport",
"class": "MMGenRenderer",
"language": "GDScript",
"path": "res://addons/material_maker/engine/renderer.gd"
}, {
"base": "MMGenBase",
"class": "MMGenShader",
"language": "GDScript",
"path": "res://addons/material_maker/engine/gen_shader.gd"
}, {
"base": "Object",
"class": "MMGradient",
"language": "GDScript",
"path": "res://addons/material_maker/types/gradient.gd"
} ]
_global_script_class_icons={
"MMGenBase": "",
@ -51,7 +61,9 @@ _global_script_class_icons={
"MMGenGraph": "",
"MMGenLoader": "",
"MMGenMaterial": "",
"MMGenShader": ""
"MMGenRenderer": "",
"MMGenShader": "",
"MMGradient": ""
}
[application]