mirror of
https://github.com/Relintai/material-maker.git
synced 2025-01-09 05:39:38 +01:00
Started implementing the Tones node
This commit is contained in:
parent
8898f709fe
commit
565219ab74
@ -53,6 +53,9 @@ func toggle_editable() -> bool:
|
||||
func is_template() -> bool:
|
||||
return model != null
|
||||
|
||||
func get_template_name() -> bool:
|
||||
return model
|
||||
|
||||
func is_editable() -> bool:
|
||||
return false
|
||||
|
||||
|
122
addons/material_maker/nodes/levels.mmg
Normal file
122
addons/material_maker/nodes/levels.mmg
Normal file
@ -0,0 +1,122 @@
|
||||
{
|
||||
"name": "levels",
|
||||
"node_position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"parameters": {
|
||||
"in_max": {
|
||||
"a": 1,
|
||||
"b": 1,
|
||||
"g": 1,
|
||||
"r": 1,
|
||||
"type": "Color"
|
||||
},
|
||||
"in_mid": {
|
||||
"a": 0.5,
|
||||
"b": 0.5,
|
||||
"g": 0.5,
|
||||
"r": 0.5,
|
||||
"type": "Color"
|
||||
},
|
||||
"in_min": {
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"g": 0,
|
||||
"r": 0,
|
||||
"type": "Color"
|
||||
},
|
||||
"out_max": {
|
||||
"a": 1,
|
||||
"b": 1,
|
||||
"g": 1,
|
||||
"r": 1,
|
||||
"type": "Color"
|
||||
},
|
||||
"out_min": {
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"g": 0,
|
||||
"r": 0,
|
||||
"type": "Color"
|
||||
}
|
||||
},
|
||||
"shader_model": {
|
||||
"code": "",
|
||||
"global": "vec4 adjust_levels(vec4 input, vec4 in_min, vec4 in_mid, vec4 in_max, vec4 out_min, vec4 out_max) {\n\tinput = clamp((input-in_min)/(in_max-in_min), 0.0, 1.0);\n\tin_mid = (in_mid-in_min)/(in_max-in_min);\n\tvec4 dark = step(in_mid, input);\n\tinput = 0.5*mix(input/(in_mid), 1.0+(input-in_mid)/(1.0-in_mid), dark);\n\treturn out_min+input*(out_max-out_min);\n}\n",
|
||||
"inputs": [
|
||||
{
|
||||
"default": "vec4(1.0)",
|
||||
"label": "",
|
||||
"name": "input",
|
||||
"type": "rgba"
|
||||
}
|
||||
],
|
||||
"instance": "",
|
||||
"name": "Levels",
|
||||
"outputs": [
|
||||
{
|
||||
"rgba": "adjust_levels($input($uv), $in_min, $in_mid, $in_max, $out_min, $out_max)",
|
||||
"type": "rgba"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"default": {
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"g": 0,
|
||||
"r": 0
|
||||
},
|
||||
"label": "",
|
||||
"name": "in_min",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"default": {
|
||||
"a": 0.498039,
|
||||
"b": 0.498039,
|
||||
"g": 0.498039,
|
||||
"r": 0.498039
|
||||
},
|
||||
"label": "",
|
||||
"name": "in_mid",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"default": {
|
||||
"a": 1,
|
||||
"b": 1,
|
||||
"g": 1,
|
||||
"r": 1
|
||||
},
|
||||
"label": "",
|
||||
"name": "in_max",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"default": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"g": 0,
|
||||
"r": 0
|
||||
},
|
||||
"label": "",
|
||||
"name": "out_min",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"default": {
|
||||
"a": 1,
|
||||
"b": 1,
|
||||
"g": 1,
|
||||
"r": 1
|
||||
},
|
||||
"label": "",
|
||||
"name": "out_max",
|
||||
"type": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "shader"
|
||||
}
|
@ -166,7 +166,7 @@ func clear_material() -> void:
|
||||
func update_graph(generators, connections) -> Array:
|
||||
var rv = []
|
||||
for g in generators:
|
||||
var node = node_factory.create_node(g.get_type())
|
||||
var node = node_factory.create_node(g.get_template_name() if g.is_template() else "", g.get_type())
|
||||
if node != null:
|
||||
node.name = "node_"+g.name
|
||||
add_node(node)
|
||||
|
@ -462,7 +462,7 @@ func make_selected_nodes_editable() -> void:
|
||||
var selected_nodes = get_selected_nodes()
|
||||
if !selected_nodes.empty():
|
||||
for n in selected_nodes:
|
||||
if n.generator.toggle_editable():
|
||||
if n.generator.toggle_editable() and n.has_method("update_node"):
|
||||
n.update_node()
|
||||
|
||||
func add_to_user_library() -> void:
|
||||
|
@ -2,13 +2,16 @@ extends Node
|
||||
|
||||
var includes
|
||||
|
||||
func create_node(type) -> Node:
|
||||
func create_node(model : String, type : String) -> Node:
|
||||
var node_type = null
|
||||
var node = null
|
||||
var file_name = "res://material_maker/nodes/"+type+".tscn"
|
||||
var file_name = "res://material_maker/nodes/"+model+".tscn"
|
||||
if ! ResourceLoader.exists(file_name):
|
||||
file_name = "res://material_maker/nodes/"+type+".tscn"
|
||||
if ResourceLoader.exists(file_name):
|
||||
var node_type = load(file_name)
|
||||
if node_type != null:
|
||||
node = node_type.instance()
|
||||
node_type = load(file_name)
|
||||
if node_type != null:
|
||||
node = node_type.instance()
|
||||
if node == null:
|
||||
node = preload("res://material_maker/nodes/generic.tscn").instance()
|
||||
return node
|
||||
|
153
material_maker/nodes/levels.gd
Normal file
153
material_maker/nodes/levels.gd
Normal file
@ -0,0 +1,153 @@
|
||||
extends MMGraphNodeBase
|
||||
|
||||
class Cursor:
|
||||
extends Control
|
||||
|
||||
var color : Color
|
||||
var top : bool = true
|
||||
var position : float
|
||||
|
||||
|
||||
const WIDTH : int = 8
|
||||
const HEIGHT : int = 8
|
||||
|
||||
func _init(c, p, t = true):
|
||||
color = c
|
||||
position = p
|
||||
top = t
|
||||
|
||||
func _ready() -> void:
|
||||
rect_position = Vector2(position * get_parent().rect_size.x - 0.5*WIDTH, -2 if top else get_parent().rect_size.y+2-HEIGHT)
|
||||
rect_size = Vector2(WIDTH, HEIGHT)
|
||||
|
||||
func _draw() -> void:
|
||||
var polygon : PoolVector2Array
|
||||
if top:
|
||||
polygon = PoolVector2Array([Vector2(0, 0), Vector2(WIDTH/2, HEIGHT), Vector2(WIDTH, 0), Vector2(0, 0)])
|
||||
else:
|
||||
polygon = PoolVector2Array([Vector2(0, HEIGHT), Vector2(WIDTH/2, 0), Vector2(WIDTH, HEIGHT), Vector2(0, HEIGHT)])
|
||||
var c = color
|
||||
c.a = 1.0
|
||||
draw_colored_polygon(polygon, c)
|
||||
var outline_color = 0.0 if position > 0.5 else 1.0
|
||||
draw_polyline(polygon, Color(outline_color, outline_color, outline_color), 1.0, true)
|
||||
|
||||
func _gui_input(ev) -> void:
|
||||
if ev is InputEventMouseMotion && (ev.button_mask & 1) != 0:
|
||||
rect_position.x += ev.relative.x
|
||||
rect_position.x = min(max(-0.5*WIDTH, rect_position.x), get_parent().rect_size.x-0.5*WIDTH)
|
||||
var new_position = (rect_position.x+0.5*WIDTH)/get_parent().rect_size.x
|
||||
if new_position != position:
|
||||
position = new_position
|
||||
get_parent().get_parent().update_value(self, position)
|
||||
update()
|
||||
|
||||
func get_position() -> Vector2:
|
||||
return rect_position.x / (get_parent().rect_size.x - WIDTH)
|
||||
|
||||
var cursor_in_min : Cursor
|
||||
var cursor_in_mid : Cursor
|
||||
var cursor_in_max : Cursor
|
||||
var cursor_out_min : Cursor
|
||||
var cursor_out_max : Cursor
|
||||
|
||||
func _ready() -> void:
|
||||
var slot_color = mm_io_types.types["rgba"].color
|
||||
var slot_type = mm_io_types.types["rgba"].slot_type
|
||||
set_slot(0, true, slot_type, slot_color, true, slot_type, slot_color)
|
||||
cursor_in_min = Cursor.new(Color(0.0, 0.0, 0.0), 0.0)
|
||||
$Histogram.add_child(cursor_in_min)
|
||||
cursor_in_mid = Cursor.new(Color(0.5, 0.5, 0.5), 0.5)
|
||||
$Histogram.add_child(cursor_in_mid)
|
||||
cursor_in_max = Cursor.new(Color(1.0, 1.0, 1.0), 1.0)
|
||||
$Histogram.add_child(cursor_in_max)
|
||||
cursor_out_min = Cursor.new(Color(0.0, 0.0, 0.0), 0.0, false)
|
||||
$Histogram.add_child(cursor_out_min)
|
||||
cursor_out_max = Cursor.new(Color(1.0, 1.0, 1.0), 1.0, false)
|
||||
$Histogram.add_child(cursor_out_max)
|
||||
|
||||
func set_generator(g) -> void:
|
||||
.set_generator(g)
|
||||
generator.connect("parameter_changed", self, "on_parameter_changed")
|
||||
update_node()
|
||||
|
||||
func update_node() -> void:
|
||||
if has_node("NodeEditButtons"):
|
||||
var r = $NodeEditButtons
|
||||
remove_child(r)
|
||||
r.free()
|
||||
rect_size = Vector2(0, 0)
|
||||
if generator.is_editable():
|
||||
var edit_buttons = preload("res://material_maker/nodes/edit_buttons.tscn").instance()
|
||||
add_child(edit_buttons)
|
||||
edit_buttons.connect_buttons(self, "edit_generator", "load_generator", "save_generator")
|
||||
set_slot(edit_buttons.get_index(), false, 0, Color(0.0, 0.0, 0.0), false, 0, Color(0.0, 0.0, 0.0))
|
||||
|
||||
func on_parameter_changed(p, v) -> void:
|
||||
if p == "__input_changed__":
|
||||
var source = generator.get_source(0)
|
||||
var result = source.generator.render(source.output_index, 128, true)
|
||||
while result is GDScriptFunctionState:
|
||||
result = yield(result, "completed")
|
||||
result.copy_to_texture($ViewportImage/ColorRect.material.get_shader_param("tex"))
|
||||
result.release()
|
||||
|
||||
func set_parameter(n : String, v : float, d : float) -> void:
|
||||
var value = generator.get_parameter(n)
|
||||
match $Mode.selected:
|
||||
0:
|
||||
value.r = v
|
||||
value.g = v
|
||||
value.b = v
|
||||
value.a = d
|
||||
1:
|
||||
value.r = v
|
||||
2:
|
||||
value.g = v
|
||||
3:
|
||||
value.b = v
|
||||
4:
|
||||
value.a = v
|
||||
generator.set_parameter(n, value)
|
||||
|
||||
func update_value(control : Cursor, value : float) -> void:
|
||||
match control:
|
||||
cursor_in_min:
|
||||
set_parameter("in_min", value, 0)
|
||||
cursor_in_mid:
|
||||
set_parameter("in_mid", value, 0.5)
|
||||
cursor_in_max:
|
||||
set_parameter("in_max", value, 1)
|
||||
cursor_out_min:
|
||||
set_parameter("out_min", value, 0)
|
||||
cursor_out_max:
|
||||
set_parameter("out_max", value, 1)
|
||||
get_parent().send_changed_signal()
|
||||
|
||||
func edit_generator() -> void:
|
||||
if generator.has_method("edit"):
|
||||
generator.edit(self)
|
||||
|
||||
func update_generator(shader_model : Dictionary) -> void:
|
||||
generator.set_shader_model(shader_model)
|
||||
update_node()
|
||||
|
||||
func save_generator() -> void:
|
||||
var dialog = FileDialog.new()
|
||||
add_child(dialog)
|
||||
dialog.rect_min_size = Vector2(500, 500)
|
||||
dialog.access = FileDialog.ACCESS_FILESYSTEM
|
||||
dialog.mode = FileDialog.MODE_SAVE_FILE
|
||||
dialog.add_filter("*.mmg;Material Maker Generator")
|
||||
dialog.connect("file_selected", self, "do_save_generator")
|
||||
dialog.popup_centered()
|
||||
|
||||
func do_save_generator(file_name : String) -> void:
|
||||
var file = File.new()
|
||||
if file.open(file_name, File.WRITE) == OK:
|
||||
var data = generator.serialize()
|
||||
data.name = file_name.get_file().get_basename()
|
||||
data.node_position = { x=0, y=0 }
|
||||
file.store_string(JSON.print(data, "\t", true))
|
||||
file.close()
|
||||
mm_loader.update_predefined_generators()
|
209
material_maker/nodes/levels.tscn
Normal file
209
material_maker/nodes/levels.tscn
Normal file
@ -0,0 +1,209 @@
|
||||
[gd_scene load_steps=14 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/nodes/levels.gd" type="Script" id=1]
|
||||
|
||||
[sub_resource type="Shader" id=1]
|
||||
code = "shader_type canvas_item;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
void fragment() {
|
||||
COLOR = texture(tex, UV);
|
||||
}
|
||||
"
|
||||
|
||||
[sub_resource type="ImageTexture" id=14]
|
||||
resource_local_to_scene = true
|
||||
flags = 0
|
||||
flags = 0
|
||||
|
||||
[sub_resource type="ShaderMaterial" id=4]
|
||||
resource_local_to_scene = true
|
||||
shader = SubResource( 1 )
|
||||
shader_param/tex = SubResource( 14 )
|
||||
|
||||
[sub_resource type="Shader" id=5]
|
||||
code = "shader_type canvas_item;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
void fragment() {
|
||||
vec4 sum = vec4(0.0);
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
sum += step(abs(texture(tex, vec2(UV.x, float(i)/127.0))-UV.y), vec4(0.02));
|
||||
}
|
||||
COLOR = vec4(sum.xyz/255.0, 1.0);
|
||||
}
|
||||
"
|
||||
|
||||
[sub_resource type="ViewportTexture" id=6]
|
||||
viewport_path = NodePath("ViewportImage")
|
||||
|
||||
[sub_resource type="ShaderMaterial" id=7]
|
||||
resource_local_to_scene = true
|
||||
shader = SubResource( 5 )
|
||||
shader_param/tex = SubResource( 6 )
|
||||
|
||||
[sub_resource type="Shader" id=8]
|
||||
code = "shader_type canvas_item;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
void fragment() {
|
||||
vec4 sum = vec4(0.0);
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
sum += texture(tex, vec2(float(i)/127.0, UV.x));
|
||||
}
|
||||
COLOR = vec4(sum.xyz/255.0, 1.0);
|
||||
}"
|
||||
|
||||
[sub_resource type="ViewportTexture" id=9]
|
||||
viewport_path = NodePath("ViewportHistogram1")
|
||||
|
||||
[sub_resource type="ShaderMaterial" id=10]
|
||||
resource_local_to_scene = true
|
||||
shader = SubResource( 8 )
|
||||
shader_param/tex = SubResource( 9 )
|
||||
|
||||
[sub_resource type="Shader" id=11]
|
||||
code = "shader_type canvas_item;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
void fragment() {
|
||||
if (abs(fract(UV.y+0.05)) < 0.1) {
|
||||
COLOR = vec4(vec3(UV.x), 1.0);
|
||||
} else {
|
||||
vec4 highest = vec4(0.0);
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
highest = max(highest, texture(tex, vec2(float(i)/128.0, 0.0)));
|
||||
}
|
||||
vec4 value = 0.5*(texture(tex, vec2(max(0.0, UV.x-0.025), 0.0))+texture(tex, vec2(min(1.0, UV.x+0.025), 0.0)));
|
||||
COLOR = vec4(step(vec4(0.95-UV.y)*highest/0.9, value).xyz, 1.0);
|
||||
}
|
||||
}"
|
||||
|
||||
[sub_resource type="ViewportTexture" id=12]
|
||||
viewport_path = NodePath("ViewportHistogram2")
|
||||
|
||||
[sub_resource type="ShaderMaterial" id=13]
|
||||
resource_local_to_scene = true
|
||||
shader = SubResource( 11 )
|
||||
shader_param/tex = SubResource( 12 )
|
||||
|
||||
[node name="Tones" type="GraphNode"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -39.6668
|
||||
margin_top = 14.4243
|
||||
margin_right = -1095.67
|
||||
margin_bottom = -579.576
|
||||
title = "Tones"
|
||||
show_close = true
|
||||
slot/0/left_enabled = true
|
||||
slot/0/left_type = 0
|
||||
slot/0/left_color = Color( 0, 0.396078, 1, 1 )
|
||||
slot/0/right_enabled = true
|
||||
slot/0/right_type = 0
|
||||
slot/0/right_color = Color( 0, 0.415686, 1, 1 )
|
||||
slot/1/left_enabled = false
|
||||
slot/1/left_type = 0
|
||||
slot/1/left_color = Color( 1, 1, 1, 1 )
|
||||
slot/1/right_enabled = false
|
||||
slot/1/right_type = 0
|
||||
slot/1/right_color = Color( 1, 1, 1, 1 )
|
||||
slot/2/left_enabled = false
|
||||
slot/2/left_type = 0
|
||||
slot/2/left_color = Color( 1, 1, 1, 1 )
|
||||
slot/2/right_enabled = false
|
||||
slot/2/right_type = 0
|
||||
slot/2/right_color = Color( 1, 1, 1, 1 )
|
||||
slot/3/left_enabled = false
|
||||
slot/3/left_type = 0
|
||||
slot/3/left_color = Color( 1, 1, 1, 1 )
|
||||
slot/3/right_enabled = false
|
||||
slot/3/right_type = 0
|
||||
slot/3/right_color = Color( 1, 1, 1, 1 )
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="ViewportImage" type="Viewport" parent="."]
|
||||
size = Vector2( 256, 256 )
|
||||
disable_3d = true
|
||||
keep_3d_linear = true
|
||||
usage = 0
|
||||
render_target_v_flip = true
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="ViewportImage"]
|
||||
material = SubResource( 4 )
|
||||
margin_right = 256.0
|
||||
margin_bottom = 128.0
|
||||
rect_min_size = Vector2( 256, 256 )
|
||||
|
||||
[node name="ViewportHistogram1" type="Viewport" parent="."]
|
||||
size = Vector2( 128, 128 )
|
||||
disable_3d = true
|
||||
keep_3d_linear = true
|
||||
usage = 0
|
||||
render_target_v_flip = true
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="ViewportHistogram1"]
|
||||
material = SubResource( 7 )
|
||||
margin_right = 128.0
|
||||
margin_bottom = 128.0
|
||||
rect_min_size = Vector2( 128, 128 )
|
||||
|
||||
[node name="ViewportHistogram2" type="Viewport" parent="."]
|
||||
size = Vector2( 128, 2 )
|
||||
disable_3d = true
|
||||
keep_3d_linear = true
|
||||
usage = 0
|
||||
render_target_v_flip = true
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="ViewportHistogram2"]
|
||||
material = SubResource( 10 )
|
||||
margin_right = 128.0
|
||||
margin_bottom = 2.0
|
||||
rect_min_size = Vector2( 128, 2 )
|
||||
|
||||
[node name="Mode" type="OptionButton" parent="."]
|
||||
margin_left = 16.0
|
||||
margin_top = 24.0
|
||||
margin_right = 208.0
|
||||
margin_bottom = 44.0
|
||||
text = "Luminance"
|
||||
items = [ "Luminance", null, false, 0, null, "Red", null, false, 1, null, "Green", null, false, 2, null, "Blue", null, false, 3, null, "Alpha", null, false, 4, null ]
|
||||
selected = 0
|
||||
|
||||
[node name="Spacer1" type="Control" parent="."]
|
||||
margin_left = 16.0
|
||||
margin_top = 45.0
|
||||
margin_right = 208.0
|
||||
margin_bottom = 49.0
|
||||
rect_min_size = Vector2( 0, 4 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Histogram" type="ColorRect" parent="."]
|
||||
material = SubResource( 13 )
|
||||
margin_left = 16.0
|
||||
margin_top = 50.0
|
||||
margin_right = 208.0
|
||||
margin_bottom = 178.0
|
||||
rect_min_size = Vector2( 192, 128 )
|
||||
|
||||
[node name="Spacer2" type="Control" parent="."]
|
||||
margin_left = 16.0
|
||||
margin_top = 179.0
|
||||
margin_right = 208.0
|
||||
margin_bottom = 183.0
|
||||
rect_min_size = Vector2( 0, 4 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
Loading…
Reference in New Issue
Block a user