mirror of
https://github.com/Relintai/material-maker.git
synced 2025-02-07 01:25:55 +01:00
Prepared function generation for inputs
This commit is contained in:
parent
8282ab24fe
commit
2a51e3b726
@ -4,10 +4,19 @@ class_name MMGenContext
|
|||||||
|
|
||||||
|
|
||||||
var variants : Dictionary = {}
|
var variants : Dictionary = {}
|
||||||
|
var parent_context : MMGenContext = null
|
||||||
|
|
||||||
|
func _init(p = null) -> void:
|
||||||
|
parent_context = p
|
||||||
|
|
||||||
func has_variant(generator) -> bool:
|
func has_variant(generator) -> bool:
|
||||||
return variants.has(generator)
|
return variants.has(generator) or parent_context != null and parent_context.has_variant(generator)
|
||||||
|
|
||||||
|
func touch_variant(generator) -> void:
|
||||||
|
if !variants.has(generator):
|
||||||
|
variants[generator] = []
|
||||||
|
if parent_context != null:
|
||||||
|
parent_context.touch_variant(generator)
|
||||||
|
|
||||||
func get_variant(generator, variant) -> int:
|
func get_variant(generator, variant) -> int:
|
||||||
var rv = -1
|
var rv = -1
|
||||||
@ -17,4 +26,5 @@ func get_variant(generator, variant) -> int:
|
|||||||
variants[generator].push_back(variant)
|
variants[generator].push_back(variant)
|
||||||
else:
|
else:
|
||||||
variants[generator] = [variant]
|
variants[generator] = [variant]
|
||||||
|
touch_variant(generator)
|
||||||
return rv
|
return rv
|
||||||
|
@ -7,6 +7,13 @@ var uses_seed = false
|
|||||||
|
|
||||||
var editable = false
|
var editable = false
|
||||||
|
|
||||||
|
const PORT_TYPES : Dictionary = {
|
||||||
|
rgba = { type="vec4" },
|
||||||
|
rgb = { type="vec3" },
|
||||||
|
f = { type="float" }
|
||||||
|
}
|
||||||
|
const GENERATE_FUNCTIONS : bool = false
|
||||||
|
|
||||||
func toggle_editable() -> bool:
|
func toggle_editable() -> bool:
|
||||||
editable = !editable
|
editable = !editable
|
||||||
if editable:
|
if editable:
|
||||||
@ -90,7 +97,19 @@ func find_keyword_call(string, keyword):
|
|||||||
parenthesis_level -= 1
|
parenthesis_level -= 1
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
func replace_input(string, context, input, type, src, default) -> Dictionary:
|
func replace_input_with_function_call(string : String, input : String) -> String:
|
||||||
|
var genname = "o"+str(get_instance_id())
|
||||||
|
while true:
|
||||||
|
var uv = find_keyword_call(string, input)
|
||||||
|
if uv == null:
|
||||||
|
break
|
||||||
|
elif uv == "":
|
||||||
|
print("syntax error")
|
||||||
|
break
|
||||||
|
string = string.replace("$%s(%s)" % [ input, uv ], "%s_input_%s(%s)" % [ genname, input, uv ])
|
||||||
|
return string
|
||||||
|
|
||||||
|
func replace_input(string : String, context, input : String, type : String, src : OutputPort, default : String) -> Dictionary:
|
||||||
var required_globals = []
|
var required_globals = []
|
||||||
var required_defs = ""
|
var required_defs = ""
|
||||||
var required_code = ""
|
var required_code = ""
|
||||||
@ -134,7 +153,7 @@ func replace_input(string, context, input, type, src, default) -> Dictionary:
|
|||||||
func is_word_letter(l) -> bool:
|
func is_word_letter(l) -> bool:
|
||||||
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1
|
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1
|
||||||
|
|
||||||
func replace_variable(string, variable, value) -> String:
|
func replace_variable(string : String, variable : String, value : String) -> String:
|
||||||
string = string.replace("$(%s)" % variable, value)
|
string = string.replace("$(%s)" % variable, value)
|
||||||
var keyword_size = variable.length()+1
|
var keyword_size = variable.length()+1
|
||||||
var new_string = ""
|
var new_string = ""
|
||||||
@ -152,7 +171,7 @@ func replace_variable(string, variable, value) -> String:
|
|||||||
string = string.right(keyword_size)
|
string = string.right(keyword_size)
|
||||||
return new_string
|
return new_string
|
||||||
|
|
||||||
func subst(string, context, uv = "") -> Dictionary:
|
func subst(string : String, context : MMGenContext, uv : String = "") -> Dictionary:
|
||||||
var genname = "o"+str(get_instance_id())
|
var genname = "o"+str(get_instance_id())
|
||||||
var required_globals = []
|
var required_globals = []
|
||||||
var required_defs = ""
|
var required_defs = ""
|
||||||
@ -199,30 +218,36 @@ func subst(string, context, uv = "") -> Dictionary:
|
|||||||
for i in range(shader_model.inputs.size()):
|
for i in range(shader_model.inputs.size()):
|
||||||
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)
|
if GENERATE_FUNCTIONS:
|
||||||
while result is GDScriptFunctionState:
|
string = replace_input_with_function_call(string, input.name)
|
||||||
result = yield(result, "completed")
|
else:
|
||||||
if string != result.string:
|
var result = replace_input(string, context, input.name, input.type, source, input.default)
|
||||||
changed = true
|
while result is GDScriptFunctionState:
|
||||||
if result.new_pass_required:
|
result = yield(result, "completed")
|
||||||
new_pass_required = true
|
if string != result.string:
|
||||||
string = result.string
|
changed = true
|
||||||
# Add global definitions
|
if result.new_pass_required:
|
||||||
for d in result.globals:
|
new_pass_required = true
|
||||||
if required_globals.find(d) == -1:
|
string = result.string
|
||||||
required_globals.push_back(d)
|
# Add global definitions
|
||||||
# Add generated definitions
|
for d in result.globals:
|
||||||
required_defs += result.defs
|
if required_globals.find(d) == -1:
|
||||||
# Add generated code
|
required_globals.push_back(d)
|
||||||
required_code += result.code
|
# Add generated definitions
|
||||||
for t in result.textures.keys():
|
required_defs += result.defs
|
||||||
required_textures[t] = result.textures[t]
|
# Add generated code
|
||||||
|
required_code += result.code
|
||||||
|
for t in result.textures.keys():
|
||||||
|
required_textures[t] = result.textures[t]
|
||||||
cont = changed and new_pass_required
|
cont = changed and new_pass_required
|
||||||
return { string=string, globals=required_globals, defs=required_defs, code=required_code, textures=required_textures }
|
return { string=string, globals=required_globals, defs=required_defs, code=required_code, textures=required_textures }
|
||||||
|
|
||||||
|
func create_input_function(function_name : String, input_index : int, context : MMGenContext) -> Dictionary:
|
||||||
|
var rv = { globals=[], defs="", code="", textures={} }
|
||||||
|
return rv
|
||||||
|
|
||||||
func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
|
func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
|
||||||
var genname = "o"+str(get_instance_id())
|
var genname = "o"+str(get_instance_id())
|
||||||
var output_info = [ { field="rgba", type="vec4" }, { field="rgb", type="vec3" }, { field="f", type="float" } ]
|
|
||||||
var rv = { globals=[], defs="", code="", textures={} }
|
var rv = { globals=[], defs="", code="", textures={} }
|
||||||
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]
|
||||||
@ -231,8 +256,10 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
|||||||
while subst_output is GDScriptFunctionState:
|
while subst_output is GDScriptFunctionState:
|
||||||
subst_output = yield(subst_output, "completed")
|
subst_output = yield(subst_output, "completed")
|
||||||
rv.defs += subst_output.string
|
rv.defs += subst_output.string
|
||||||
|
# process textures
|
||||||
for t in subst_output.textures.keys():
|
for t in subst_output.textures.keys():
|
||||||
rv.textures[t] = subst_output.textures[t]
|
rv.textures[t] = subst_output.textures[t]
|
||||||
|
# Generate functions for gradients
|
||||||
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]
|
||||||
@ -240,6 +267,29 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
|||||||
g = MMGradient.new()
|
g = MMGradient.new()
|
||||||
g.deserialize(parameters[p.name])
|
g.deserialize(parameters[p.name])
|
||||||
rv.defs += g.get_shader(genname+"_p_"+p.name+"_gradient_fct")
|
rv.defs += g.get_shader(genname+"_p_"+p.name+"_gradient_fct")
|
||||||
|
# Generate functions for inputs
|
||||||
|
if shader_model.has("inputs"):
|
||||||
|
for i in range(shader_model.inputs.size()):
|
||||||
|
if GENERATE_FUNCTIONS:
|
||||||
|
var input = shader_model.inputs[i]
|
||||||
|
var source = get_source(i)
|
||||||
|
var string = "$%s(uv)" % input.name
|
||||||
|
var local_context = MMGenContext.new(context)
|
||||||
|
var result = replace_input(string, local_context, input.name, input.type, source, input.default)
|
||||||
|
while result is GDScriptFunctionState:
|
||||||
|
result = yield(result, "completed")
|
||||||
|
# Add global definitions
|
||||||
|
for d in result.globals:
|
||||||
|
if rv.globals.find(d) == -1:
|
||||||
|
rv.globals.push_back(d)
|
||||||
|
# Add generated definitions
|
||||||
|
rv.defs += result.defs
|
||||||
|
# Add textures
|
||||||
|
for t in result.textures.keys():
|
||||||
|
rv.textures[t] = result.textures[t]
|
||||||
|
rv.defs += "%s %s_input_%s(vec2 uv) {\n" % [ PORT_TYPES[input.type].type, genname, input.name ]
|
||||||
|
rv.defs += "%s\n" % result.code
|
||||||
|
rv.defs += "return %s;\n}\n" % result.string
|
||||||
# Add inline code
|
# Add inline code
|
||||||
if shader_model.has("code"):
|
if shader_model.has("code"):
|
||||||
var variant_index = context.get_variant(self, uv)
|
var variant_index = context.get_variant(self, uv)
|
||||||
@ -262,9 +312,9 @@ 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)
|
||||||
for t in output_info:
|
for f in PORT_TYPES.keys():
|
||||||
if output.has(t.field):
|
if output.has(f):
|
||||||
var subst_output = subst(output[t.field], context, uv)
|
var subst_output = subst(output[f], context, uv)
|
||||||
while subst_output is GDScriptFunctionState:
|
while subst_output is GDScriptFunctionState:
|
||||||
subst_output = yield(subst_output, "completed")
|
subst_output = yield(subst_output, "completed")
|
||||||
# Add global definitions
|
# Add global definitions
|
||||||
@ -275,12 +325,12 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
|||||||
rv.defs += subst_output.defs
|
rv.defs += subst_output.defs
|
||||||
# Add generated code
|
# Add generated code
|
||||||
rv.code += subst_output.code
|
rv.code += subst_output.code
|
||||||
rv.code += "%s %s_%d_%d_%s = %s;\n" % [ t.type, genname, output_index, variant_index, t.field, subst_output.string ]
|
rv.code += "%s %s_%d_%d_%s = %s;\n" % [ PORT_TYPES[f].type, genname, output_index, variant_index, f, subst_output.string ]
|
||||||
for t in subst_output.textures.keys():
|
for t in subst_output.textures.keys():
|
||||||
rv.textures[t] = subst_output.textures[t]
|
rv.textures[t] = subst_output.textures[t]
|
||||||
for t in output_info:
|
for f in PORT_TYPES.keys():
|
||||||
if output.has(t.field):
|
if output.has(f):
|
||||||
rv[t.field] = "%s_%d_%d_%s" % [ genname, output_index, variant_index, t.field ]
|
rv[f] = "%s_%d_%d_%s" % [ genname, output_index, variant_index, f ]
|
||||||
if shader_model.has("global") && rv.globals.find(shader_model.global) == -1:
|
if shader_model.has("global") && rv.globals.find(shader_model.global) == -1:
|
||||||
rv.globals.push_back(shader_model.global)
|
rv.globals.push_back(shader_model.global)
|
||||||
return rv
|
return rv
|
||||||
|
Loading…
Reference in New Issue
Block a user