more refactoring, added combine, emboss, export nodes

- Added a combine node that assembles channels into colors
- Added an emboss node
- Added an export node that generates additional file when exporting the material
- Refactored convolution related code
This commit is contained in:
Rodolphe Suescun 2018-08-14 15:09:46 +02:00
parent 18015aec93
commit d1b8f12b5b
18 changed files with 478 additions and 88 deletions

View File

@ -165,7 +165,9 @@ func do_save_file(filename):
func export_textures(size = 512): func export_textures(size = 512):
if save_path != null: if save_path != null:
var prefix = save_path.left(save_path.rfind(".")) var prefix = save_path.left(save_path.rfind("."))
$Material.export_textures(prefix) for c in get_children():
if c is GraphNode && c.has_method("export_textures"):
c.export_textures(prefix)
func send_changed_signal(): func send_changed_signal():
set_need_save(true) set_need_save(true)

View File

@ -7,6 +7,10 @@
"tree_item":"Filters", "tree_item":"Filters",
"collapsed":false "collapsed":false
}, },
{
"tree_item":"Miscellaneous",
"collapsed":false
},
{ {
"tree_item":"Generators/Image", "tree_item":"Generators/Image",
"type":"image", "type":"image",
@ -65,6 +69,15 @@
"type":"blur", "type":"blur",
"sigma":1.0 "sigma":1.0
}, },
{
"tree_item":"Filters/Combine",
"type":"combine"
},
{
"tree_item":"Filters/Emboss",
"type":"emboss",
"direction":0
},
{ {
"tree_item":"Filters/Normal map", "tree_item":"Filters/Normal map",
"type":"normal_map", "type":"normal_map",
@ -122,5 +135,9 @@
"r": 0 "r": 0
} }
] ]
},
{
"tree_item":"Miscellaneous/Export",
"type":"export"
} }
]} ]}

View File

@ -107,7 +107,7 @@ func close_material():
func export_material(): func export_material():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control() var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
if graph_edit != null: if graph_edit != null:
graph_edit.export_textures(1024) graph_edit.export_textures(2048)
func quit(): func quit():
get_tree().quit() get_tree().quit()

View File

@ -4,7 +4,7 @@
[ext_resource path="res://addons/procedural_material/library.gd" type="Script" id=2] [ext_resource path="res://addons/procedural_material/library.gd" type="Script" id=2]
[ext_resource path="res://addons/procedural_material/preview.tscn" type="PackedScene" id=3] [ext_resource path="res://addons/procedural_material/preview.tscn" type="PackedScene" id=3]
[node name="MainWindow" type="Panel" index="0"] [node name="MainWindow" type="Panel"]
anchor_left = 0.0 anchor_left = 0.0
anchor_top = 0.0 anchor_top = 0.0

View File

@ -207,6 +207,37 @@ func _rerender():
# Generic code for convolution nodes # Generic code for convolution nodes
func get_convolution_shader(convolution):
var shader_code
shader_code = "shader_type canvas_item;\n"
shader_code += "uniform sampler2D input_tex;\n"
shader_code += "void fragment() {\n"
shader_code += "vec3 color = vec3(0.0);\n"
for dy in range(-convolution.y, convolution.y+1):
for dx in range(-convolution.x, convolution.x+1):
var i = (2*convolution.x+1)*(dy+convolution.y)+dx+convolution.x
var coef = convolution.kernel[i]
if typeof(coef) == TYPE_INT:
coef = float(coef)
if typeof(coef) == TYPE_REAL:
coef = Vector3(coef, coef, coef)
if typeof(coef) != TYPE_VECTOR3 or coef == Vector3(0, 0, 0):
continue
shader_code += "color += vec3(%.9f, %.9f, %.9f) * textureLod(input_tex, UV+vec2(%.9f, %.9f), %.9f).rgb;\n" % [ coef.x, coef.y, coef.z, dx*convolution.epsilon, dy*convolution.epsilon, convolution.epsilon ]
if convolution.has("scale_before_normalize"):
shader_code += "color *= %.9f;\n" % [ convolution.scale_before_normalize ]
if convolution.has("translate_before_normalize"):
shader_code += "color += vec3(%.9f, %.9f, %.9f);\n" % [ convolution.translate_before_normalize.x, convolution.translate_before_normalize.y, convolution.translate_before_normalize.z ]
if convolution.has("normalize") and convolution.normalize:
shader_code += "color = normalize(color);\n"
if convolution.has("scale"):
shader_code += "color *= %.9f;\n" % [ convolution.scale ]
if convolution.has("translate"):
shader_code += "color += vec3(%.9f, %.9f, %.9f);\n" % [ convolution.translate.x, convolution.translate.y, convolution.translate.z ]
shader_code += "COLOR = vec4(color, 1.0);\n"
shader_code += "}\n"
return shader_code;
func get_shader_code_convolution(src, convolution, uv): func get_shader_code_convolution(src, convolution, uv):
var rv = { defs="", code="" } var rv = { defs="", code="" }
var variant_index = generated_variants.find(uv) var variant_index = generated_variants.find(uv)
@ -218,38 +249,6 @@ func get_shader_code_convolution(src, convolution, uv):
generated_variants.append(uv) generated_variants.append(uv)
var inputs_code = "" var inputs_code = ""
var code = "vec3 %s_%d_rgb = " % [ name, variant_index ] var code = "vec3 %s_%d_rgb = " % [ name, variant_index ]
if convolution.has("translate"):
code += "vec3(%.9f, %.9f, %.9f)+" % [ convolution.translate.x, convolution.translate.y, convolution.translate.z ]
if convolution.has("scale"):
code += "%.9f*" % [ convolution.scale ]
if convolution.has("normalize") and convolution.normalize:
code += "normalize"
code += "("
if convolution.has("translate_before_normalize"):
code += "vec3(%.9f, %.9f, %.9f)+" % [ convolution.translate_before_normalize.x, convolution.translate_before_normalize.y, convolution.translate_before_normalize.z ]
if convolution.has("scale_before_normalize"):
code += "%.9f*" % [ convolution.scale_before_normalize ]
code += "("
var first = true
for dy in range(-2, 3):
for dx in range(-2, 3):
var i = 5*(dy+2)+dx+2
var coef = convolution.kernel[i]
if typeof(coef) == TYPE_REAL:
coef = Vector3(coef, coef, coef)
if typeof(coef) != TYPE_VECTOR3 or coef == Vector3(0, 0, 0):
continue
var src_code = src.get_shader_code(uv+"+vec2(%.9f, %.9f)" % [ dx*convolution.epsilon, dy*convolution.epsilon ])
if need_defs:
rv.defs = src_code.defs
need_defs = false
inputs_code += src_code.code
if !first:
code += "+"
else:
first = false
code += "vec3(%.9f, %.9f, %.9f)*(%s)"% [ coef.x, coef.y, coef.z, src_code.rgb ]
code += "));"
rv.code += inputs_code + code rv.code += inputs_code + code
rv.rgb = name+"_"+str(variant_index)+"_rgb" rv.rgb = name+"_"+str(variant_index)+"_rgb"
return rv return rv

