Updated gradient with a choice of 4 interpolation options

This commit is contained in:
RodZill4 2019-10-30 22:57:51 +01:00
parent 47fa19c65f
commit f664a54e4b
4 changed files with 160 additions and 33 deletions

View File

@ -10,9 +10,9 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
width="128"
height="64"
viewBox="0 0 64 64"
viewBox="0 0 128 64"
version="1.1"
id="svg8"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
@ -49,8 +49,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="14.304427"
inkscape:cx="23.663017"
inkscape:cy="5.4603811"
inkscape:cx="79.150133"
inkscape:cy="47.863625"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@ -358,5 +358,40 @@
id="path4561"
d="m 33.500409,335.78733 4.34961,-0.0488 0.123047,-6.82227 h 4.27539 l 0.125,6.82227 4.34961,0.0488 -6.611328,6.8457 z"
style="fill:#ffffff;fill-opacity:0.84322037;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.77952766;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 67.601449,292.54414 5.38295,-1e-5"
id="path4570"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.77952766;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 73.823299,283.52594 9.857089,-0.0699"
id="path4572"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.77952766;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 85.288282,289.32835 7.55011,-0.0699"
id="path4574"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#f6f6f6;stroke-width:3.77952766;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 98.850517,292.96359 8.668643,-9.57745 9.36773,9.92699 8.24919,-6.78111"
id="path4576"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#f6f6f6;stroke-width:3.77952766;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 67.110738,309.04251 c 3.472118,0.55927 4.555698,-9.96194 8.319101,-9.85708 3.763403,0.10486 4.678964,9.98562 9.36773,9.92699 4.552323,-0.0569 5.040651,-6.78111 8.24919,-6.78111"
id="path4576-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="czsc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#f6f6f6;stroke-width:3.77952766;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 99.268615,309.04251 c 0,0 4.241035,-9.53142 8.668645,-9.57745 4.42761,-0.046 4.9669,9.84949 9.36773,9.92699 3.55898,0.0627 8.24919,-6.78111 8.24919,-6.78111"
id="path4576-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="czsc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -6,6 +6,7 @@ class CustomSorter:
return a.v < b.v
var points = [ { v=0.0, c=Color(0.0, 0.0, 0.0, 0.0) }, { v=1.0, c=Color(1.0, 1.0, 1.0, 1.0) } ]
var interpolation = 1
var sorted = true
func to_string() -> String:
@ -59,22 +60,69 @@ func get_shader(name) -> String:
sort()
var shader
shader = "vec4 "+name+"(float x) {\n"
if points.size() > 0:
shader += " if (x < %.9f) {\n" % points[0].v
shader += " return "+gcis(points[0].c)+";\n"
var s = points.size()-1
for i in range(s):
var p0 = points[i].v
var c0 = points[i].c
var p1mp0 = points[i+1].v-p0
var c1mc0 = points[i+1].c-c0
if p1mp0 > 0:
shader += " } else if (x < %.9f) {\n" % points[i+1].v
shader += " return %s+x*%s;\n" % [gcis(c0-c1mc0*(p0/p1mp0)), gcis(c1mc0/p1mp0)]
shader += " }\n"
shader += " return "+gcis(points[s].c)+";\n"
else:
shader += " return vec4(0.0, 0.0, 0.0, 1.0);\n"
match interpolation:
0:
if points.size() > 0:
shader += " if (x < %.9f) {\n" % (0.5*(points[0].v + points[1].v))
shader += " return "+gcis(points[0].c)+";\n"
var s = points.size()-1
for i in range(s):
var p0 = points[i].v
var c0 = points[i].c
var p1mp0 = points[i+1].v-p0
var c1mc0 = points[i+1].c-c0
if p1mp0 > 0:
shader += " } else if (x < %.9f) {\n" % (0.5*(points[i].v + points[i+1].v))
shader += " return "+gcis(points[i].c)+";\n"
shader += " }\n"
shader += " return "+gcis(points[s].c)+";\n"
else:
shader += " return vec4(0.0, 0.0, 0.0, 1.0);\n"
1, 2:
if points.size() > 0:
shader += " if (x < %.9f) {\n" % points[0].v
shader += " return "+gcis(points[0].c)+";\n"
var s = points.size()-1
for i in range(s):
var p1mp0 = points[i+1].v-points[i].v
if p1mp0 > 0:
shader += " } else if (x < %.9f) {\n" % points[i+1].v
var function = "(" if interpolation == 1 else "0.5-0.5*cos(3.14159265359*"
shader += " return mix(%s, %s, %s(x-%.9f)/%.9f));\n" % [ gcis(points[i].c), gcis(points[i+1].c), function, points[i].v, p1mp0 ]
shader += " }\n"
shader += " return "+gcis(points[s].c)+";\n"
else:
shader += " return vec4(0.0, 0.0, 0.0, 1.0);\n"
3:
if points.size() > 0:
shader += " if (x < %.9f) {\n" % points[0].v
shader += " return "+gcis(points[0].c)+";\n"
var s = points.size()-1
for i in range(s):
var p1mp0 = points[i+1].v-points[i].v
if p1mp0 > 0:
shader += " } else if (x < %.9f) {\n" % points[i+1].v
var dx : String = "(x-%.9f)/%.9f" % [ points[i].v, p1mp0 ]
var b : String = "mix(%s, %s, %s)" % [ gcis(points[i].c), gcis(points[i+1].c), dx ]
if i > 0 and points[i-1].v < points[i].v:
var a : String = "mix(%s, %s, (x-%.9f)/%.9f)" % [ gcis(points[i-1].c), gcis(points[i].c), points[i-1].v, points[i].v-points[i-1].v ]
if i < s-1 and points[i+1].v < points[i+2].v:
var c : String = "mix(%s, %s, (x-%.9f)/%.9f)" % [ gcis(points[i+1].c), gcis(points[i+2].c), points[i+1].v, points[i+2].v-points[i+1].v ]
var ac : String = "mix("+a+", "+c+", 0.5-0.5*cos(3.14159265359*"+dx+"))"
shader += " return 0.5*("+b+" + "+ac+");\n"
else:
shader += " return mix("+a+", "+b+", 0.5+0.5*"+dx+");\n"
elif i < s-1 and points[i+1].v < points[i+2].v:
var c : String = "mix(%s, %s, (x-%.9f)/%.9f)" % [ gcis(points[i+1].c), gcis(points[i+2].c), points[i+1].v, points[i+2].v-points[i+1].v ]
shader += " return mix("+c+", "+b+", 1.0-0.5*"+dx+");\n"
else:
shader += " return "+b+";\n"
shader += " }\n"
shader += " return "+gcis(points[s].c)+";\n"
else:
shader += " return vec4(0.0, 0.0, 0.0, 1.0);\n"
_:
print("interpolation: "+str(interpolation))
shader += "}\n"
return shader
@ -83,7 +131,7 @@ func serialize() -> Dictionary:
var rv = []
for p in points:
rv.append({ pos=p.v, r=p.c.r, g=p.c.g, b=p.c.b, a=p.c.a })
rv = { type="Gradient", points=rv }
rv = { type="Gradient", points=rv, interpolation=interpolation }
return rv
func deserialize(v) -> void:
@ -96,6 +144,10 @@ func deserialize(v) -> void:
for i in v.points:
if !i.has("a"): i.a = 1.0
add_point(i.pos, Color(i.r, i.g, i.b, i.a))
if v.has("interpolation"):
interpolation = int(v.interpolation)
else:
interpolation = 1
elif typeof(v) == TYPE_OBJECT and v.get_script() == get_script():
clear()
for p in v.points:

View File

@ -61,13 +61,14 @@ func set_value(v) -> void:
c.free()
for p in value.points:
add_cursor(p.v*(rect_size.x-GradientCursor.WIDTH), p.c)
$Interpolation.selected = value.interpolation
update_shader()
func update_value() -> void:
value.clear()
for p in get_children():
if p != $Gradient and p != $Background:
value.add_point(p.rect_position.x/(rect_size.x-GradientCursor.WIDTH), p.color)
for c in get_children():
if c is GradientCursor:
value.add_point(c.rect_position.x/(rect_size.x-GradientCursor.WIDTH), c.color)
update_shader()
func add_cursor(x, color) -> void:
@ -108,9 +109,10 @@ func _on_Popup_popup_hide() -> void:
# Calculating a color from the gradient and generating the shader
func get_sorted_cursors() -> Array:
var array = get_children()
array.erase($Gradient)
array.erase($Background)
var array = []
for c in get_children():
if c is GradientCursor:
array.append(c)
array.sort_custom(GradientCursor, "sort")
return array
@ -124,3 +126,7 @@ func update_shader() -> void:
shader += "void fragment() { COLOR = gradient(UV.x); }"
$Gradient.material.shader.set_code(shader)
emit_signal("updated", value)
func _on_Interpolation_item_selected(ID):
value.interpolation = ID
update_shader()

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=7 format=2]
[gd_scene load_steps=12 format=2]
[ext_resource path="res://addons/material_maker/widgets/gradient_editor.gd" type="Script" id=1]
[ext_resource path="res://addons/material_maker/icons/icons.svg" type="Texture" id=2]
[sub_resource type="Shader" id=1]
code = "shader_type canvas_item;
@ -12,21 +13,43 @@ void fragment() {
[sub_resource type="ShaderMaterial" id=2]
shader = SubResource( 1 )
[sub_resource type="Shader" id=6]
[sub_resource type="Shader" id=3]
code = "shader_type canvas_item;
vec4 gradient(float x) {
if (x < 0.000000000) {
return vec4(0.000000000,0.000000000,0.000000000,0.000000000);
} else if (x < 1.000000000) {
return (mix(vec4(0.000000000,0.000000000,0.000000000,0.000000000), vec4(1.000000000,1.000000000,1.000000000,1.000000000), (x-0.000000000)/1.000000000));
}
return vec4(0.000000000,0.000000000,0.000000000,0.000000000);
return vec4(1.000000000,1.000000000,1.000000000,1.000000000);
}
void fragment() { COLOR = gradient(UV.x); }"
[sub_resource type="ShaderMaterial" id=7]
shader = SubResource( 6 )
[sub_resource type="ShaderMaterial" id=4]
shader = SubResource( 3 )
[sub_resource type="Theme" id=5]
[sub_resource type="AtlasTexture" id=6]
flags = 4
atlas = ExtResource( 2 )
region = Rect2( 96, 0, 32, 16 )
[sub_resource type="AtlasTexture" id=7]
flags = 4
atlas = ExtResource( 2 )
region = Rect2( 64, 0, 32, 16 )
[sub_resource type="AtlasTexture" id=8]
flags = 4
atlas = ExtResource( 2 )
region = Rect2( 64, 16, 32, 16 )
[sub_resource type="AtlasTexture" id=9]
flags = 4
atlas = ExtResource( 2 )
region = Rect2( 96, 16, 32, 16 )
[node name="Control" type="Control"]
margin_right = 120.0
margin_bottom = 30.0
@ -43,7 +66,7 @@ rect_min_size = Vector2( 112, 17 )
mouse_filter = 2
[node name="Gradient" type="ColorRect" parent="."]
material = SubResource( 7 )
material = SubResource( 4 )
anchor_right = 1.0
margin_left = 4.0
margin_right = -4.0
@ -64,4 +87,15 @@ margin_top = 4.0
margin_right = 4.0
margin_bottom = 4.0
rect_scale = Vector2( 0.75, 0.75 )
[node name="Interpolation" type="OptionButton" parent="."]
margin_left = 0.418457
margin_top = -2.90374
margin_right = 73.4185
margin_bottom = 19.0963
rect_scale = Vector2( 0.5, 0.5 )
icon = SubResource( 6 )
items = [ "", SubResource( 7 ), false, 0, null, "", SubResource( 6 ), false, 1, null, "", SubResource( 8 ), false, 2, null, "", SubResource( 9 ), false, 3, null ]
selected = 1
[connection signal="popup_hide" from="Gradient/Popup" to="." method="_on_Popup_popup_hide"]
[connection signal="item_selected" from="Interpolation" to="." method="_on_Interpolation_item_selected"]