mirror of
https://github.com/Relintai/material-maker.git
synced 2024-12-23 21:16:54 +01:00
Started optimizing 2D preview
float parameters don't trigger shader regeneration anymore
This commit is contained in:
parent
59c9e3b7b1
commit
455dcc7fde
@ -110,12 +110,19 @@ func get_parameter_def(param_name : String) -> Dictionary:
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
func get_parameter(n : String):
|
func get_parameter(n : String):
|
||||||
|
if parameters.has(n):
|
||||||
return parameters[n]
|
return parameters[n]
|
||||||
|
else:
|
||||||
|
return get_parameter_def(n).default
|
||||||
|
|
||||||
func set_parameter(n : String, v) -> void:
|
func set_parameter(n : String, v) -> void:
|
||||||
parameters[n] = v
|
parameters[n] = v
|
||||||
source_changed(0)
|
source_changed(0)
|
||||||
emit_signal("parameter_changed", n, v)
|
emit_signal("parameter_changed", n, v)
|
||||||
|
if is_inside_tree():
|
||||||
|
var parameter_def : Dictionary = get_parameter_def(n)
|
||||||
|
if parameter_def.has("type") and parameter_def.type == "float":
|
||||||
|
get_tree().call_group("preview", "on_float_parameter_changed", "p_o%s_%s" % [ str(get_instance_id()), n ], v)
|
||||||
|
|
||||||
func notify_output_change(output_index : int) -> void:
|
func notify_output_change(output_index : int) -> void:
|
||||||
var targets = get_targets(output_index)
|
var targets = get_targets(output_index)
|
||||||
@ -159,7 +166,7 @@ func get_input_shader(input_index : int) -> Dictionary:
|
|||||||
func get_shader(output_index : int, context) -> Dictionary:
|
func get_shader(output_index : int, context) -> Dictionary:
|
||||||
return get_shader_code("UV", output_index, context)
|
return get_shader_code("UV", output_index, context)
|
||||||
|
|
||||||
func generate_preview_shader(src_code, type) -> String:
|
static func generate_preview_shader(src_code, type, main_fct = "void fragment() { COLOR = preview_2d(UV); }") -> String:
|
||||||
var code
|
var code
|
||||||
code = "shader_type canvas_item;\n"
|
code = "shader_type canvas_item;\n"
|
||||||
code += "render_mode blend_disabled;\n"
|
code += "render_mode blend_disabled;\n"
|
||||||
@ -182,6 +189,7 @@ func generate_preview_shader(src_code, type) -> String:
|
|||||||
shader_code += preview_code
|
shader_code += preview_code
|
||||||
#print("GENERATED SHADER:\n"+shader_code)
|
#print("GENERATED SHADER:\n"+shader_code)
|
||||||
code += shader_code
|
code += shader_code
|
||||||
|
code += main_fct
|
||||||
return code
|
return code
|
||||||
|
|
||||||
func render(output_index : int, size : int, preview : bool = false) -> Object:
|
func render(output_index : int, size : int, preview : bool = false) -> Object:
|
||||||
|
@ -188,7 +188,7 @@ func subst(string : String, context : MMGenContext, uv : String = "") -> Diction
|
|||||||
var value = parameters[p.name]
|
var value = parameters[p.name]
|
||||||
var value_string = null
|
var value_string = null
|
||||||
if p.type == "float":
|
if p.type == "float":
|
||||||
value_string = "%.9f" % value
|
value_string = "p_%s_%s" % [ genname, p.name ]
|
||||||
elif p.type == "size":
|
elif p.type == "size":
|
||||||
value_string = "%.9f" % pow(2, value)
|
value_string = "%.9f" % pow(2, value)
|
||||||
elif p.type == "enum":
|
elif p.type == "enum":
|
||||||
@ -247,7 +247,9 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
|||||||
if !context.has_variant(self):
|
if !context.has_variant(self):
|
||||||
# Generate functions for gradients
|
# Generate functions for gradients
|
||||||
for p in shader_model.parameters:
|
for p in shader_model.parameters:
|
||||||
if p.type == "gradient":
|
if p.type == "float":
|
||||||
|
rv.defs += "uniform float p_%s_%s = %.9f;\n" % [ genname, p.name, parameters[p.name] ]
|
||||||
|
elif p.type == "gradient":
|
||||||
var g = parameters[p.name]
|
var g = parameters[p.name]
|
||||||
if !(g is MMGradient):
|
if !(g is MMGradient):
|
||||||
g = MMGradient.new()
|
g = MMGradient.new()
|
||||||
|
@ -39,7 +39,7 @@ func get_input_defs() -> Array:
|
|||||||
|
|
||||||
func get_output_defs() -> Array:
|
func get_output_defs() -> Array:
|
||||||
var rv : Array = []
|
var rv : Array = []
|
||||||
for o in range(parameters.outputs):
|
for o in range(get_parameter("outputs")):
|
||||||
var n = PoolByteArray([65+o]).get_string_from_ascii()
|
var n = PoolByteArray([65+o]).get_string_from_ascii()
|
||||||
rv.push_back({ name=n, type="any" })
|
rv.push_back({ name=n, type="any" })
|
||||||
return rv
|
return rv
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
void fragment() {
|
vec4 preview_2d(vec2 uv) {
|
||||||
vec2 uv = UV;
|
|
||||||
$(code)
|
$(code)
|
||||||
COLOR = vec4(vec3($(value)), 1.0);
|
return vec4(vec3($(value)), 1.0);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
void fragment() {
|
vec4 preview_2d(vec2 uv) {
|
||||||
vec2 uv = UV;
|
|
||||||
$(code)
|
$(code)
|
||||||
COLOR = vec4($(value), 1.0);
|
return vec4($(value), 1.0);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
void fragment() {
|
vec4 preview_2d(vec2 uv) {
|
||||||
vec2 uv = UV;
|
|
||||||
$(code)
|
$(code)
|
||||||
COLOR = $(value);
|
return $(value);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
void fragment() {
|
vec4 preview_2d(vec2 uv) {
|
||||||
vec2 uv = UV;
|
|
||||||
$(code)
|
$(code)
|
||||||
float d = $(value);
|
float d = $(value);
|
||||||
vec3 col = vec3(cos(d*min(256, preview_size)));
|
vec3 col = vec3(cos(d*min(256, preview_size)));
|
||||||
col *= clamp(1.0-d*d, 0.0, 1.0);
|
col *= clamp(1.0-d*d, 0.0, 1.0);
|
||||||
col *= vec3(1.0, vec2(step(-0.015, d)));
|
col *= vec3(1.0, vec2(step(-0.015, d)));
|
||||||
col *= vec3(vec2(step(d, 0.015)), 1.0);
|
col *= vec3(vec2(step(d, 0.015)), 1.0);
|
||||||
COLOR = vec4(col, 1.0);
|
return vec4(col, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ vec3 normal(vec3 p) {
|
|||||||
return normalize(n);
|
return normalize(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fragment() {
|
vec4 preview_2d(vec2 uv) {
|
||||||
vec2 uv = UV-vec2(0.5);
|
uv -= vec2(0.5);
|
||||||
vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0)));
|
vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0)));
|
||||||
vec3 n = normal(p);
|
vec3 n = normal(p);
|
||||||
vec3 l = vec3(5.0, 5.0, 10.0);
|
vec3 l = vec3(5.0, 5.0, 10.0);
|
||||||
@ -29,5 +29,5 @@ void fragment() {
|
|||||||
float o = step(p.z, 0.001);
|
float o = step(p.z, 0.001);
|
||||||
float shadow = 1.0-0.75*step(raymarch(l, -ld), length(l-p)-0.01);
|
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;
|
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);
|
return vec4(vec3(0.8+0.2*o, 0.8+0.2*o, 1.0)*light, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@ vec3 rm_color(float c) {
|
|||||||
return 1.0 * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), 1.0);
|
return 1.0 * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fragment() {
|
vec4 preview_2d(vec2 uv) {
|
||||||
vec2 uv = UV-vec2(0.5);
|
uv -= vec2(0.5);
|
||||||
vec2 rm = raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0));
|
vec2 rm = raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0));
|
||||||
vec3 p = vec3(uv, 2.0-rm.x);
|
vec3 p = vec3(uv, 2.0-rm.x);
|
||||||
vec3 n = normal(p);
|
vec3 n = normal(p);
|
||||||
@ -41,5 +41,5 @@ void fragment() {
|
|||||||
float o = step(p.z, 0.001);
|
float o = step(p.z, 0.001);
|
||||||
float shadow = 1.0-0.75*step(raymarch(l, -ld).x, length(l-p)-0.01);
|
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;
|
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);
|
return vec4(mix(rm_color(fract(rm.y)), vec3(0.9), o)*light, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ vec3 normal(vec3 p) {
|
|||||||
return normalize(n);
|
return normalize(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fragment() {
|
vec4 preview_2d(vec2 uv) {
|
||||||
vec2 uv = UV-vec2(0.5);
|
vec2 uv -= vec2(0.5);
|
||||||
vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0)));
|
vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0)));
|
||||||
vec3 n = normal(p);
|
vec3 n = normal(p);
|
||||||
vec3 l = vec3(5.0, 5.0, 10.0);
|
vec3 l = vec3(5.0, 5.0, 10.0);
|
||||||
@ -33,5 +33,5 @@ void fragment() {
|
|||||||
float o = step(p.z, 0.001);
|
float o = step(p.z, 0.001);
|
||||||
float shadow = 1.0-0.75*step(raymarch(l, -ld), length(l-p)-0.01);
|
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;
|
float light = 0.3+0.7*dot(n, ld)*shadow;
|
||||||
COLOR = vec4(calcColor(vec4(p, 0.0))*light, 1.0);
|
return vec4(calcColor(vec4(p, 0.0))*light, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -583,33 +583,33 @@ func update_preview_2d(node = null) -> void:
|
|||||||
node = n
|
node = n
|
||||||
break
|
break
|
||||||
if node != null:
|
if node != null:
|
||||||
var result = node.generator.render(0, 1024, true)
|
preview_2d.set_generator(node.generator)
|
||||||
while result is GDScriptFunctionState:
|
preview_2d_background.set_generator(node.generator)
|
||||||
result = yield(result, "completed")
|
|
||||||
var tex = ImageTexture.new()
|
|
||||||
result.copy_to_texture(tex)
|
|
||||||
result.release()
|
|
||||||
preview_2d.set_preview_texture(tex)
|
|
||||||
preview_2d_background.set_preview_texture(tex)
|
|
||||||
else:
|
else:
|
||||||
preview_2d.set_preview_texture(null)
|
preview_2d.set_generator(null)
|
||||||
preview_2d_background.set_preview_texture(null)
|
preview_2d_background.set_generator(null)
|
||||||
|
|
||||||
func update_preview_3d(previews : Array) -> void:
|
func update_preview_3d(previews : Array) -> void:
|
||||||
|
var visible_previews = []
|
||||||
|
for p in previews:
|
||||||
|
if p.is_visible_in_tree():
|
||||||
|
visible_previews.push_back(p)
|
||||||
|
if visible_previews.empty():
|
||||||
|
return
|
||||||
var graph_edit : MMGraphEdit = get_current_graph_edit()
|
var graph_edit : MMGraphEdit = get_current_graph_edit()
|
||||||
if graph_edit != null and graph_edit.top_generator != null and graph_edit.top_generator.has_node("Material"):
|
if graph_edit != null and graph_edit.top_generator != null and graph_edit.top_generator.has_node("Material"):
|
||||||
var gen_material = graph_edit.top_generator.get_node("Material")
|
var gen_material = graph_edit.top_generator.get_node("Material")
|
||||||
var status = gen_material.render_textures()
|
var status = gen_material.render_textures()
|
||||||
while status is GDScriptFunctionState:
|
while status is GDScriptFunctionState:
|
||||||
status = yield(status, "completed")
|
status = yield(status, "completed")
|
||||||
for p in previews:
|
for p in visible_previews:
|
||||||
gen_material.update_materials(p.get_materials())
|
gen_material.update_materials(p.get_materials())
|
||||||
|
|
||||||
var selected_node = null
|
var selected_node = null
|
||||||
func on_selected_node_change(node) -> void:
|
func on_selected_node_change(node) -> void:
|
||||||
if node != selected_node:
|
if node != selected_node:
|
||||||
selected_node = node
|
selected_node = node
|
||||||
preview_2d.setup_controls(node.generator if node != null else null)
|
preview_2d.set_generator(node.generator if node != null else null)
|
||||||
update_preview_2d(node)
|
update_preview_2d(node)
|
||||||
|
|
||||||
func _on_Projects_tab_changed(tab) -> void:
|
func _on_Projects_tab_changed(tab) -> void:
|
||||||
|
@ -1,24 +1,39 @@
|
|||||||
extends ColorRect
|
extends ColorRect
|
||||||
|
|
||||||
var generator = null
|
export(String, MULTILINE) var shader : String = ""
|
||||||
|
|
||||||
func set_preview_texture(tex: Texture) -> void:
|
var generator : MMGenBase = null
|
||||||
material.set_shader_param("tex", tex)
|
|
||||||
|
|
||||||
func on_resized() -> void:
|
func set_generator(g : MMGenBase) -> void:
|
||||||
material.set_shader_param("size", rect_size)
|
if generator != null and is_instance_valid(generator):
|
||||||
setup_controls(generator)
|
generator.disconnect("float_param_changed", self, "on_float_param_changed")
|
||||||
|
var source = { defs="", code="", textures={}, type="f", f="1.0" }
|
||||||
func setup_controls(g : MMGenBase) -> void:
|
|
||||||
if is_instance_valid(g):
|
if is_instance_valid(g):
|
||||||
generator = g
|
generator = g
|
||||||
var param_defs : Array = generator.get_parameter_defs()
|
var param_defs : Array = generator.get_parameter_defs()
|
||||||
for c in get_children():
|
for c in get_children():
|
||||||
c.setup_control(generator, param_defs)
|
c.setup_control(generator, param_defs)
|
||||||
|
generator.connect("float_param_changed", self, "on_float_param_changed")
|
||||||
|
var gen_output_defs = generator.get_output_defs()
|
||||||
|
if ! gen_output_defs.empty():
|
||||||
|
var context : MMGenContext = MMGenContext.new()
|
||||||
|
source = generator.get_shader_code("uv", 0, context)
|
||||||
|
while source is GDScriptFunctionState:
|
||||||
|
source = yield(source, "completed")
|
||||||
|
if source.empty():
|
||||||
|
source = { defs="", code="", textures={}, type="f", f="1.0" }
|
||||||
else:
|
else:
|
||||||
g = null
|
g = null
|
||||||
for c in get_children():
|
for c in get_children():
|
||||||
c.setup_control(generator, [])
|
c.setup_control(generator, [])
|
||||||
|
material.shader.code = MMGenBase.generate_preview_shader(source, source.type, shader)
|
||||||
|
|
||||||
|
func on_float_parameter_changed(n : String, v : float) -> void:
|
||||||
|
material.set_shader_param(n, v)
|
||||||
|
|
||||||
|
func on_resized() -> void:
|
||||||
|
material.set_shader_param("size", rect_size)
|
||||||
|
set_generator(generator)
|
||||||
|
|
||||||
func value_to_pos(value : Vector2) -> Vector2:
|
func value_to_pos(value : Vector2) -> Vector2:
|
||||||
return rect_size*0.5+value*min(rect_size.x, rect_size.y)/1.2
|
return rect_size*0.5+value*min(rect_size.x, rect_size.y)/1.2
|
||||||
|
@ -3,28 +3,14 @@
|
|||||||
[ext_resource path="res://material_maker/preview/preview_2d.gd" type="Script" id=1]
|
[ext_resource path="res://material_maker/preview/preview_2d.gd" type="Script" id=1]
|
||||||
|
|
||||||
[sub_resource type="Shader" id=1]
|
[sub_resource type="Shader" id=1]
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
uniform sampler2D tex;
|
|
||||||
uniform vec2 size;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
float ms = max(size.x, size.y);
|
|
||||||
vec2 uv = fract(0.5+1.2*(UV-vec2(0.5))*ms/size.yx);
|
|
||||||
float is = min(size.x, size.y)/1.2;
|
|
||||||
vec2 m2 = min(fract(uv), 1.0-fract(uv));
|
|
||||||
vec4 image = texture(tex, uv);
|
|
||||||
vec3 image_with_background = mix(vec3(mod(floor(uv.x*32.0)+floor(uv.y*32.0), 2.0)), image.xyz, image.a);
|
|
||||||
float lines_color = 0.5*(cos(5.0*TIME+100.0*(uv.x+uv.y))+1.0);
|
|
||||||
COLOR = vec4(mix(image_with_background, vec3(lines_color), step(is*min(m2.x, m2.y), 1.0)), 1.0);
|
|
||||||
}"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=2]
|
[sub_resource type="ShaderMaterial" id=2]
|
||||||
resource_local_to_scene = true
|
resource_local_to_scene = true
|
||||||
shader = SubResource( 1 )
|
shader = SubResource( 1 )
|
||||||
shader_param/size = Vector2( 585, 492 )
|
|
||||||
|
|
||||||
[node name="Preview2D" type="ColorRect"]
|
[node name="Preview2D" type="ColorRect" groups=[
|
||||||
|
"preview",
|
||||||
|
]]
|
||||||
material = SubResource( 2 )
|
material = SubResource( 2 )
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
@ -39,4 +25,16 @@ script = ExtResource( 1 )
|
|||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
shader = "uniform vec2 size;
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
float ms = max(size.x, size.y);
|
||||||
|
vec2 uv = fract(0.5+1.2*(UV-vec2(0.5))*ms/size.yx);
|
||||||
|
float is = min(size.x, size.y)/1.2;
|
||||||
|
vec2 m2 = min(fract(uv), 1.0-fract(uv));
|
||||||
|
vec4 image = preview_2d(uv);
|
||||||
|
vec3 image_with_background = mix(vec3(mod(floor(uv.x*32.0)+floor(uv.y*32.0), 2.0)), image.xyz, image.a);
|
||||||
|
float lines_color = 0.5*(cos(5.0*TIME+100.0*(uv.x+uv.y))+1.0);
|
||||||
|
COLOR = vec4(mix(image_with_background, vec3(lines_color), step(is*min(m2.x, m2.y), 1.0)), 1.0);
|
||||||
|
}"
|
||||||
[connection signal="resized" from="." to="." method="on_resized"]
|
[connection signal="resized" from="." to="." method="on_resized"]
|
||||||
|
Loading…
Reference in New Issue
Block a user