View File

@ -15,34 +15,31 @@ func _ready():
final_texture = ImageTexture.new() final_texture = ImageTexture.new()
initialize_properties([ $HBoxContainer1/epsilon, $HBoxContainer2/sigma ]) initialize_properties([ $HBoxContainer1/epsilon, $HBoxContainer2/sigma ])
func get_gaussian_blur_shader(v): func get_gaussian_blur_shader(horizontal):
var shader_code var convolution = { x=0, y=0, kernel=[], epsilon=epsilon }
var kernel_size = 10 var kernel_size = 10
var kernel = [] if horizontal:
kernel.resize(2*kernel_size+1) convolution.x = kernel_size
shader_code = "shader_type canvas_item;\n" else:
shader_code += "uniform sampler2D input_tex;\n" convolution.y = kernel_size
shader_code += "void fragment() {\n" convolution.kernel.resize(2*kernel_size+1)
shader_code += "vec3 color = vec3(0.0);"
var sum = 0 var sum = 0
for x in range(-kernel_size, kernel_size+1): for x in range(-kernel_size, kernel_size+1):
var coef = exp(-0.5*(pow((x)/sigma, 2.0))) / (2.0*PI*sigma*sigma) var coef = exp(-0.5*(pow((x)/sigma, 2.0))) / (2.0*PI*sigma*sigma)
kernel[x+kernel_size] = coef convolution.kernel[x+kernel_size] = coef
sum += coef sum += coef
for x in range(-kernel_size, kernel_size+1): for x in range(-kernel_size, kernel_size+1):
shader_code += "color += %.9f*textureLod(input_tex, UV+vec2(%.9f, %.9f), %.9f).rgb;\n" % [ kernel[x+kernel_size] / sum, x*v.x, x*v.y, epsilon ] convolution.kernel[x+kernel_size] /= sum
shader_code += "COLOR = vec4(color, 1.0);\n" return get_convolution_shader(convolution)
shader_code += "}\n"
return shader_code;
func _rerender(): func _rerender():
get_parent().precalculate_shader(input_shader, get_source().get_textures(), 4096, input_texture, self, "pass_1", []) get_parent().precalculate_shader(input_shader, get_source().get_textures(), 4096, input_texture, self, "pass_1", [])
func pass_1(): func pass_1():
get_parent().precalculate_shader(get_gaussian_blur_shader(Vector2(epsilon, 0)), { input=input_texture}, 4096, mid_texture, self, "pass_2", []) get_parent().precalculate_shader(get_gaussian_blur_shader(true), { input=input_texture}, 4096, mid_texture, self, "pass_2", [])
func pass_2(): func pass_2():
get_parent().precalculate_shader(get_gaussian_blur_shader(Vector2(0, epsilon)), { input=mid_texture}, 4096, final_texture, self, "rerender_targets", []) get_parent().precalculate_shader(get_gaussian_blur_shader(false), { input=mid_texture}, 4096, final_texture, self, "rerender_targets", [])
func get_textures(): func get_textures():
var list = {} var list = {}
@ -65,24 +62,3 @@ func _get_shader_code(uv):
rv.code = "vec3 "+name+"_"+str(variant_index)+"_rgb = texture("+name+"_tex, "+uv+").rgb;\n" rv.code = "vec3 "+name+"_"+str(variant_index)+"_rgb = texture("+name+"_tex, "+uv+").rgb;\n"
rv.rgb = name+"_"+str(variant_index)+"_rgb" rv.rgb = name+"_"+str(variant_index)+"_rgb"
return rv return rv
func __get_shader_code(uv):
var convolution = {
kernel=[
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0
],
epsilon=epsilon
}
var sum = 0
for x in range(-2, 3):
for y in range(-2, 3):
var coef = exp(-0.5*(pow((x-2)/sigma, 2.0) + pow((y-2)/sigma, 2.0))) / (2.0*PI*sigma*sigma)
convolution.kernel[x+2+5*(y+2)] = coef
sum += coef
for i in range(25):
convolution.kernel[i] /= sum
return get_shader_code_convolution(convolution, uv)

