Merge pull request #86 from RodZill4/dev-generic
Generic node slots, 2D preview in graphview, 3D textures and splatter nodes
Before Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 5.2 KiB |
@ -37,17 +37,6 @@ var parameters = {}
|
||||
var seed_locked : bool = false
|
||||
var seed_value : int = 0
|
||||
|
||||
const PORT_TYPE_NAMES : Array = [ "f", "rgb", "rgba", "sdf2d", "sdf3d" ]
|
||||
|
||||
const PORT_TYPES : Dictionary = {
|
||||
f = { type="float", paramdefs="vec2 uv", params="uv", slot_type=0, color=Color(0.5, 0.5, 0.5) },
|
||||
rgb = { type="vec3", paramdefs="vec2 uv", params="uv", slot_type=0, color=Color(0.5, 0.5, 1.0) },
|
||||
rgba = { type="vec4", paramdefs="vec2 uv", params="uv", slot_type=0, color=Color(0.0, 0.5, 0.0, 0.5) },
|
||||
sdf2d = { type="float", paramdefs="vec2 uv", params="uv", slot_type=1, color=Color(1.0, 0.5, 0.0) },
|
||||
sdf3d = { type="float", paramdefs="vec3 p", params="p", slot_type=2, color=Color(1.0, 0.0, 0.0) },
|
||||
any = { slot_type=42, color=Color(1.0, 1.0, 1.0) }
|
||||
}
|
||||
|
||||
func _ready() -> void:
|
||||
init_parameters()
|
||||
|
||||
@ -150,7 +139,7 @@ func get_targets(output_index : int) -> Array:
|
||||
return []
|
||||
|
||||
# get the list of outputs that depend on the input whose index is passed as parameter
|
||||
func follow_input(input_index : int) -> Array:
|
||||
func follow_input(_input_index : int) -> Array:
|
||||
var rv = []
|
||||
for i in range(get_output_defs().size()):
|
||||
rv.push_back(OutputPort.new(self, i))
|
||||
@ -165,6 +154,31 @@ func get_input_shader(input_index : int) -> Dictionary:
|
||||
func get_shader(output_index : int, context) -> Dictionary:
|
||||
return get_shader_code("UV", output_index, context)
|
||||
|
||||
func generate_preview_shader(src_code, type) -> String:
|
||||
var code
|
||||
code = "shader_type canvas_item;\n"
|
||||
code += "render_mode blend_disabled;\n"
|
||||
code += "uniform float preview_size = 64;\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("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
|
||||
var shader_code = src_code.defs
|
||||
if src_code.has(type):
|
||||
var preview_code : String = mm_io_types.types[type].preview
|
||||
preview_code = preview_code.replace("$(code)", src_code.code)
|
||||
preview_code = preview_code.replace("$(value)", src_code[type])
|
||||
shader_code += preview_code
|
||||
#print("GENERATED SHADER:\n"+shader_code)
|
||||
code += shader_code
|
||||
return code
|
||||
|
||||
func render(output_index : int, size : int, preview : bool = false) -> Object:
|
||||
var context : MMGenContext = MMGenContext.new()
|
||||
var source = get_shader_code("uv", output_index, context)
|
||||
@ -174,7 +188,11 @@ func render(output_index : int, size : int, preview : bool = false) -> Object:
|
||||
source = { defs="", code="", textures={}, rgba="vec4(0.0)" }
|
||||
var shader : String
|
||||
if preview:
|
||||
shader = mm_renderer.generate_preview_shader(source)
|
||||
var output_type = "rgba"
|
||||
var outputs = get_output_defs()
|
||||
if outputs.size() > output_index:
|
||||
output_type = outputs[output_index].type
|
||||
shader = generate_preview_shader(source, output_type)
|
||||
else:
|
||||
shader = mm_renderer.generate_shader(source)
|
||||
var result = mm_renderer.render_shader(shader, source.textures, size)
|
||||
@ -186,20 +204,15 @@ 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.empty():
|
||||
if !rv.has("f"):
|
||||
if rv.has("rgb"):
|
||||
rv.f = "(dot("+rv.rgb+", vec3(1.0))/3.0)"
|
||||
elif rv.has("rgba"):
|
||||
rv.f = "(dot("+rv.rgba+".rgb, vec3(1.0))/3.0)"
|
||||
if !rv.has("rgb"):
|
||||
if rv.has("rgba"):
|
||||
rv.rgb = rv.rgba+".rgb"
|
||||
elif rv.has("f"):
|
||||
rv.rgb = "vec3("+rv.f+")"
|
||||
if !rv.has("rgba"):
|
||||
if rv.has("rgb"):
|
||||
rv.rgba = "vec4("+rv.rgb+", 1.0)"
|
||||
if rv.has("type") and mm_io_types.types.has(rv.type):
|
||||
if mm_io_types.types[rv.type].has("convert"):
|
||||
for c in mm_io_types.types[rv.type].convert:
|
||||
if !rv.has(c.type):
|
||||
var expr = c.expr.replace("$(value)", rv[rv.type])
|
||||
rv[c.type] = expr
|
||||
else:
|
||||
print("Missing type for node ")
|
||||
print(rv)
|
||||
return rv
|
||||
|
||||
func _get_shader_code(__, __, __) -> Dictionary:
|
||||
@ -212,8 +225,11 @@ func _serialize(data: Dictionary) -> Dictionary:
|
||||
|
||||
func serialize() -> Dictionary:
|
||||
var rv = { name=name, type=get_type(), parameters={}, node_position={ x=position.x, y=position.y } }
|
||||
for p in parameters.keys():
|
||||
rv.parameters[p] = MMType.serialize_value(parameters[p])
|
||||
for p in get_parameter_defs():
|
||||
if parameters.has(p.name):
|
||||
rv.parameters[p.name] = MMType.serialize_value(parameters[p.name])
|
||||
else:
|
||||
rv.parameters[p.name] = p.default
|
||||
if seed_locked:
|
||||
rv.seed_value = seed_value
|
||||
if model != null:
|
||||
@ -222,7 +238,7 @@ func serialize() -> Dictionary:
|
||||
rv = _serialize(rv)
|
||||
return rv
|
||||
|
||||
func _deserialize(data : Dictionary) -> void:
|
||||
func _deserialize(_data : Dictionary) -> void:
|
||||
pass
|
||||
|
||||
func deserialize(data : Dictionary) -> void:
|
||||
|
@ -174,6 +174,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
||||
for t in src_code.textures.keys():
|
||||
rv.textures[t] = src_code.textures[t]
|
||||
rv[convolution_params.output_type] = "%s_%d" % [ genname, variant_index ]
|
||||
rv.type = convolution_params.output_type
|
||||
return rv
|
||||
|
||||
|
||||
|
@ -331,5 +331,4 @@ func _deserialize(data : Dictionary) -> void:
|
||||
if data.has("label"):
|
||||
label = data.label
|
||||
var nodes = data.nodes if data.has("nodes") else []
|
||||
var connections = data.connections if data.has("connections") else []
|
||||
load("res://addons/material_maker/engine/loader.gd").add_to_gen_graph(self, nodes, connections)
|
||||
mm_loader.add_to_gen_graph(self, nodes, data.connections if data.has("connections") else [])
|
||||
|
@ -55,7 +55,6 @@ func set_port_name(i : int, n : String) -> void:
|
||||
ports[i].name = n
|
||||
|
||||
func set_port_type(i : int, t : String) -> void:
|
||||
print(t)
|
||||
ports[i].type = t
|
||||
emit_signal("parameter_changed", "__update_all__", null)
|
||||
|
||||
|
@ -37,7 +37,6 @@ func get_next_widget_name() -> String:
|
||||
|
||||
func fix() -> void:
|
||||
# Make sure all widgets have a name
|
||||
var i = 0
|
||||
for w in widgets:
|
||||
if !w.has("name"):
|
||||
w.name = get_next_widget_name()
|
||||
@ -76,7 +75,6 @@ func get_type_name() -> String:
|
||||
|
||||
func get_parameter_defs() -> Array:
|
||||
var rv = []
|
||||
var i = 0
|
||||
for w in widgets:
|
||||
match w.type:
|
||||
"config_control":
|
||||
@ -90,7 +88,6 @@ func get_parameter_defs() -> Array:
|
||||
for c in configurations:
|
||||
p.values.push_back({ name=c, value=c })
|
||||
rv.append(p)
|
||||
i += 1
|
||||
"linked_control":
|
||||
var linked = w.linked_widgets[0]
|
||||
var p : Dictionary
|
||||
@ -105,7 +102,6 @@ func get_parameter_defs() -> Array:
|
||||
p.name = w.name
|
||||
p.label = w.label
|
||||
rv.append(p)
|
||||
i += 1
|
||||
_:
|
||||
print("Unsupported widget of type "+str(w.type))
|
||||
return rv
|
||||
|
@ -55,7 +55,7 @@ func set_shader_model(data: Dictionary) -> void:
|
||||
for i in range(shader_model.outputs.size()):
|
||||
var output = shader_model.outputs[i]
|
||||
var output_code = ""
|
||||
for f in PORT_TYPES.keys():
|
||||
for f in mm_io_types.types.keys():
|
||||
if output.has(f):
|
||||
shader_model.outputs[i].type = f
|
||||
output_code = output[f]
|
||||
@ -78,7 +78,6 @@ func find_keyword_call(string, keyword):
|
||||
return null
|
||||
var parenthesis_level = 0
|
||||
var parameter_begin = position+search_string.length()
|
||||
var parameter_end = -1
|
||||
for i in range(parameter_begin, string.length()):
|
||||
if string[i] == '(':
|
||||
parenthesis_level += 1
|
||||
@ -126,7 +125,7 @@ func replace_input(string : String, context, input : String, type : String, src
|
||||
if src_code.has(type):
|
||||
src_code.string = src_code[type]
|
||||
else:
|
||||
src_code.string = "*error*"
|
||||
src_code.string = "*error missing "+type+"*\n"+JSON.print(src_code)
|
||||
# Add global definitions
|
||||
if src_code.has("globals"):
|
||||
for d in src_code.globals:
|
||||
@ -236,10 +235,6 @@ func subst(string : String, context : MMGenContext, uv : String = "") -> Diction
|
||||
cont = changed and new_pass_required
|
||||
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:
|
||||
var genname = "o"+str(get_instance_id())
|
||||
var rv = { globals=[], defs="", code="", textures={} }
|
||||
@ -260,7 +255,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
||||
var input = shader_model.inputs[i]
|
||||
if input.has("function") and input.function:
|
||||
var source = get_source(i)
|
||||
var string = "$%s(%s)" % [ input.name, PORT_TYPES[input.type].params ]
|
||||
var string = "$%s(%s)" % [ input.name, mm_io_types.types[input.type].params ]
|
||||
var local_context = MMGenContext.new(context)
|
||||
var result = replace_input(string, local_context, input.name, input.type, source, input.default)
|
||||
while result is GDScriptFunctionState:
|
||||
@ -274,7 +269,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
||||
# Add textures
|
||||
for t in result.textures.keys():
|
||||
rv.textures[t] = result.textures[t]
|
||||
rv.defs += "%s %s_input_%s(%s) {\n" % [ PORT_TYPES[input.type].type, genname, input.name, PORT_TYPES[input.type].paramdefs ]
|
||||
rv.defs += "%s %s_input_%s(%s) {\n" % [ mm_io_types.types[input.type].type, genname, input.name, mm_io_types.types[input.type].paramdefs ]
|
||||
rv.defs += "%s\n" % result.code
|
||||
rv.defs += "return %s;\n}\n" % result.string
|
||||
if shader_model.has("instance"):
|
||||
@ -307,7 +302,7 @@ 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)
|
||||
for f in PORT_TYPES.keys():
|
||||
for f in mm_io_types.types.keys():
|
||||
if output.has(f):
|
||||
var subst_output = subst(output[f], context, uv)
|
||||
while subst_output is GDScriptFunctionState:
|
||||
@ -320,12 +315,13 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
||||
rv.defs += subst_output.defs
|
||||
# Add generated code
|
||||
rv.code += subst_output.code
|
||||
rv.code += "%s %s_%d_%d_%s = %s;\n" % [ PORT_TYPES[f].type, genname, output_index, variant_index, f, subst_output.string ]
|
||||
rv.code += "%s %s_%d_%d_%s = %s;\n" % [ mm_io_types.types[f].type, genname, output_index, variant_index, f, subst_output.string ]
|
||||
for t in subst_output.textures.keys():
|
||||
rv.textures[t] = subst_output.textures[t]
|
||||
for f in PORT_TYPES.keys():
|
||||
for f in mm_io_types.types.keys():
|
||||
if output.has(f):
|
||||
rv[f] = "%s_%d_%d_%s" % [ genname, output_index, variant_index, f ]
|
||||
rv.type = output.type
|
||||
if shader_model.has("global") && rv.globals.find(shader_model.global) == -1:
|
||||
rv.globals.push_back(shader_model.global)
|
||||
return rv
|
||||
|
@ -9,11 +9,11 @@ Base class for texture generators that provide a texture as output
|
||||
var texture : ImageTexture = ImageTexture.new()
|
||||
|
||||
func get_output_defs() -> Array:
|
||||
return [ { rgba="" } ]
|
||||
return [ { rgba="", type="rgba" } ]
|
||||
|
||||
func _get_shader_code_lod(uv : String, output_index : int, context : MMGenContext, lod : float = 0.0) -> Dictionary:
|
||||
var genname = "o"+str(get_instance_id())
|
||||
var rv = { globals=[], defs="", code="" }
|
||||
var rv = { globals=[], defs="", code="", type="rgba" }
|
||||
var texture_name = genname+"_tex"
|
||||
var variant_index = context.get_variant(self, uv)
|
||||
if variant_index == -1:
|
||||
|
22
addons/material_maker/engine/io_types.gd
Normal file
@ -0,0 +1,22 @@
|
||||
tool
|
||||
extends Node
|
||||
|
||||
var type_names : Array = []
|
||||
var types : Dictionary = {}
|
||||
|
||||
func _ready():
|
||||
var file = File.new()
|
||||
if file.open("res://addons/material_maker/nodes/io_types.mmt", File.READ) != OK:
|
||||
print("Cannot read types")
|
||||
return false
|
||||
var type_list = parse_json(file.get_as_text())
|
||||
file.close()
|
||||
for t in type_list:
|
||||
if t.has("label"):
|
||||
type_names.push_back(t.name)
|
||||
var c = t.color
|
||||
t.color = Color(c.r, c.g, c.b, c.a)
|
||||
if file.open("res://addons/material_maker/nodes/preview_"+t.name+".shader", File.READ) == OK:
|
||||
t.preview = file.get_as_text()
|
||||
file.close()
|
||||
types[t.name] = t
|
@ -1,23 +1,42 @@
|
||||
tool
|
||||
extends Object
|
||||
class_name MMGenLoader
|
||||
extends Node
|
||||
|
||||
const STD_GENDEF_PATH = "res://addons/material_maker/nodes"
|
||||
|
||||
static func generator_name_from_path(path : String) -> String:
|
||||
var predefined_generators = {}
|
||||
|
||||
func _ready()-> void:
|
||||
update_predefined_generators()
|
||||
|
||||
func update_predefined_generators()-> void:
|
||||
predefined_generators = {}
|
||||
for path in [ STD_GENDEF_PATH, OS.get_executable_path().get_base_dir()+"/generators" ]:
|
||||
var dir = Directory.new()
|
||||
if dir.open(path) == OK:
|
||||
dir.list_dir_begin()
|
||||
var file_name = dir.get_next()
|
||||
while file_name != "":
|
||||
if !dir.current_is_dir() and file_name.get_extension() == "mmg":
|
||||
var file : File = File.new()
|
||||
if file.open(path+"/"+file_name, File.READ) == OK:
|
||||
predefined_generators[file_name.get_basename()] = parse_json(file.get_as_text())
|
||||
file.close()
|
||||
file_name = dir.get_next()
|
||||
|
||||
func generator_name_from_path(path : String) -> String:
|
||||
for p in [ STD_GENDEF_PATH, OS.get_executable_path().get_base_dir()+"/generators" ]:
|
||||
print(p)
|
||||
print(path.get_base_dir())
|
||||
return path.get_basename().get_file()
|
||||
|
||||
static func load_gen(filename: String) -> MMGenBase:
|
||||
func load_gen(filename: String) -> MMGenBase:
|
||||
var file = File.new()
|
||||
if file.open(filename, File.READ) == OK:
|
||||
var data = parse_json(file.get_as_text())
|
||||
return create_gen(data)
|
||||
return null
|
||||
|
||||
static func add_to_gen_graph(gen_graph, generators, connections) -> Dictionary:
|
||||
func add_to_gen_graph(gen_graph, generators, connections) -> Dictionary:
|
||||
var rv = { generators=[], connections=[] }
|
||||
var gennames = {}
|
||||
for n in generators:
|
||||
@ -35,7 +54,7 @@ static func add_to_gen_graph(gen_graph, generators, connections) -> Dictionary:
|
||||
rv.connections.append(c)
|
||||
return rv
|
||||
|
||||
static func create_gen(data) -> MMGenBase:
|
||||
func create_gen(data) -> MMGenBase:
|
||||
var guess = [
|
||||
{ keyword="connections", type=MMGenGraph },
|
||||
{ keyword="nodes", type=MMGenGraph },
|
||||
@ -64,22 +83,11 @@ static func create_gen(data) -> MMGenBase:
|
||||
if types.has(data.type):
|
||||
generator = types[data.type].new()
|
||||
else:
|
||||
var file = File.new()
|
||||
var gen_paths = [ STD_GENDEF_PATH, OS.get_executable_path().get_base_dir()+"/generators" ]
|
||||
for p in gen_paths:
|
||||
if file.open(p+"/"+data.type+".mmg", File.READ) == OK:
|
||||
generator = create_gen(parse_json(file.get_as_text()))
|
||||
generator.model = data.type
|
||||
file.close()
|
||||
break
|
||||
elif file.open(p+"/"+data.type+".mmn", File.READ) == OK:
|
||||
generator = MMGenShader.new()
|
||||
generator.model = data.type
|
||||
generator.set_shader_model(parse_json(file.get_as_text()))
|
||||
file.close()
|
||||
break
|
||||
generator = create_gen(predefined_generators[data.type])
|
||||
if generator == null:
|
||||
print("Cannot find description for "+data.type)
|
||||
else:
|
||||
generator.model = data.type
|
||||
if generator != null:
|
||||
generator.name = data.type
|
||||
if generator == null:
|
||||
@ -88,7 +96,7 @@ static func create_gen(data) -> MMGenBase:
|
||||
generator.deserialize(data)
|
||||
return generator
|
||||
|
||||
static func get_generator_list() -> Array:
|
||||
func get_generator_list() -> Array:
|
||||
var rv = []
|
||||
var dir : Directory = Directory.new()
|
||||
for p in [ STD_GENDEF_PATH, OS.get_executable_path().get_base_dir()+"/generators" ]:
|
||||
|
@ -38,75 +38,6 @@ static func generate_shader(src_code) -> String:
|
||||
code += shader_code
|
||||
return code
|
||||
|
||||
static func generate_preview_shader(src_code) -> String:
|
||||
var code
|
||||
code = "shader_type canvas_item;\n"
|
||||
code += "render_mode blend_disabled;\n"
|
||||
code += "uniform float preview_size = 64;\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("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
|
||||
var shader_code = src_code.defs
|
||||
if src_code.has("rgba"):
|
||||
shader_code += "\nvoid fragment() {\n"
|
||||
shader_code += "vec2 uv = UV;\n"
|
||||
shader_code += src_code.code
|
||||
shader_code += "COLOR = "+src_code.rgba+";\n"
|
||||
shader_code += "}\n"
|
||||
elif src_code.has("sdf2d"):
|
||||
shader_code += "\nvoid fragment() {\n"
|
||||
shader_code += "vec2 uv = UV;\n"
|
||||
shader_code += src_code.code
|
||||
shader_code += "float d = "+src_code.sdf2d+";\n"
|
||||
shader_code += "vec3 col = vec3(cos(d*min(256, preview_size)));\n"
|
||||
shader_code += "col *= clamp(1.0-d*d, 0.0, 1.0);\n"
|
||||
shader_code += "col *= vec3(1.0, vec2(step(-0.015, d)));\n"
|
||||
shader_code += "col *= vec3(vec2(step(d, 0.015)), 1.0);\n"
|
||||
shader_code += "COLOR = vec4(col, 1.0);\n"
|
||||
shader_code += "}\n"
|
||||
elif src_code.has("sdf3d"):
|
||||
shader_code += "\nfloat calcdist(vec3 uv) {\n"
|
||||
shader_code += src_code.code
|
||||
shader_code += "return min("+src_code.sdf3d+", uv.z);\n"
|
||||
shader_code += "}\n"
|
||||
shader_code += "float raymarch(vec3 ro, vec3 rd) {\n"
|
||||
shader_code += "float d=0.0;\n"
|
||||
shader_code += "for (int i = 0; i < 50; i++) {\n"
|
||||
shader_code += "vec3 p = ro + rd*d;\n"
|
||||
shader_code += "float dstep = calcdist(p);\n"
|
||||
shader_code += "d += dstep;\n"
|
||||
shader_code += "if (dstep < 0.0001) break;\n"
|
||||
shader_code += "}\n"
|
||||
shader_code += "return d;\n"
|
||||
shader_code += "}\n"
|
||||
shader_code += "vec3 normal(vec3 p) {\n"
|
||||
shader_code += " float d = calcdist(p);\n"
|
||||
shader_code += " float e = .0001;\n"
|
||||
shader_code += " vec3 n = d - vec3(calcdist(p-vec3(e, 0.0, 0.0)), calcdist(p-vec3(0.0, e, 0.0)), calcdist(p-vec3(0.0, 0.0, e)));\n"
|
||||
shader_code += " return normalize(n);\n"
|
||||
shader_code += "}\n"
|
||||
shader_code += "\nvoid fragment() {\n"
|
||||
shader_code += "vec2 uv = UV-vec2(0.5);\n"
|
||||
shader_code += "vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0)));\n"
|
||||
shader_code += "vec3 n = normal(p);\n"
|
||||
shader_code += "vec3 l = vec3(5.0, 5.0, 10.0);\n"
|
||||
shader_code += "vec3 ld = normalize(l-p);\n"
|
||||
shader_code += "float o = step(p.z, 0.001);\n"
|
||||
shader_code += "float shadow = 1.0-0.75*step(raymarch(l, -ld), length(l-p)-0.01);\n"
|
||||
shader_code += "float light = 0.3+0.7*dot(n, ld)*shadow;\n"
|
||||
shader_code += "COLOR = vec4(vec3(0.8+0.2*o, 0.8+0.2*o, 1.0)*light, 1.0);\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) -> String:
|
||||
var code
|
||||
code = "shader_type canvas_item;\n"
|
||||
|
@ -13,8 +13,7 @@ func set_ptex(s : String) -> void :
|
||||
call_deferred("update_texture")
|
||||
|
||||
func update_texture() -> void:
|
||||
var loader = MMGenLoader.new()
|
||||
var mm_graph = loader.create_gen(parse_json(ptex))
|
||||
var mm_graph = mm_loader.create_gen(parse_json(ptex))
|
||||
if mm_graph == null:
|
||||
return
|
||||
var mm_material : MMGenMaterial = mm_graph.get_node("Material")
|
||||
|
@ -10,7 +10,7 @@
|
||||
"corner": 0,
|
||||
"mortar": 0.1,
|
||||
"pattern": 0,
|
||||
"repeat": 1,
|
||||
"repeat": 2,
|
||||
"round": 0,
|
||||
"row_offset": 0.5,
|
||||
"rows": 6
|
||||
@ -29,7 +29,7 @@
|
||||
"type": "f"
|
||||
},
|
||||
{
|
||||
"rgb": "rand3(vec2($(name_uv).w, $(seed)))",
|
||||
"rgb": "rand3(fract($(name_uv)_rect.xy)+rand2(vec2($seed)))",
|
||||
"type": "rgb"
|
||||
},
|
||||
{
|
||||
|
92
addons/material_maker/nodes/fbm.mmg
Normal file
@ -0,0 +1,92 @@
|
||||
{
|
||||
"name": "fbm",
|
||||
"node_position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"parameters": {
|
||||
"iterations": 3,
|
||||
"noise": 0,
|
||||
"persistence": 0.5,
|
||||
"scale_x": 4,
|
||||
"scale_y": 4
|
||||
},
|
||||
"shader_model": {
|
||||
"code": "",
|
||||
"global": "float fbm_value(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat p00 = rand(mod(o, size));\n\tfloat p01 = rand(mod(o + vec2(0.0, 1.0), size));\n\tfloat p10 = rand(mod(o + vec2(1.0, 0.0), size));\n\tfloat p11 = rand(mod(o + vec2(1.0, 1.0), size));\n\tvec2 t = f * f * (3.0 - 2.0 * f);\n\treturn mix(mix(p00, p10, t.x), mix(p01, p11, t.x), t.y);\n}\n\nfloat fbm_perlin(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat a00 = rand(mod(o, size)) * 6.28318530718;\n\tfloat a01 = rand(mod(o + vec2(0.0, 1.0), size)) * 6.28318530718;\n\tfloat a10 = rand(mod(o + vec2(1.0, 0.0), size)) * 6.28318530718;\n\tfloat a11 = rand(mod(o + vec2(1.0, 1.0), size)) * 6.28318530718;\n\tvec2 v00 = vec2(cos(a00), sin(a00));\n\tvec2 v01 = vec2(cos(a01), sin(a01));\n\tvec2 v10 = vec2(cos(a10), sin(a10));\n\tvec2 v11 = vec2(cos(a11), sin(a11));\n\tfloat p00 = dot(v00, f);\n\tfloat p01 = dot(v01, f - vec2(0.0, 1.0));\n\tfloat p10 = dot(v10, f - vec2(1.0, 0.0));\n\tfloat p11 = dot(v11, f - vec2(1.0, 1.0));\n\tvec2 t = f * f * (3.0 - 2.0 * f);\n\treturn 0.5 + mix(mix(p00, p10, t.x), mix(p01, p11, t.x), t.y);\n}\n\nfloat fbm_cellular(vec2 coord, vec2 size, float seed) {\n\tvec2 o = floor(coord)+rand2(vec2(float(seed), 1.0-float(seed)))+size;\n\tvec2 f = fract(coord);\n\tfloat min_dist = 2.0;\n\tfor(float x = -1.0; x <= 1.0; x++) {\n\t\tfor(float y = -1.0; y <= 1.0; y++) {\n\t\t\tvec2 node = rand2(mod(o + vec2(x, y), size)) + vec2(x, y);\n\t\t\tfloat dist = sqrt((f - node).x * (f - node).x + (f - node).y * (f - node).y);\n\t\t\tmin_dist = min(min_dist, dist);\n\t\t}\n\t}\n\treturn min_dist;\n}\n",
|
||||
"inputs": [
|
||||
|
||||
],
|
||||
"instance": "float $(name)_fbm(vec2 coord, vec2 size, int octaves, float persistence, float seed) {\n\tfloat normalize_factor = 0.0;\n\tfloat value = 0.0;\n\tfloat scale = 1.0;\n\tfor (int i = 0; i < octaves; i++) {\n\t\tvalue += fbm_$noise(coord*size, size, seed) * scale;\n\t\tnormalize_factor += scale;\n\t\tsize *= 2.0;\n\t\tscale *= persistence;\n\t}\n\treturn value / normalize_factor;\n}\n",
|
||||
"name": "FBM",
|
||||
"outputs": [
|
||||
{
|
||||
"f": "$(name)_fbm($(uv), vec2($(scale_x), $(scale_y)), int($(iterations)), $(persistence), $(seed))",
|
||||
"type": "f"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"default": 2,
|
||||
"label": "Noise",
|
||||
"name": "noise",
|
||||
"type": "enum",
|
||||
"values": [
|
||||
{
|
||||
"name": "Value",
|
||||
"value": "value"
|
||||
},
|
||||
{
|
||||
"name": "Perlin",
|
||||
"value": "perlin"
|
||||
},
|
||||
{
|
||||
"name": "Cellular",
|
||||
"value": "cellular"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"control": "None",
|
||||
"default": 4,
|
||||
"label": "Scale X",
|
||||
"max": 32,
|
||||
"min": 1,
|
||||
"name": "scale_x",
|
||||
"step": 1,
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"control": "None",
|
||||
"default": 4,
|
||||
"label": "Scale Y",
|
||||
"max": 32,
|
||||
"min": 1,
|
||||
"name": "scale_y",
|
||||
"step": 1,
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"control": "None",
|
||||
"default": 3,
|
||||
"label": "Iterations",
|
||||
"max": 10,
|
||||
"min": 1,
|
||||
"name": "iterations",
|
||||
"step": 1,
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"control": "None",
|
||||
"default": 0.5,
|
||||
"label": "Persistance",
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"name": "persistence",
|
||||
"step": 0.05,
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "shader"
|
||||
}
|
88
addons/material_maker/nodes/io_types.mmt
Normal file
@ -0,0 +1,88 @@
|
||||
[
|
||||
{
|
||||
"name":"f",
|
||||
"label":"Greyscale",
|
||||
"type":"float",
|
||||
"paramdefs":"vec2 uv",
|
||||
"params":"uv",
|
||||
"slot_type":0,
|
||||
"convert":[
|
||||
{ "type":"rgb", "expr":"vec3($(value))" },
|
||||
{ "type":"rgba", "expr":"vec4(vec3($(value)), 1.0)" }
|
||||
],
|
||||
"color":{ "r":0.5, "g":0.5, "b":0.5, "a":1.0 }
|
||||
},
|
||||
{
|
||||
"name":"rgb",
|
||||
"label":"Color",
|
||||
"type":"vec3",
|
||||
"paramdefs":"vec2 uv",
|
||||
"params":"uv",
|
||||
"slot_type":0,
|
||||
"convert":[
|
||||
{ "type":"f", "expr":"(dot($(value), vec3(1.0))/3.0)" },
|
||||
{ "type":"rgba", "expr":"vec4($(value), 1.0)" }
|
||||
],
|
||||
"color":{ "r":0.5, "g":0.5, "b":1.0, "a":1.0 }
|
||||
},
|
||||
{
|
||||
"name":"rgba",
|
||||
"label":"RGBA",
|
||||
"type":"vec4",
|
||||
"paramdefs":"vec2 uv",
|
||||
"params":"uv",
|
||||
"slot_type":0,
|
||||
"convert":[
|
||||
{ "type":"f", "expr":"(dot(($(value)).rgb, vec3(1.0))/3.0)" },
|
||||
{ "type":"rgb", "expr":"(($(value)).rgb)" }
|
||||
],
|
||||
"color":{ "r":0.0, "g":0.5, "b":0.0, "a":0.5 }
|
||||
},
|
||||
{
|
||||
"name":"sdf2d",
|
||||
"label":"SDF2D",
|
||||
"type":"float",
|
||||
"paramdefs":"vec2 uv",
|
||||
"params":"uv",
|
||||
"slot_type":1,
|
||||
"color":{ "r":1.0, "g":0.5, "b":0.0, "a":1.0 }
|
||||
},
|
||||
{
|
||||
"name":"sdf3d",
|
||||
"label":"SDF3D",
|
||||
"type":"float",
|
||||
"paramdefs":"vec3 p",
|
||||
"params":"p",
|
||||
"slot_type":2,
|
||||
"convert":[
|
||||
{ "type":"sdf3dc", "expr":"vec2($(value), 0.0)" }
|
||||
],
|
||||
"color":{ "r":0.5, "g":0.0, "b":0.0, "a":1.0 }
|
||||
},
|
||||
{
|
||||
"name":"sdf3dc",
|
||||
"label":"SDF3D-C",
|
||||
"type":"vec2",
|
||||
"paramdefs":"vec3 p",
|
||||
"params":"p",
|
||||
"slot_type":2,
|
||||
"convert":[
|
||||
{ "type":"sdf3d", "expr":"($(value)).x" }
|
||||
],
|
||||
"color":{ "r":1.0, "g":0.0, "b":0.0, "a":1.0 }
|
||||
},
|
||||
{
|
||||
"name":"tex3d",
|
||||
"label":"TEX3D",
|
||||
"type":"vec3",
|
||||
"paramdefs":"vec4 p",
|
||||
"params":"p",
|
||||
"slot_type":3,
|
||||
"color":{ "r":1.0, "g":0.0, "b":1.0, "a":1.0 }
|
||||
},
|
||||
{
|
||||
"name":"any",
|
||||
"slot_type":42,
|
||||
"color":{ "r":1.0, "g":1.0, "b":1.0, "a":1.0 }
|
||||
}
|
||||
]
|
60
addons/material_maker/nodes/mul_detect.mmg
Normal file
@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "mul_detect",
|
||||
"node_position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"parameters": {
|
||||
"t": 0.01,
|
||||
"v": 0.5
|
||||
},
|
||||
"shader_model": {
|
||||
"code": "float $(name_uv)_d = ($in($uv)-$v)/$t;",
|
||||
"global": "",
|
||||
"inputs": [
|
||||
{
|
||||
"default": "1.0",
|
||||
"label": "",
|
||||
"name": "mul",
|
||||
"type": "f"
|
||||
},
|
||||
{
|
||||
"default": "0.0",
|
||||
"label": "",
|
||||
"name": "in",
|
||||
"type": "f"
|
||||
}
|
||||
],
|
||||
"instance": "",
|
||||
"name": "MulDetect",
|
||||
"outputs": [
|
||||
{
|
||||
"f": "$mul($uv)*clamp(1.0-$(name_uv)_d*$(name_uv)_d, 0.0, 1.0)",
|
||||
"type": "f"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"control": "None",
|
||||
"default": 0.5,
|
||||
"label": "Value",
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"name": "v",
|
||||
"step": 0.01,
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"control": "None",
|
||||
"default": 0.1,
|
||||
"label": "Tolerance",
|
||||
"max": 1,
|
||||
"min": 0.01,
|
||||
"name": "t",
|
||||
"step": 0.001,
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "shader"
|
||||
}
|
5
addons/material_maker/nodes/preview_f.shader
Normal file
@ -0,0 +1,5 @@
|
||||
void fragment() {
|
||||
vec2 uv = UV;
|
||||
$(code)
|
||||
COLOR = vec4(vec3($(value)), 1.0);
|
||||
}
|
5
addons/material_maker/nodes/preview_rgb.shader
Normal file
@ -0,0 +1,5 @@
|
||||
void fragment() {
|
||||
vec2 uv = UV;
|
||||
$(code)
|
||||
COLOR = vec4($(value), 1.0);
|
||||
}
|
5
addons/material_maker/nodes/preview_rgba.shader
Normal file
@ -0,0 +1,5 @@
|
||||
void fragment() {
|
||||
vec2 uv = UV;
|
||||
$(code)
|
||||
COLOR = $(value);
|
||||
}
|
10
addons/material_maker/nodes/preview_sdf2d.shader
Normal file
@ -0,0 +1,10 @@
|
||||
void fragment() {
|
||||
vec2 uv = UV;
|
||||
$(code)
|
||||
float d = $(value);
|
||||
vec3 col = vec3(cos(d*min(256, preview_size)));
|
||||
col *= clamp(1.0-d*d, 0.0, 1.0);
|
||||
col *= vec3(1.0, vec2(step(-0.015, d)));
|
||||
col *= vec3(vec2(step(d, 0.015)), 1.0);
|
||||
COLOR = vec4(col, 1.0);
|
||||
}
|
33
addons/material_maker/nodes/preview_sdf3d.shader
Normal file
@ -0,0 +1,33 @@
|
||||
float calcdist(vec3 uv) {
|
||||
$(code)
|
||||
return min($(value), uv.z);
|
||||
}
|
||||
|
||||
float raymarch(vec3 ro, vec3 rd) {
|
||||
float d=0.0;
|
||||
for (int i = 0; i < 50; i++) {
|
||||
vec3 p = ro + rd*d;
|
||||
float dstep = calcdist(p);
|
||||
d += dstep;
|
||||
if (dstep < 0.0001) break;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
vec3 normal(vec3 p) {
|
||||
float d = calcdist(p);
|
||||
float e = .0001;
|
||||
vec3 n = d - vec3(calcdist(p-vec3(e, 0.0, 0.0)), calcdist(p-vec3(0.0, e, 0.0)), calcdist(p-vec3(0.0, 0.0, e)));
|
||||
return normalize(n);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec2 uv = UV-vec2(0.5);
|
||||
vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0)));
|
||||
vec3 n = normal(p);
|
||||
vec3 l = vec3(5.0, 5.0, 10.0);
|
||||
vec3 ld = normalize(l-p);
|
||||
float o = step(p.z, 0.001);
|
||||
float shadow = 1.0-0.75*step(raymarch(l, -ld), length(l-p)-0.01);
|
||||
float light = 0.3+0.7*dot(n, ld)*shadow;
|
||||
COLOR = vec4(vec3(0.8+0.2*o, 0.8+0.2*o, 1.0)*light, 1.0);
|
||||
}
|
45
addons/material_maker/nodes/preview_sdf3dc.shader
Normal file
@ -0,0 +1,45 @@
|
||||
vec2 calcdist(vec3 uv) {
|
||||
$(code)
|
||||
vec2 v = $(value);
|
||||
return vec2(min(v.x, uv.z), v.y);
|
||||
}
|
||||
|
||||
vec2 raymarch(vec3 ro, vec3 rd) {
|
||||
float d=0.0;
|
||||
float color;
|
||||
for (int i = 0; i < 50; i++) {
|
||||
vec3 p = ro + rd*d;
|
||||
vec2 dstep = calcdist(p);
|
||||
d += dstep.x;
|
||||
if (dstep.x < 0.0001) {
|
||||
color = dstep.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return vec2(d, color);
|
||||
}
|
||||
vec3 normal(vec3 p) {
|
||||
float d = calcdist(p).x;
|
||||
float e = .0001;
|
||||
vec3 n = d - vec3(calcdist(p-vec3(e, 0.0, 0.0)).x, calcdist(p-vec3(0.0, e, 0.0)).x, calcdist(p-vec3(0.0, 0.0, e)).x);
|
||||
return normalize(n);
|
||||
}
|
||||
|
||||
vec3 rm_color(float c) {
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(vec3(c) + K.xyz) * 6.0 - K.www);
|
||||
return 1.0 * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), 1.0);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec2 uv = UV-vec2(0.5);
|
||||
vec2 rm = raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0));
|
||||
vec3 p = vec3(uv, 2.0-rm.x);
|
||||
vec3 n = normal(p);
|
||||
vec3 l = vec3(5.0, 5.0, 10.0);
|
||||
vec3 ld = normalize(l-p);
|
||||
float o = step(p.z, 0.001);
|
||||
float shadow = 1.0-0.75*step(raymarch(l, -ld).x, length(l-p)-0.01);
|
||||
float light = 0.3+0.7*dot(n, ld)*shadow;
|
||||
COLOR = vec4(mix(rm_color(fract(rm.y)), vec3(0.9), o)*light, 1.0);
|
||||
}
|
37
addons/material_maker/nodes/preview_tex3d.shader
Normal file
@ -0,0 +1,37 @@
|
||||
float calcdist(vec3 p) {
|
||||
return length(p)-0.4;
|
||||
}
|
||||
|
||||
vec3 calcColor(vec4 uv) {
|
||||
$(code)
|
||||
return $(value);
|
||||
}
|
||||
|
||||
float raymarch(vec3 ro, vec3 rd) {
|
||||
float d=0.0;
|
||||
for (int i = 0; i < 50; i++) {
|
||||
vec3 p = ro + rd*d;
|
||||
float dstep = calcdist(p);
|
||||
d += dstep;
|
||||
if (dstep < 0.0001) break;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
vec3 normal(vec3 p) {
|
||||
float d = calcdist(p);
|
||||
float e = .0001;
|
||||
vec3 n = d - vec3(calcdist(p-vec3(e, 0.0, 0.0)), calcdist(p-vec3(0.0, e, 0.0)), calcdist(p-vec3(0.0, 0.0, e)));
|
||||
return normalize(n);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec2 uv = UV-vec2(0.5);
|
||||
vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0)));
|
||||
vec3 n = normal(p);
|
||||
vec3 l = vec3(5.0, 5.0, 10.0);
|
||||
vec3 ld = normalize(l-p);
|
||||
float o = step(p.z, 0.001);
|
||||
float shadow = 1.0-0.75*step(raymarch(l, -ld), length(l-p)-0.01);
|
||||
float light = 0.3+0.7*dot(n, ld)*shadow;
|
||||
COLOR = vec4(calcColor(vec4(p, 0.0))*light, 1.0);
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
|
||||
},
|
||||
"shader_model": {
|
||||
"code": "float $(name_uv)_d = raymarch_$name($uv);\n",
|
||||
"code": "vec2 $(name_uv)_d = raymarch_$name($uv);\n",
|
||||
"global": "",
|
||||
"inputs": [
|
||||
{
|
||||
@ -16,19 +16,23 @@
|
||||
"function": true,
|
||||
"label": "",
|
||||
"name": "sdf",
|
||||
"type": "sdf3d"
|
||||
"type": "sdf3dc"
|
||||
}
|
||||
],
|
||||
"instance": "float input_$name(vec3 p) {\n\tif (p.z > 0.0) {\n\t\treturn $sdf(p);\n\t} else {\n\t\treturn p.z;\n\t}\n}\n\nfloat raymarch_$name(vec2 uv) {\n\tvec3 ro = vec3(uv-vec2(0.5), 1.0);\n\tvec3 rd = vec3(0.0, 0.0, -1.0);\n\tfloat dO=0.;\n \n for (int i=0; i < 25; i++) {\n \tvec3 p = ro + rd*dO;\n float dS = input_$name(p);\n dO += dS;\n if (dO > 1.0 || dS < 0.0001) break;\n }\n \n return dO;\n}\n\nvec3 normal_$name(vec3 p) {\n\tfloat d = input_$name(p);\n float e = .001;\n \n vec3 n = d - vec3(\n input_$name(p-vec3(e, 0.0, 0.0)),\n input_$name(p-vec3(0.0, e, 0.0)),\n input_$name(p-vec3(0.0, 0.0, e)));\n \n return vec3(-1.0, -1.0, -1.0)*normalize(n);\n}\n\n",
|
||||
"instance": "vec2 raymarch_$name(vec2 uv) {\n\tvec3 ro = vec3(uv-vec2(0.5), 1.0);\n\tvec3 rd = vec3(0.0, 0.0, -1.0);\n\tfloat dO = 0.0;\n\tfloat c = 0.0;\n for (int i=0; i < 100; i++) {\n \tvec3 p = ro + rd*dO;\n vec2 dS = $sdf(p);\n dO += dS.x;\n\n if (dO >= 1.0) {\n\t\t\tbreak;\n\t\t} else if (dS.x < 0.0001) {\n\t\t\tc = dS.y;\n\t\t\tbreak;\n\t\t}\n }\n \n return vec2(dO, c);\n}\n\nvec3 normal_$name(vec3 p) {\n\tif (p.z <= 0.0) {\n\t\treturn vec3(0.0, 0.0, 1.0);\n\t}\n\n\tfloat d = $sdf(p).x;\n float e = .001;\n \n vec3 n = d - vec3(\n $sdf(p-vec3(e, 0.0, 0.0)).x,\n $sdf(p-vec3(0.0, e, 0.0)).x,\n $sdf(p-vec3(0.0, 0.0, e)).x);\n \n return vec3(-1.0, -1.0, -1.0)*normalize(n);\n}\n\n",
|
||||
"name": "Raymarching",
|
||||
"outputs": [
|
||||
{
|
||||
"f": "1.0-$(name_uv)_d",
|
||||
"f": "1.0-$(name_uv)_d.x",
|
||||
"type": "f"
|
||||
},
|
||||
{
|
||||
"rgb": "vec3(0.5)+0.5*normal_$name(vec3($uv-vec2(0.5), 1.0-$(name_uv)_d))",
|
||||
"rgb": "vec3(0.5)+0.5*normal_$name(vec3($uv-vec2(0.5), 1.0-$(name_uv)_d.x))",
|
||||
"type": "rgb"
|
||||
},
|
||||
{
|
||||
"f": "$(name_uv)_d.y",
|
||||
"type": "f"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
|
@ -5,57 +5,51 @@
|
||||
"y": 0
|
||||
},
|
||||
"parameters": {
|
||||
"bevel": 0,
|
||||
"cx": 0,
|
||||
"cy": 0,
|
||||
"h": 0.08,
|
||||
"op": 0,
|
||||
"r": 0.3,
|
||||
"w": 0.28
|
||||
"op": 0
|
||||
},
|
||||
"shader_model": {
|
||||
"code": "",
|
||||
"global": "",
|
||||
"global": "vec2 sdf3dc_union(vec2 a, vec2 b) {\n\treturn vec2(min(a.x, b.x), mix(b.y, a.y, step(a.x, b.x)));\n}\nvec2 sdf3dc_sub(vec2 a, vec2 b) {\n\treturn vec2(max(-a.x, b.x), a.y);\n}\nvec2 sdf3dc_inter(vec2 a, vec2 b) {\n\treturn vec2(max(a.x, b.x), mix(a.y, b.y, step(a.x, b.x)));\n}\n",
|
||||
"inputs": [
|
||||
{
|
||||
"default": "0.0",
|
||||
"default": "vec2(0.0)",
|
||||
"label": "",
|
||||
"name": "in1",
|
||||
"type": "sdf3d"
|
||||
"type": "sdf3dc"
|
||||
},
|
||||
{
|
||||
"default": "0.0",
|
||||
"default": "vec2(0.0)",
|
||||
"label": "",
|
||||
"name": "in2",
|
||||
"type": "sdf3d"
|
||||
"type": "sdf3dc"
|
||||
}
|
||||
],
|
||||
"instance": "",
|
||||
"name": "Boolean",
|
||||
"outputs": [
|
||||
{
|
||||
"sdf3d": "$op $in1($uv), $in2($uv))",
|
||||
"type": "sdf3d"
|
||||
"sdf3dc": "$op($in1($uv), $in2($uv))",
|
||||
"type": "sdf3dc"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"default": 1,
|
||||
"default": 2,
|
||||
"label": "",
|
||||
"name": "op",
|
||||
"type": "enum",
|
||||
"values": [
|
||||
{
|
||||
"name": "Union",
|
||||
"value": "min("
|
||||
"value": "sdf3dc_union"
|
||||
},
|
||||
{
|
||||
"name": "Subtraction",
|
||||
"value": "max(-"
|
||||
"value": "sdf3dc_sub"
|
||||
},
|
||||
{
|
||||
"name": "Intersection",
|
||||
"value": "max("
|
||||
"value": "sdf3dc_inter"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
},
|
||||
"parameters": {
|
||||
"a": 0,
|
||||
"c": 4,
|
||||
"c": 5,
|
||||
"r": 0.24,
|
||||
"rx": 4,
|
||||
"ry": 4,
|
||||
@ -20,22 +20,23 @@
|
||||
"global": "vec3 circle_repeat_transform(vec3 p, float count) {\n\tfloat r = 6.28/count;\n\tfloat pa = atan(p.x, p.y);\n\tfloat a = mod(pa+0.5*r, r)-0.5*r;\n\tvec3 rv;\n\tfloat c = cos(a-pa);\n\tfloat s = sin(a-pa);\n\trv.x = p.x*c+p.y*s;\n\trv.y = -p.x*s+p.y*c;\n\trv.z = p.z;\n\treturn rv;\n}\n",
|
||||
"inputs": [
|
||||
{
|
||||
"default": "0.0",
|
||||
"default": "vec2(0.0)",
|
||||
"label": "",
|
||||
"name": "in",
|
||||
"type": "sdf3d"
|
||||
"type": "sdf3dc"
|
||||
}
|
||||
],
|
||||
"instance": "",
|
||||
"name": "Circle Repeat",
|
||||
"outputs": [
|
||||
{
|
||||
"sdf3d": "$in(circle_repeat_transform($uv, $c))",
|
||||
"type": "sdf3d"
|
||||
"sdf3dc": "$in(circle_repeat_transform($uv, $c))",
|
||||
"type": "sdf3dc"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"control": "None",
|
||||
"default": 4,
|
||||
"label": "",
|
||||
"max": 32,
|
||||
|
51
addons/material_maker/nodes/sdf3d_color.mmg
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "sdf3d_color",
|
||||
"node_position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"parameters": {
|
||||
"bevel": 0,
|
||||
"c": 0.5,
|
||||
"cx": 0,
|
||||
"cy": 0,
|
||||
"h": 0.08,
|
||||
"k": 0.15,
|
||||
"op": 0,
|
||||
"r": 0.15,
|
||||
"w": 0.28
|
||||
},
|
||||
"shader_model": {
|
||||
"code": "",
|
||||
"global": "",
|
||||
"inputs": [
|
||||
{
|
||||
"default": "0.0",
|
||||
"label": "",
|
||||
"name": "in",
|
||||
"type": "sdf3d"
|
||||
}
|
||||
],
|
||||
"instance": "",
|
||||
"name": "Color",
|
||||
"outputs": [
|
||||
{
|
||||
"sdf3dc": "vec2($in($uv), $c)",
|
||||
"type": "sdf3dc"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"control": "None",
|
||||
"default": 0,
|
||||
"label": "",
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"name": "c",
|
||||
"step": 0.01,
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "shader"
|
||||
}
|
65
addons/material_maker/nodes/sdf3d_elongation.mmg
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "sdf3d_elongation",
|
||||
"node_position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"parameters": {
|
||||
"x": 0.2,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"shader_model": {
|
||||
"code": "",
|
||||
"global": "",
|
||||
"inputs": [
|
||||
{
|
||||
"default": "vec2(0.0)",
|
||||
"label": "",
|
||||
"name": "in",
|
||||
"type": "sdf3dc"
|
||||
}
|
||||
],
|
||||
"instance": "",
|
||||
"name": "Elongation",
|
||||
"outputs": [
|
||||
{
|
||||
"sdf3dc": "$in($uv-clamp($uv, -abs(vec3($x, $y, $z)), abs(vec3($x, $y, $z))))",
|
||||
"type": "sdf3dc"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"control": "P1.x",
|
||||
"default": 0,
|
||||
"label": "X",
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"name": "x",
|
||||
"step": 0.01,
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"control": "P1.y",
|
||||
"default": 0,
|
||||
"label": "Y",
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"name": "y",
|
||||
"step": 0.01,
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"control": "None",
|
||||
"default": 0,
|
||||
"label": "Z",
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"name": "z",
|
||||
"step": 0.01,
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "shader"
|
||||
}
|