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