View File

@ -5,7 +5,7 @@
[sub_resource type="Theme" id=1] [sub_resource type="Theme" id=1]
[node name="Blur" type="GraphNode"] [node name="Blur" type="GraphNode" index="0"]
anchor_left = 0.0 anchor_left = 0.0
anchor_top = 0.0 anchor_top = 0.0

View File

@ -0,0 +1,31 @@
tool
extends "res://addons/procedural_material/node_base.gd"
func _get_shader_code(uv):
var rv = { defs="", code="" }
var src0 = get_source(0)
var src1 = get_source(1)
var src2 = get_source(2)
var src0_code = { defs="", code="", f="0.0" }
var src1_code = { defs="", code="", f="0.0" }
var src2_code = { defs="", code="", f="0.0" }
if src0 != null:
src0_code = src0.get_shader_code(uv)
if src1 != null:
src1_code = src1.get_shader_code(uv)
if src2 != null:
src2_code = src2.get_shader_code(uv)
if generated_variants.empty():
rv.defs = src0_code.defs;
rv.defs += src1_code.defs;
rv.defs += src2_code.defs;
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
generated_variants.append(uv)
rv.code = src0_code.code
rv.code += src1_code.code
rv.code += src2_code.code
rv.code += "vec3 %s_%d_rgb = vec3(%s, %s, %s);\n" % [ name, variant_index, src0_code.f, src1_code.f, src2_code.f ]
rv.rgb = "%s_%d_rgb" % [ name, variant_index ]
return rv

View File

