mirror of
https://github.com/Relintai/material-maker.git
synced 2024-11-13 06:27:18 +01:00
More refactoring and added buffer generator
This commit is contained in:
parent
e9a21454c1
commit
d8d9aaa9b4
@ -9,16 +9,7 @@ class OutputPort:
|
||||
func _init(g : MMGenBase, o : int):
|
||||
generator = g
|
||||
output_index = o
|
||||
"""
|
||||
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()
|
||||
"""
|
||||
func to_str():
|
||||
return generator.name+"("+str(output_index)+")"
|
||||
|
||||
@ -81,16 +72,20 @@ func get_globals():
|
||||
func render(output_index : int, renderer : MMGenRenderer, size : int):
|
||||
var context : MMGenContext = MMGenContext.new(renderer)
|
||||
var source = get_shader_code("UV", output_index, context)
|
||||
while source is GDScriptFunctionState:
|
||||
source = yield(source, "completed")
|
||||
if source == null:
|
||||
return false
|
||||
var shader : String = renderer.generate_shader(source)
|
||||
var status = renderer.render_shader(shader, {}, 1024)
|
||||
var status = renderer.render_shader(shader, source.textures, size)
|
||||
while status is GDScriptFunctionState:
|
||||
status = yield(status, "completed")
|
||||
return status
|
||||
|
||||
func get_shader_code(uv : String, output_index : int, context : MMGenContext):
|
||||
var rv = _get_shader_code(uv, output_index, context)
|
||||
while rv is GDScriptFunctionState:
|
||||
rv = yield(rv, "completed")
|
||||
if rv != null:
|
||||
if !rv.has("f"):
|
||||
if rv.has("rgb"):
|
||||
|
@ -2,6 +2,8 @@ tool
|
||||
extends MMGenBase
|
||||
class_name MMGenBuffer
|
||||
|
||||
var texture : ImageTexture = ImageTexture.new()
|
||||
|
||||
func _ready():
|
||||
if !parameters.has("size"):
|
||||
parameters.size = 4
|
||||
@ -16,7 +18,28 @@ func get_parameter_defs():
|
||||
return [ { name="size", type="size", first=4, last=11, default=4 } ]
|
||||
|
||||
func get_input_defs():
|
||||
return [ ]
|
||||
return [ { name="in", type="rgba" } ]
|
||||
|
||||
func get_output_defs():
|
||||
return [ ]
|
||||
return [ { rgba="" } ]
|
||||
|
||||
func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
|
||||
var source = get_source(0)
|
||||
if source != null:
|
||||
print(parameters.size)
|
||||
var status = source.generator.render(source.output_index, context.renderer, pow(2, 4+parameters.size))
|
||||
while status is GDScriptFunctionState:
|
||||
status = yield(status, "completed")
|
||||
if status:
|
||||
var image : Image = context.renderer.get_texture().get_data()
|
||||
texture.create_from_image(image)
|
||||
texture.flags = 0
|
||||
var rv = { defs="" }
|
||||
var variant_index = context.get_variant(self, uv)
|
||||
if variant_index == -1:
|
||||
variant_index = context.get_variant(self, uv)
|
||||
var texture_name = name+"_tex"
|
||||
rv.code = "vec4 %s_%d = texture(%s, %s);\n" % [ name, variant_index, texture_name, uv ]
|
||||
rv.rgba = "%s_%d" % [ name, variant_index ]
|
||||
rv.textures = { texture_name:texture }
|
||||
return rv
|
@ -39,8 +39,7 @@ func _ready():
|
||||
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)
|
||||
var status = source.generator.render(source.output_index, renderer, 512)
|
||||
while status is GDScriptFunctionState:
|
||||
status = yield(status, "completed")
|
||||
print("Render status: "+str(status))
|
||||
|
@ -3,7 +3,6 @@ extends MMGenBase
|
||||
class_name MMGenShader
|
||||
|
||||
var shader_model : Dictionary = {}
|
||||
var generated_variants = []
|
||||
|
||||
func get_type():
|
||||
return "shader"
|
||||
@ -19,6 +18,18 @@ func get_parameter_defs():
|
||||
else:
|
||||
return shader_model.parameters
|
||||
|
||||
func get_input_defs():
|
||||
if shader_model == null or !shader_model.has("inputs"):
|
||||
return []
|
||||
else:
|
||||
return shader_model.inputs
|
||||
|
||||
func get_output_defs():
|
||||
if shader_model == null or !shader_model.has("outputs"):
|
||||
return []
|
||||
else:
|
||||
return shader_model.outputs
|
||||
|
||||
func set_shader_model(data: Dictionary):
|
||||
shader_model = data
|
||||
init_parameters()
|
||||
@ -43,6 +54,7 @@ func find_keyword_call(string, keyword):
|
||||
func replace_input(string, context, input, type, src, default):
|
||||
var required_defs = ""
|
||||
var required_code = ""
|
||||
var required_textures = {}
|
||||
while true:
|
||||
var uv = find_keyword_call(string, input)
|
||||
if uv == null:
|
||||
@ -52,15 +64,17 @@ func replace_input(string, context, input, type, src, default):
|
||||
break
|
||||
var src_code
|
||||
if src == null:
|
||||
src_code = subst(default, "(%s)" % uv)
|
||||
src_code = subst(default, context, "(%s)" % uv)
|
||||
else:
|
||||
print(src.to_str())
|
||||
src_code = src.generator.get_shader_code(uv, src.output_index, context)
|
||||
while src_code is GDScriptFunctionState:
|
||||
src_code = yield(src_code, "completed")
|
||||
src_code.string = src_code[type]
|
||||
required_defs += src_code.defs
|
||||
required_code += src_code.code
|
||||
required_textures = src_code.textures
|
||||
string = string.replace("$%s(%s)" % [ input, uv ], src_code.string)
|
||||
return { string=string, defs=required_defs, code=required_code }
|
||||
return { string=string, defs=required_defs, code=required_code, textures=required_textures }
|
||||
|
||||
func is_word_letter(l):
|
||||
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1
|
||||
@ -86,6 +100,7 @@ func replace_variable(string, variable, value):
|
||||
func subst(string, context, uv = ""):
|
||||
var required_defs = ""
|
||||
var required_code = ""
|
||||
var required_textures = {}
|
||||
string = replace_variable(string, "name", name)
|
||||
string = replace_variable(string, "seed", str(get_seed()))
|
||||
if uv != "":
|
||||
@ -113,20 +128,29 @@ func subst(string, context, uv = ""):
|
||||
var input = shader_model.inputs[i]
|
||||
var source = get_source(i)
|
||||
var result = replace_input(string, context, input.name, input.type, source, input.default)
|
||||
while result is GDScriptFunctionState:
|
||||
result = yield(result, "completed")
|
||||
string = result.string
|
||||
required_defs += result.defs
|
||||
required_code += result.code
|
||||
return { string=string, defs=required_defs, code=required_code }
|
||||
for t in result.textures.keys():
|
||||
required_textures[t] = result.textures[t]
|
||||
return { string=string, defs=required_defs, code=required_code, textures=required_textures }
|
||||
|
||||
func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
|
||||
var output_info = [ { field="rgba", type="vec4" }, { field="rgb", type="vec3" }, { field="f", type="float" } ]
|
||||
var rv = { defs="", code="" }
|
||||
var rv = { defs="", code="", textures={} }
|
||||
var variant_string = uv+","+str(output_index)
|
||||
if shader_model != null and shader_model.has("outputs") and shader_model.outputs.size() > output_index:
|
||||
var output = shader_model.outputs[output_index]
|
||||
rv.defs = ""
|
||||
if shader_model.has("instance") && !context.has_variant(self):
|
||||
rv.defs += subst(shader_model.instance, context).string
|
||||
var subst_output = subst(shader_model.instance, context, uv)
|
||||
while subst_output is GDScriptFunctionState:
|
||||
subst_output = yield(subst_output, "completed")
|
||||
rv.defs += subst_output.string
|
||||
for t in subst_output.textures.keys():
|
||||
rv.textures[t] = subst_output.textures[t]
|
||||
for p in shader_model.parameters:
|
||||
if p.type == "gradient":
|
||||
var g = parameters[p.name]
|
||||
@ -137,13 +161,16 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
|
||||
var variant_index = context.get_variant(self, variant_string)
|
||||
if variant_index == -1:
|
||||
variant_index = context.get_variant(self, variant_string)
|
||||
generated_variants.append(variant_string)
|
||||
for t in output_info:
|
||||
if output.has(t.field):
|
||||
var subst_output = subst(output[t.field], context, uv)
|
||||
while subst_output is GDScriptFunctionState:
|
||||
subst_output = yield(subst_output, "completed")
|
||||
rv.defs += subst_output.defs
|
||||
rv.code += subst_output.code
|
||||
rv.code += "%s %s_%d_%d_%s = %s;\n" % [ t.type, name, output_index, variant_index, t.field, subst_output.string ]
|
||||
for t in subst_output.textures.keys():
|
||||
rv.textures[t] = subst_output.textures[t]
|
||||
for t in output_info:
|
||||
if output.has(t.field):
|
||||
rv[t.field] = "%s_%d_%d_%s" % [ name, output_index, variant_index, t.field ]
|
||||
|
@ -18,6 +18,9 @@ static func generate_shader(src_code):
|
||||
file.open("res://addons/material_maker/common.shader", File.READ)
|
||||
code += file.get_as_text()
|
||||
code += "\n"
|
||||
if src_code.has("textures"):
|
||||
for t in src_code.textures.keys():
|
||||
code += "uniform sampler2D "+t+";\n"
|
||||
if src_code.has("globals"):
|
||||
for g in src_code.globals:
|
||||
code += g
|
||||
@ -84,7 +87,7 @@ func render_shader(shader, textures, render_size):
|
||||
shader_material.shader.code = shader
|
||||
if textures != null:
|
||||
for k in textures.keys():
|
||||
shader_material.set_shader_param(k+"_tex", textures[k])
|
||||
shader_material.set_shader_param(k, textures[k])
|
||||
render_target_update_mode = Viewport.UPDATE_ONCE
|
||||
update_worlds()
|
||||
yield(get_tree(), "idle_frame")
|
||||
|
@ -1 +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"}]}
|
||||
{"global":"","inputs":[{"default":"$uv.x","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"}]}
|
@ -86,13 +86,11 @@ func update_node(data):
|
||||
if data.has("instance") and data.instance.find("$(seed)"):
|
||||
uses_seed = true
|
||||
# Parameters
|
||||
print("Parameters")
|
||||
controls = []
|
||||
var sizer = null
|
||||
for p in generator.get_parameter_defs():
|
||||
if !p.has("name") or !p.has("type"):
|
||||
continue
|
||||
print(p.name)
|
||||
var control = null
|
||||
if p.type == "float":
|
||||
if p.has("widget") and p.widget == "spinbox":
|
||||
@ -141,35 +139,39 @@ func update_node(data):
|
||||
control.size_flags_horizontal = SIZE_EXPAND | SIZE_FILL
|
||||
sizer.add_child(control)
|
||||
initialize_properties()
|
||||
if data.has("inputs") and typeof(data.inputs) == TYPE_ARRAY:
|
||||
for i in range(data.inputs.size()):
|
||||
var input = data.inputs[i]
|
||||
var enable_left = false
|
||||
var color_left = Color(0.5, 0.5, 0.5)
|
||||
if typeof(input) == TYPE_DICTIONARY:
|
||||
if input.type == "rgb":
|
||||
enable_left = true
|
||||
color_left = Color(0.5, 0.5, 1.0)
|
||||
elif input.type == "rgba":
|
||||
enable_left = true
|
||||
color_left = Color(0.0, 0.5, 0.0, 0.5)
|
||||
else:
|
||||
enable_left = true
|
||||
set_slot(i, enable_left, 0, color_left, false, 0, Color())
|
||||
if data.has("outputs") and typeof(data.outputs) == TYPE_ARRAY:
|
||||
for i in range(data.outputs.size()):
|
||||
var output = 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("rgba"):
|
||||
enable_right = true
|
||||
color_right = Color(0.0, 0.5, 0.0, 0.5)
|
||||
elif output.has("f"):
|
||||
enable_right = true
|
||||
set_slot(i, is_slot_enabled_left(i), get_slot_type_left(i), get_slot_color_left(i), enable_right, 0, color_right)
|
||||
# Inputs
|
||||
var inputs = generator.get_input_defs()
|
||||
for i in range(inputs.size()):
|
||||
var input = inputs[i]
|
||||
print(input)
|
||||
var enable_left = false
|
||||
var color_left = Color(0.5, 0.5, 0.5)
|
||||
if typeof(input) == TYPE_DICTIONARY:
|
||||
if input.type == "rgb":
|
||||
enable_left = true
|
||||
color_left = Color(0.5, 0.5, 1.0)
|
||||
elif input.type == "rgba":
|
||||
enable_left = true
|
||||
color_left = Color(0.0, 0.5, 0.0, 0.5)
|
||||
else:
|
||||
enable_left = true
|
||||
set_slot(i, enable_left, 0, color_left, false, 0, Color())
|
||||
# Outputs
|
||||
var outputs = generator.get_output_defs()
|
||||
for i in range(outputs.size()):
|
||||
var output = outputs[i]
|
||||
print(output)
|
||||
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("rgba"):
|
||||
enable_right = true
|
||||
color_right = Color(0.0, 0.5, 0.0, 0.5)
|
||||
elif output.has("f"):
|
||||
enable_right = true
|
||||
set_slot(i, is_slot_enabled_left(i), get_slot_type_left(i), get_slot_color_left(i), enable_right, 0, color_right)
|
||||
if custom_node_buttons != null:
|
||||
move_child(custom_node_buttons, get_child_count()-1)
|
||||
|
Loading…
Reference in New Issue
Block a user