@ -0,0 +1,116 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/procedural_material/nodes/combine.gd" type="Script" id=1]
[sub_resource type="Theme" id=1]
[node name="Combine" type="GraphNode" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 204.0
margin_top = 72.0
margin_right = 306.0
margin_bottom = 145.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = SubResource( 1 )
title = "Combine"
offset = Vector2( 0, 0 )
show_close = true
resizable = false
selected = false
comment = false
overlay = 0
slot/0/left_enabled = true
slot/0/left_type = 0
slot/0/left_color = Color( 0.5, 0.5, 1, 1 )
slot/0/right_enabled = true
slot/0/right_type = 0
slot/0/right_color = Color( 0.5, 0.5, 1, 1 )
slot/1/left_enabled = true
slot/1/left_type = 0
slot/1/left_color = Color( 0.498039, 0.498039, 1, 1 )
slot/1/right_enabled = false
slot/1/right_type = 0
slot/1/right_color = Color( 0.498039, 0.498039, 1, 1 )
slot/2/left_enabled = true
slot/2/left_type = 0
slot/2/left_color = Color( 0.498039, 0.498039, 1, 1 )
slot/2/right_enabled = false
slot/2/right_type = 0
slot/2/right_color = Color( 0.498039, 0.498039, 1, 1 )
script = ExtResource( 1 )
_sections_unfolded = [ "Theme", "slot", "slot/0", "slot/1", "slot/2" ]
[node name="R" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0
margin_top = 24.0
margin_right = 86.0
margin_bottom = 38.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "R"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="G" type="Label" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0
margin_top = 38.0
margin_right = 86.0
margin_bottom = 52.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "G"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="B" type="Label" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0
margin_top = 53.0
margin_right = 86.0
margin_bottom = 67.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "B"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1

View File

@ -0,0 +1,60 @@
tool
extends "res://addons/procedural_material/node_base.gd"
var direction = 0
var input_shader = ""
var input_texture
var final_texture
const CONVOLUTION = {
x=1,
y=1,
kernel=[
1, 2, 1,
0, 0, 0,
-1, -2, -1
],
epsilon=1.0/1024,
scale=0.5,
translate=Vector3(0.5, 0.5, 0.5)
}
const INDICES = [ 0, 1, 2, 5, 8, 7, 6, 3 ]
const COEFS = [ 1, 2, 1, 0, -1, -2, -1, 0 ]
func _ready():
input_texture = ImageTexture.new()
final_texture = ImageTexture.new()
initialize_properties([ $direction ])
func _rerender():
get_parent().precalculate_shader(input_shader, get_source().get_textures(), 1024, input_texture, self, "pass_1", [])
func pass_1():
var convolution = CONVOLUTION
for i in range(8):
convolution.kernel[INDICES[i]] = COEFS[(i+8-int(direction))%8]
get_parent().precalculate_shader(get_convolution_shader(convolution), {input=input_texture}, 1024, final_texture, self, "rerender_targets", [])
func get_textures():
var list = {}
list[name] = final_texture
return list
func _get_shader_code(uv):
var rv = { defs="", code="" }
var src = get_source()
if src == null:
return rv
input_shader = do_generate_shader(src.get_shader_code("UV"))
_rerender()
if generated_variants.empty():
rv.defs = "uniform sampler2D "+name+"_tex;\n"
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
generated_variants.append(uv)
rv.code = "vec3 "+name+"_"+str(variant_index)+"_rgb = texture("+name+"_tex, "+uv+").rgb;\n"
rv.rgb = name+"_"+str(variant_index)+"_rgb"
return rv

View File

@ -0,0 +1,70 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/procedural_material/nodes/emboss.gd" type="Script" id=1]
[sub_resource type="Theme" id=1]
[node name="Emboss" type="GraphNode" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 1.0
margin_top = 1.0
margin_right = 124.0
margin_bottom = 54.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = SubResource( 1 )
title = "Emboss"
offset = Vector2( 0, 0 )
show_close = true
resizable = false
selected = false
comment = false
overlay = 0
slot/0/left_enabled = true
slot/0/left_type = 0
slot/0/left_color = Color( 0.5, 0.5, 1, 1 )
slot/0/right_enabled = true
slot/0/right_type = 0
slot/0/right_color = Color( 0.5, 0.5, 1, 1 )
script = ExtResource( 1 )
_sections_unfolded = [ "Theme", "slot", "slot/0" ]
[node name="direction" type="OptionButton" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0
margin_top = 24.0
margin_right = 107.0
margin_bottom = 44.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
action_mode = 0
enabled_focus_mode = 2
shortcut = null
group = null
text = "Objet 0"
flat = false
align = 0
items = [ "N", null, false, 0, null, "NE", null, false, 1, null, "E", null, false, 2, null, "SE", null, false, 3, null, "S", null, false, 4, null, "SW", null, false, 5, null, "W", null, false, 6, null, "NW", null, false, 7, null ]
selected = 0
_sections_unfolded = [ "Caret", "Placeholder" ]

View File

@ -0,0 +1,27 @@
tool
extends "res://addons/procedural_material/node_base.gd"
func _ready():
pass
func _get_shader_code(uv):
var rv = { defs="", code="", f="0.0" }
var src = get_source()
if src != null:
rv = src.get_shader_code(uv)
return rv
func export_textures(prefix):
var suffix = $Suffix.text
if suffix != "":
get_parent().export_texture(get_source(), prefix+"_"+suffix+".png", 1024)
func serialize():
var data = .serialize()
data.suffix = $Suffix.text
return data
func deserialize(data):
if data.has("suffix"):
$Suffix.text = data.suffix
.deserialize(data)

View File

@ -0,0 +1,64 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/procedural_material/nodes/export.gd" type="Script" id=1]
[sub_resource type="Theme" id=1]
[node name="Export" type="GraphNode"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 114.0
margin_bottom = 55.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = SubResource( 1 )
title = "Export"
offset = Vector2( 0, 0 )
show_close = false
resizable = false
selected = false
comment = false
overlay = 0
slot/0/left_enabled = true
slot/0/left_type = 0
slot/0/left_color = Color( 0.5, 0.5, 1, 1 )
slot/0/right_enabled = false
slot/0/right_type = 0
slot/0/right_color = Color( 0.5, 0.5, 1, 1 )
script = ExtResource( 1 )
_sections_unfolded = [ "Theme", "slot", "slot/0" ]
[node name="Suffix" type="LineEdit" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0
margin_top = 24.0
margin_right = 98.0
margin_bottom = 48.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 1
size_flags_horizontal = 1
size_flags_vertical = 1
text = "suffix"
focus_mode = 2
context_menu_enabled = true
placeholder_alpha = 0.6
caret_blink = false
caret_blink_speed = 0.65
caret_position = 0

View File

@ -3,15 +3,19 @@ extends "res://addons/procedural_material/node_base.gd"
var amount = 0.0 var amount = 0.0
var input_shader = ""
var input_texture
var final_texture
const CONVOLUTION = { const CONVOLUTION = {
x=1,
y=1,
kernel=[ kernel=[
0, 0, 0, 0, 0, Vector3(-1, -1, 0), Vector3(0, -2, 0), Vector3(1, -1, 0),
0, Vector3(-1, -1, 0), Vector3(0, -2, 0), Vector3(1, -1, 0), 0, Vector3(-2, 0, 0), 0, Vector3(2, 0, 0),
0, Vector3(-2, 0, 0), 0, Vector3(2, 0, 0), 0, Vector3(-1, 1, 0), Vector3(0, 2, 0), Vector3(1, 1, 0),
0, Vector3(-1, 1, 0), Vector3(0, 2, 0), Vector3(1, 1, 0), 0,
0, 0, 0, 0, 0
], ],
epsilon=0.005, epsilon=1.0/1024,
normalize=true, normalize=true,
translate_before_normalize=Vector3(0.0, 0.0, -1.0), translate_before_normalize=Vector3(0.0, 0.0, -1.0),
scale_before_normalize=0.5, scale_before_normalize=0.5,
@ -20,12 +24,36 @@ const CONVOLUTION = {
} }
func _ready(): func _ready():
input_texture = ImageTexture.new()
final_texture = ImageTexture.new()
initialize_properties([ $amount ]) initialize_properties([ $amount ])
func _rerender():
get_parent().precalculate_shader(input_shader, get_source().get_textures(), 1024, input_texture, self, "pass_1", [])
func pass_1():
var convolution = CONVOLUTION
convolution.scale_before_normalize = 8.0*amount
get_parent().precalculate_shader(get_convolution_shader(convolution), { input=input_texture}, 1024, final_texture, self, "rerender_targets", [])
func get_textures():
var list = {}
list[name] = final_texture
return list
func _get_shader_code(uv): func _get_shader_code(uv):
var rv = { defs="", code="" }
var src = get_source() var src = get_source()
if src == null: if src == null:
return { defs="", code="" } return rv
var convolution = CONVOLUTION input_shader = do_generate_shader(src.get_shader_code("UV"))
convolution.scale_before_normalize = amount _rerender()
return get_shader_code_convolution(src, convolution, uv) if generated_variants.empty():
rv.defs = "uniform sampler2D "+name+"_tex;\n"
var variant_index = generated_variants.find(uv)
if variant_index == -1:
variant_index = generated_variants.size()
generated_variants.append(uv)
rv.code = "vec3 "+name+"_"+str(variant_index)+"_rgb = texture("+name+"_tex, "+uv+").rgb;\n"
rv.rgb = name+"_"+str(variant_index)+"_rgb"
return rv

View File

@ -5,7 +5,7 @@
[sub_resource type="Theme" id=1] [sub_resource type="Theme" id=1]
[node name="Pattern" type="GraphNode" index="0"] [node name="Pattern" type="GraphNode"]
anchor_left = 0.0 anchor_left = 0.0
anchor_top = 0.0 anchor_top = 0.0

View File

@ -1 +1 @@
{"connections":[{"from":"Perlin","from_port":0,"to":"Warp","to_port":1},{"from":"Warp","from_port":0,"to":"colorize_2","to_port":0},{"from":"colorize_2","from_port":0,"to":"blend_0","to_port":2},{"from":"colorize_1","from_port":0,"to":"blend_0","to_port":0},{"from":"colorize_0","from_port":0,"to":"blend_0","to_port":1},{"from":"blend_0","from_port":0,"to":"Material","to_port":0},{"from":"normal_map_0","from_port":0,"to":"Material","to_port":4},{"from":"colorize_2","from_port":0,"to":"colorize_4","to_port":0},{"from":"colorize_4","from_port":0,"to":"Material","to_port":2},{"from":"Bricks","from_port":0,"to":"Warp","to_port":0},{"from":"blend_1","from_port":0,"to":"colorize_1","to_port":0},{"from":"Bricks","from_port":1,"to":"blend_1","to_port":1},{"from":"Warp","from_port":0,"to":"blend_2","to_port":0},{"from":"Perlin","from_port":0,"to":"blend_2","to_port":1},{"from":"blend_2","from_port":0,"to":"colorize_3","to_port":0},{"from":"blend_2","from_port":0,"to":"colorize_6","to_port":0},{"from":"colorize_6","from_port":0,"to":"normal_map_0","to_port":0},{"from":"Perlin","from_port":0,"to":"blend_1","to_port":0},{"from":"Perlin","from_port":0,"to":"colorize_0","to_port":0},{"from":"uniform_0","from_port":0,"to":"Material","to_port":1},{"from":"colorize_3","from_port":0,"to":"Material","to_port":5}],"nodes":[{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":1,"r":1}],"name":"colorize_0","node_position":{"x":560.943665,"y":50},"type":"colorize"},{"gradient":[{"b":0.0016,"g":0.0016,"pos":0,"r":0.307292},{"b":0,"g":0.180135,"pos":0.2,"r":0.606771},{"b":0,"g":0,"pos":0.354545,"r":0.3125},{"b":0,"g":0.19869,"pos":0.554545,"r":0.669271},{"b":0.019368,"g":0.060224,"pos":0.754545,"r":0.309896},{"b":0,"g":0.180135,"pos":1,"r":0.606771}],"name":"colorize_1","node_position":{"x":562.943665,"y":-65},"type":"colorize"},{"bevel":0.2,"columns":3,"mortar":0.05,"name":"Bricks","node_position":{"x":118,"y":-22},"row_offset":0.5,"rows":6,"type":"bricks"},{"amount":0.04,"name":"Warp","node_position":{"x":384,"y":10.75},"type":"warp"},{"albedo_color":{"a":1,"b":1,"g":1,"r":1,"type":"Color"},"ao_light_affect":1,"depth_scale":0,"emission_energy":1,"metallic":1,"name":"Material","node_position":{"x":1081,"y":208},"normal_scale":1,"roughness":1,"type":"material"},{"amount":0.5,"blend_type":0,"name":"blend_2","node_position":{"x":536,"y":331},"type":"blend"},{"gradient":[{"b":1,"g":1,"pos":0,"r":1},{"b":0.463542,"g":0.463542,"pos":1,"r":0.463542}],"name":"colorize_4","node_position":{"x":708,"y":224},"type":"colorize"},{"amount":0.5,"blend_type":0,"name":"blend_0","node_position":{"x":836.943726,"y":-71},"type":"blend"},{"color":{"a":1,"b":0,"g":0,"r":0,"type":"Color"},"name":"uniform_0","node_position":{"x":892,"y":179},"type":"uniform"},{"amount":0.5,"name":"normal_map_0","node_position":{"x":913,"y":278},"type":"normal_map"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":0.1,"r":1}],"name":"colorize_2","node_position":{"x":544.943665,"y":159},"type":"colorize"},{"amount":0.5,"blend_type":6,"name":"blend_1","node_position":{"x":349,"y":215},"type":"blend"},{"iterations":6,"name":"Perlin","node_position":{"x":115,"y":194},"persistence":0.85,"scale_x":4,"scale_y":4,"type":"perlin"},{"gradient":[{"b":1,"g":1,"pos":0,"r":1},{"b":0,"g":0,"pos":1,"r":0}],"name":"colorize_6","node_position":{"x":743,"y":291},"type":"colorize"},{"gradient":[{"b":0.510417,"g":0.510417,"pos":0.245455,"r":0.510417},{"b":1,"g":1,"pos":0.536364,"r":1}],"name":"colorize_3","node_position":{"x":753,"y":364},"type":"colorize"}]} {"connections":[{"from":"Perlin","from_port":0,"to":"Warp","to_port":1},{"from":"Warp","from_port":0,"to":"colorize_2","to_port":0},{"from":"colorize_2","from_port":0,"to":"blend_0","to_port":2},{"from":"colorize_1","from_port":0,"to":"blend_0","to_port":0},{"from":"colorize_0","from_port":0,"to":"blend_0","to_port":1},{"from":"blend_0","from_port":0,"to":"Material","to_port":0},{"from":"normal_map_0","from_port":0,"to":"Material","to_port":4},{"from":"colorize_2","from_port":0,"to":"colorize_4","to_port":0},{"from":"colorize_4","from_port":0,"to":"Material","to_port":2},{"from":"Bricks","from_port":0,"to":"Warp","to_port":0},{"from":"blend_1","from_port":0,"to":"colorize_1","to_port":0},{"from":"Bricks","from_port":1,"to":"blend_1","to_port":1},{"from":"Warp","from_port":0,"to":"blend_2","to_port":0},{"from":"Perlin","from_port":0,"to":"blend_2","to_port":1},{"from":"blend_2","from_port":0,"to":"colorize_3","to_port":0},{"from":"blend_2","from_port":0,"to":"colorize_6","to_port":0},{"from":"colorize_6","from_port":0,"to":"normal_map_0","to_port":0},{"from":"Perlin","from_port":0,"to":"blend_1","to_port":0},{"from":"Perlin","from_port":0,"to":"colorize_0","to_port":0},{"from":"uniform_0","from_port":0,"to":"Material","to_port":1},{"from":"colorize_3","from_port":0,"to":"Material","to_port":5},{"from":"uniform_0","from_port":0,"to":"combine_0","to_port":0},{"from":"colorize_4","from_port":0,"to":"combine_0","to_port":1},{"from":"combine_0","from_port":0,"to":"export_0","to_port":0}],"nodes":[{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":1,"r":1}],"name":"colorize_0","node_position":{"x":560.943665,"y":50},"type":"colorize"},{"gradient":[{"b":0.0016,"g":0.0016,"pos":0,"r":0.307292},{"b":0,"g":0.180135,"pos":0.2,"r":0.606771},{"b":0,"g":0,"pos":0.345455,"r":0.3125},{"b":0,"g":0.19869,"pos":0.545455,"r":0.669271},{"b":0.019368,"g":0.060224,"pos":0.745455,"r":0.309896},{"b":0,"g":0.180135,"pos":1,"r":0.606771}],"name":"colorize_1","node_position":{"x":562.943665,"y":-65},"type":"colorize"},{"bevel":0.2,"columns":3,"mortar":0.05,"name":"Bricks","node_position":{"x":118,"y":-22},"row_offset":0.5,"rows":6,"type":"bricks"},{"amount":0.04,"name":"Warp","node_position":{"x":384,"y":10.75},"type":"warp"},{"albedo_color":{"a":1,"b":1,"g":1,"r":1,"type":"Color"},"ao_light_affect":1,"depth_scale":0,"emission_energy":1,"metallic":1,"name":"Material","node_position":{"x":1081,"y":208},"normal_scale":1,"roughness":1,"type":"material"},{"amount":0.5,"blend_type":0,"name":"blend_2","node_position":{"x":536,"y":331},"type":"blend"},{"gradient":[{"b":1,"g":1,"pos":0,"r":1},{"b":0.463542,"g":0.463542,"pos":1,"r":0.463542}],"name":"colorize_4","node_position":{"x":708,"y":224},"type":"colorize"},{"amount":0.5,"blend_type":0,"name":"blend_0","node_position":{"x":836.943726,"y":-71},"type":"blend"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":0.1,"r":1}],"name":"colorize_2","node_position":{"x":544.943665,"y":159},"type":"colorize"},{"amount":0.5,"blend_type":6,"name":"blend_1","node_position":{"x":349,"y":215},"type":"blend"},{"iterations":6,"name":"Perlin","node_position":{"x":115,"y":194},"persistence":0.85,"scale_x":4,"scale_y":4,"type":"perlin"},{"gradient":[{"b":1,"g":1,"pos":0,"r":1},{"b":0,"g":0,"pos":1,"r":0}],"name":"colorize_6","node_position":{"x":743,"y":291},"type":"colorize"},{"gradient":[{"b":0.510417,"g":0.510417,"pos":0.245455,"r":0.510417},{"b":1,"g":1,"pos":0.536364,"r":1}],"name":"colorize_3","node_position":{"x":753,"y":364},"type":"colorize"},{"amount":0.5,"name":"normal_map_0","node_position":{"x":922,"y":297},"type":"normal_map"},{"color":{"a":1,"b":0,"g":0,"r":0,"type":"Color"},"name":"uniform_0","node_position":{"x":764,"y":164},"type":"uniform"},{"name":"combine_0","node_position":{"x":896,"y":86},"type":"combine"},{"name":"export_0","node_position":{"x":1050,"y":79},"suffix":"mr","type":"export"}]}

View File

@ -1 +1 @@
{"connections":[{"from":"pattern_0","from_port":0,"to":"colorize_0","to_port":0},{"from":"colorize_0","from_port":0,"to":"blend_0","to_port":0},{"from":"transform_0","from_port":0,"to":"blend_0","to_port":1},{"from":"colorize_0","from_port":0,"to":"transform_0","to_port":0},{"from":"blend_0","from_port":0,"to":"transform_1","to_port":0},{"from":"transform_1","from_port":0,"to":"blend_1","to_port":1},{"from":"blend_0","from_port":0,"to":"blend_1","to_port":0},{"from":"blend_1","from_port":0,"to":"colorize_1","to_port":0},{"from":"colorize_1","from_port":0,"to":"normal_map_0","to_port":0},{"from":"normal_map_0","from_port":0,"to":"Material","to_port":4},{"from":"perlin_0","from_port":0,"to":"colorize_2","to_port":0},{"from":"colorize_2","from_port":0,"to":"blend_2","to_port":0},{"from":"blend_2","from_port":0,"to":"Material","to_port":0},{"from":"colorize_4","from_port":0,"to":"blend_2","to_port":2},{"from":"colorize_4","from_port":0,"to":"colorize_5","to_port":0},{"from":"colorize_5","from_port":0,"to":"Material","to_port":1},{"from":"colorize_4","from_port":0,"to":"colorize_6","to_port":0},{"from":"colorize_6","from_port":0,"to":"Material","to_port":2},{"from":"perlin_1","from_port":0,"to":"blend_3","to_port":1},{"from":"colorize_7","from_port":0,"to":"blend_3","to_port":0},{"from":"blend_1","from_port":0,"to":"colorize_7","to_port":0},{"from":"blend_3","from_port":0,"to":"colorize_4","to_port":0},{"from":"uniform_0","from_port":0,"to":"blend_2","to_port":1}],"nodes":[{"iterations":7,"name":"perlin_0","node_position":{"x":1,"y":-330},"persistence":0.85,"scale_x":4,"scale_y":4,"type":"perlin"},{"gradient":[{"b":0,"g":0,"pos":0.018182,"r":0},{"b":1,"g":1,"pos":0.045455,"r":1}],"name":"colorize_0","node_position":{"x":-828,"y":218},"type":"colorize"},{"gradient":[{"b":0,"g":0.152344,"pos":0,"r":0.270833},{"b":0,"g":0.191569,"pos":0.954545,"r":0.557292}],"name":"colorize_2","node_position":{"x":201,"y":-298},"type":"colorize"},{"name":"Material","node_position":{"x":755,"y":-137},"type":"material"},{"amount":0.5,"blend_type":0,"name":"blend_2","node_position":{"x":407.094238,"y":-265.083313},"type":"blend"},{"gradient":[{"b":1,"g":1,"pos":0.609091,"r":1},{"b":0,"g":0,"pos":0.645455,"r":0}],"name":"colorize_5","node_position":{"x":447,"y":-146},"type":"colorize"},{"gradient":[{"b":0,"g":0,"pos":0.445455,"r":0},{"b":1,"g":1,"pos":0.545455,"r":1}],"name":"colorize_4","node_position":{"x":258,"y":-136},"type":"colorize"},{"mix":5,"name":"pattern_0","node_position":{"x":-858,"y":120},"type":"pattern","x_scale":8,"x_wave":0,"y_scale":8,"y_wave":0},{"name":"transform_1","node_position":{"x":-647,"y":285},"repeat":true,"rotate":90,"scale_x":1,"scale_y":1,"translate_x":0.06,"translate_y":0,"type":"transform"},{"amount":1,"blend_type":2,"name":"blend_0","node_position":{"x":-633,"y":181},"type":"blend"},{"amount":1,"blend_type":2,"name":"blend_1","node_position":{"x":-632,"y":77},"type":"blend"},{"color":{"a":1,"b":1,"g":1,"r":1,"type":"Color"},"name":"uniform_0","node_position":{"x":233,"y":-216},"type":"uniform"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":0.018182,"r":1}],"name":"colorize_7","node_position":{"x":-109.265503,"y":-175},"type":"colorize"},{"amount":0.2,"blend_type":2,"name":"blend_3","node_position":{"x":72.734497,"y":-156},"type":"blend"},{"iterations":7,"name":"perlin_1","node_position":{"x":-161,"y":-86},"persistence":0.75,"scale_x":4,"scale_y":4,"type":"perlin"},{"gradient":[{"b":0.640625,"g":0.640625,"pos":0,"r":0.640625},{"b":1,"g":1,"pos":1,"r":1}],"name":"colorize_6","node_position":{"x":444,"y":-66},"type":"colorize"},{"amount":0.35,"name":"normal_map_0","node_position":{"x":294,"y":76},"type":"normal_map"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":1,"r":1}],"name":"colorize_1","node_position":{"x":85,"y":72},"type":"colorize"},{"name":"transform_0","node_position":{"x":-845,"y":279},"repeat":true,"rotate":0,"scale_x":1,"scale_y":1,"translate_x":0.06,"translate_y":0.06,"type":"transform"}]} {"connections":[{"from":"pattern_0","from_port":0,"to":"colorize_0","to_port":0},{"from":"colorize_0","from_port":0,"to":"blend_0","to_port":0},{"from":"transform_0","from_port":0,"to":"blend_0","to_port":1},{"from":"colorize_0","from_port":0,"to":"transform_0","to_port":0},{"from":"blend_0","from_port":0,"to":"transform_1","to_port":0},{"from":"transform_1","from_port":0,"to":"blend_1","to_port":1},{"from":"blend_0","from_port":0,"to":"blend_1","to_port":0},{"from":"blend_1","from_port":0,"to":"colorize_1","to_port":0},{"from":"colorize_1","from_port":0,"to":"normal_map_0","to_port":0},{"from":"normal_map_0","from_port":0,"to":"Material","to_port":4},{"from":"perlin_0","from_port":0,"to":"colorize_2","to_port":0},{"from":"colorize_2","from_port":0,"to":"blend_2","to_port":0},{"from":"blend_2","from_port":0,"to":"Material","to_port":0},{"from":"colorize_4","from_port":0,"to":"blend_2","to_port":2},{"from":"colorize_4","from_port":0,"to":"colorize_5","to_port":0},{"from":"colorize_5","from_port":0,"to":"Material","to_port":1},{"from":"colorize_4","from_port":0,"to":"colorize_6","to_port":0},{"from":"colorize_6","from_port":0,"to":"Material","to_port":2},{"from":"perlin_1","from_port":0,"to":"blend_3","to_port":1},{"from":"colorize_7","from_port":0,"to":"blend_3","to_port":0},{"from":"blend_1","from_port":0,"to":"colorize_7","to_port":0},{"from":"blend_3","from_port":0,"to":"colorize_4","to_port":0},{"from":"uniform_0","from_port":0,"to":"blend_2","to_port":1},{"from":"colorize_5","from_port":0,"to":"combine_0","to_port":0},{"from":"colorize_6","from_port":0,"to":"combine_0","to_port":1},{"from":"combine_0","from_port":0,"to":"export_0","to_port":0}],"nodes":[{"iterations":7,"name":"perlin_0","node_position":{"x":1,"y":-330},"persistence":0.85,"scale_x":4,"scale_y":4,"type":"perlin"},{"gradient":[{"b":0,"g":0,"pos":0.018182,"r":0},{"b":1,"g":1,"pos":0.045455,"r":1}],"name":"colorize_0","node_position":{"x":-828,"y":218},"type":"colorize"},{"gradient":[{"b":0,"g":0.152344,"pos":0,"r":0.270833},{"b":0,"g":0.191569,"pos":0.945455,"r":0.557292}],"name":"colorize_2","node_position":{"x":201,"y":-298},"type":"colorize"},{"albedo_color":{"a":1,"b":1,"g":1,"r":1,"type":"Color"},"ao_light_affect":1,"depth_scale":1,"emission_energy":1,"metallic":1,"name":"Material","node_position":{"x":755,"y":-137},"normal_scale":1,"roughness":1,"type":"material"},{"amount":0.5,"blend_type":0,"name":"blend_2","node_position":{"x":407.094238,"y":-265.083313},"type":"blend"},{"gradient":[{"b":0,"g":0,"pos":0.445455,"r":0},{"b":1,"g":1,"pos":0.545455,"r":1}],"name":"colorize_4","node_position":{"x":258,"y":-136},"type":"colorize"},{"mix":5,"name":"pattern_0","node_position":{"x":-858,"y":120},"type":"pattern","x_scale":8,"x_wave":0,"y_scale":8,"y_wave":0},{"name":"transform_1","node_position":{"x":-647,"y":285},"repeat":true,"rotate":90,"scale_x":1,"scale_y":1,"translate_x":0.06,"translate_y":0,"type":"transform"},{"amount":1,"blend_type":2,"name":"blend_0","node_position":{"x":-633,"y":181},"type":"blend"},{"amount":1,"blend_type":2,"name":"blend_1","node_position":{"x":-632,"y":77},"type":"blend"},{"color":{"a":1,"b":1,"g":1,"r":1,"type":"Color"},"name":"uniform_0","node_position":{"x":233,"y":-216},"type":"uniform"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":0.018182,"r":1}],"name":"colorize_7","node_position":{"x":-109.265503,"y":-175},"type":"colorize"},{"iterations":7,"name":"perlin_1","node_position":{"x":-161,"y":-86},"persistence":0.75,"scale_x":4,"scale_y":4,"type":"perlin"},{"gradient":[{"b":0.640625,"g":0.640625,"pos":0,"r":0.640625},{"b":1,"g":1,"pos":1,"r":1}],"name":"colorize_6","node_position":{"x":444,"y":-66},"type":"colorize"},{"gradient":[{"b":0,"g":0,"pos":0,"r":0},{"b":1,"g":1,"pos":1,"r":1}],"name":"colorize_1","node_position":{"x":85,"y":72},"type":"colorize"},{"name":"transform_0","node_position":{"x":-845,"y":279},"repeat":true,"rotate":0,"scale_x":1,"scale_y":1,"translate_x":0.06,"translate_y":0.06,"type":"transform"},{"gradient":[{"b":1,"g":1,"pos":0.609091,"r":1},{"b":0,"g":0,"pos":0.645455,"r":0}],"name":"colorize_5","node_position":{"x":446,"y":-150},"type":"colorize"},{"name":"combine_0","node_position":{"x":677,"y":-264},"type":"combine"},{"name":"export_0","node_position":{"x":828,"y":-268},"suffix":"mr","type":"export"},{"amount":0.6,"name":"normal_map_0","node_position":{"x":294,"y":76},"type":"normal_map"},{"amount":0.2,"blend_type":2,"name":"blend_3","node_position":{"x":72.734497,"y":-130},"type":"blend"}]}

View File

@ -5,15 +5,15 @@ platform="Windows Desktop"
runnable=true runnable=true
custom_features="" custom_features=""
export_filter="all_resources" export_filter="all_resources"
include_filter="" include_filter="*.json,res://addons/procedural_material/library/base/*.png"
exclude_filter="*.ptex" exclude_filter="*.ptex"
patch_list=PoolStringArray( ) patch_list=PoolStringArray( )
[preset.0.options] [preset.0.options]
texture_format/s3tc=true texture_format/s3tc=true
texture_format/etc=false texture_format/etc=true
texture_format/etc2=false texture_format/etc2=true
binary_format/64_bits=true binary_format/64_bits=true
custom_template/release="" custom_template/release=""
custom_template/debug="" custom_template/debug=""