Prepared all nodes for caching and added Image node

Added Image node that can be used to import textures
Renamed all get_shader_code methods to _get_shader code so a caching system can be integrated in node_base (and we can get rid of get_source_rgb and get_source_f functions)
This commit is contained in:
RodZill4 2018-07-26 08:31:28 +02:00
parent 4e0af78b31
commit d04a319944
21 changed files with 238 additions and 51 deletions

View File

@ -68,6 +68,19 @@ func get_source_rgb(source):
rv = "***error***"
return rv
func get_shader_code(uv):
return _get_shader_code(uv)
func get_textures():
var list = {}
for i in range(5):
var source = get_source(i)
if source != null:
var source_list = source.get_textures()
for k in source_list.keys():
list[k] = source_list[k]
return list
func queue_free():
get_parent().remove_node(self.name)
.queue_free()

View File

@ -12,7 +12,7 @@ func _ready():
func color_to_string(c):
return "vec3("+str(c.r)+","+str(c.g)+","+str(c.b)+")"
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="" }
var src0 = get_source(0)
var src1 = get_source(1)

View File

@ -11,10 +11,9 @@ anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 3.0
margin_top = 4.0
margin_right = 93.0
margin_bottom = 87.0
margin_left = 1.0
margin_right = 91.0
margin_bottom = 83.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1

View File

@ -11,7 +11,7 @@ func _ready():
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
initialize_properties([ $GridContainer/rows, $GridContainer/columns, $GridContainer/row_offset, $GridContainer/mortar, $GridContainer/bevel ])
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="" }
if generated_variants.empty():
rv.defs = "float "+name+"_f(vec2 uv) { return bricks(uv, vec2("+str(columns)+", "+str(rows)+"), "+str(row_offset)+", "+str(mortar)+", "+str(max(0.001, bevel))+"); }\n"

View File

@ -11,7 +11,7 @@ func _ready():
func color_to_string(c):
return "vec3("+str(c.r)+","+str(c.g)+","+str(c.b)+")"
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="" }
var src = get_source()
if src == null:

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,30 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/godot_logo.png-045faf38aa6152514c35dacd2584c5c2.s3tc.stex"
path.etc2="res://.import/godot_logo.png-045faf38aa6152514c35dacd2584c5c2.etc2.stex"
[deps]
source_file="res://addons/procedural_material/nodes/godot_logo.png"
dest_files=[ "res://.import/godot_logo.png-045faf38aa6152514c35dacd2584c5c2.s3tc.stex", "res://.import/godot_logo.png-045faf38aa6152514c35dacd2584c5c2.etc2.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@ -0,0 +1,28 @@
tool
extends "res://addons/procedural_material/node_base.gd"
var rows
func _ready():
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
func set_texture(path):
var texture = ImageTexture.new()
texture.load(path)
func get_textures():
var list = {}
list[name] = $TextureButton.texture_normal
return list
func _get_shader_code(uv):
var rv = { defs="", code="" }
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=4 format=2]
[ext_resource path="res://addons/procedural_material/nodes/image.gd" type="Script" id=1]
[ext_resource path="res://addons/procedural_material/nodes/godot_logo.png" type="Texture" id=2]
[sub_resource type="Theme" id=1]
[node name="Image" 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 = 95.0
margin_bottom = 92.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 = "Image"
offset = Vector2( 0, 0 )
show_close = true
resizable = false
selected = false
comment = false
overlay = 0
slot/0/left_enabled = false
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" ]
[node name="TextureButton" type="TextureButton" 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 = 80.0
margin_bottom = 88.0
rect_min_size = Vector2( 64, 64 )
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
enabled_focus_mode = 2
shortcut = null
group = null
texture_normal = ExtResource( 2 )
stretch_mode = 5
_sections_unfolded = [ "Rect", "Textures" ]
[connection signal="close_request" from="." to="." method="queue_free"]

View File

@ -9,7 +9,7 @@ func _ready():
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
initialize_properties([ $GridContainer/subdivide, $GridContainer/u, $GridContainer/v ])
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="" }
if generated_variants.empty():
rv.defs = "float "+name+"_f(vec2 uv) { return iqnoise(uv, "+str(subdivide)+", "+str(u)+", "+str(v)+"); }\n"

View File

@ -5,7 +5,7 @@ func _ready():
set_slot(0, true, 0, Color(0.5, 0.5, 1), false, 0, Color(0.5, 0.5, 1))
set_slot(1, true, 0, Color(0.5, 0.5, 1), false, 0, Color(0.5, 0.5, 1))
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="", f="0.0" }
var src = get_source()
if src != null:

View File

@ -8,7 +8,7 @@ func _ready():
set_slot(1, true, 0, Color(0.5, 0.5, 1), false, 0, Color(0.5, 0.5, 1))
initialize_properties([ $amount ])
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="" }
var src = get_source()
if src == null:

View File

@ -10,7 +10,7 @@ func _ready():
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
initialize_properties([ $GridContainer/scale_x, $GridContainer/scale_y, $GridContainer/iterations, $GridContainer/persistance ])
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="" }
if generated_variants.empty():
rv.defs = "float "+name+"_f(vec2 uv) { return perlin(uv, vec2("+str(scale_x)+", "+str(scale_y)+"), "+str(iterations)+", "+str(persistance)+"); }\n"

View File

@ -8,7 +8,7 @@ func _ready():
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
initialize_properties([ $waves, $sharpness ])
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="" }
if generated_variants.empty():
rv.defs = "float "+name+"_f(vec2 uv) { return sine(uv, "+str(waves)+", "+str(sharpness)+"); }\n"

View File

@ -8,7 +8,7 @@ func _ready():
set_slot(0, true, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
initialize_properties([ $GridContainer/rotate, $GridContainer/scale ])
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="" }
var src = get_source()
if src == null:

View File

@ -8,7 +8,7 @@ func _ready():
set_slot(1, true, 0, Color(0.5, 0.5, 1), false, 0, Color(0.5, 0.5, 1))
initialize_properties([ $amount ])
func get_shader_code(uv):
func _get_shader_code(uv):
var rv = { defs="", code="" }
var src0 = get_source(0)
var src1 = get_source(1)

View File

@ -4,13 +4,14 @@ extends Container
var popup_position = Vector2(0, 0)
var selected_node = null
var material_preview_shader = null
var texture_preview_shader = null
var preview_material = null
var texture_preview_material = null
const MENU = [
{ command="load_texture", description="Load texture" },
{ command="save_texture", description="Save texture" },
{ command="export_texture", description="Export texture" },
{ name="image", description="Image" },
{ name="sine", description="Sine" },
{ name="bricks", description="Bricks" },
{ name="iqnoise", description="IQ Noise" },
@ -24,9 +25,9 @@ const MENU = [
func _ready():
# Duplicate the material we'll modify and store the shaders
material_preview_shader = $Container/ViewportContainer/MaterialPreview.material.shader
preview_material = $Container/ViewportContainer/MaterialPreview.material
$Container/ViewportContainer/SelectedPreview.material = $Container/ViewportContainer/SelectedPreview.material.duplicate(true)
texture_preview_shader = $Container/ViewportContainer/SelectedPreview.material.shader
texture_preview_material = $Container/ViewportContainer/SelectedPreview.material
$GraphEdit.add_valid_connection_type(0, 0)
$GraphEdit/PopupMenu.clear()
for i in MENU.size():
@ -108,11 +109,11 @@ func save_file(filename):
file.close()
func export_texture():
var size = 1024
var size = 256
$SaveViewport.size = Vector2(size, size)
$SaveViewport/ColorRect.rect_position = Vector2(0, 0)
$SaveViewport/ColorRect.rect_size = Vector2(size, size)
$SaveViewport/ColorRect.material.shader.set_code($GraphEdit.generate_shader(selected_node))
setup_material($SaveViewport/ColorRect.material, selected_node.get_textures(), $GraphEdit.generate_shader(selected_node))
$SaveViewport.render_target_update_mode = Viewport.UPDATE_ONCE
#$SaveViewport/ColorRect.update()
$SaveViewport.update_worlds()
@ -120,13 +121,20 @@ func export_texture():
yield($SaveViewport/Timer, "timeout")
var viewport_texture = $SaveViewport.get_texture()
var viewport_image = viewport_texture.get_data()
viewport_image.save_png("res://generated_image.png")
viewport_image.save_png("res://generated_image.png")
func setup_material(shader_material, textures, shader_code):
for k in textures.keys():
print("Setting param "+k+" to "+str(textures[k]))
shader_material.set_shader_param(k+"_tex", textures[k])
shader_material.shader.code = shader_code
func generate_shader():
material_preview_shader.set_code($GraphEdit.generate_shader($GraphEdit/Material, 1))
setup_material(preview_material, $GraphEdit/Material.get_textures(), $GraphEdit.generate_shader($GraphEdit/Material, 1))
if selected_node != null:
texture_preview_shader.set_code($GraphEdit.generate_shader(selected_node))
setup_material(texture_preview_material, selected_node.get_textures(), $GraphEdit.generate_shader(selected_node))
func _on_GraphEdit_node_selected(node):
selected_node = node
texture_preview_shader.set_code($GraphEdit.generate_shader(selected_node))
setup_material(texture_preview_material, selected_node.get_textures(), $GraphEdit.generate_shader(selected_node))

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=17 format=2]
[gd_scene load_steps=20 format=2]
[ext_resource path="res://addons/procedural_material/pm_editor.gd" type="Script" id=1]
[ext_resource path="res://addons/procedural_material/graph_edit.gd" type="Script" id=2]
[ext_resource path="res://addons/procedural_material/nodes/material.tscn" type="PackedScene" id=3]
[ext_resource path="res://addons/procedural_material/material_preview.gd" type="Script" id=4]
[ext_resource path="res://addons/procedural_material/nodes/godot_logo.png" type="Texture" id=5]
[sub_resource type="ProceduralSky" id=1]
@ -117,7 +118,16 @@ subdivide_width = 0
subdivide_height = 0
subdivide_depth = 0
[sub_resource type="CylinderMesh" id=5]
[sub_resource type="Shader" id=5]
code = ""
[sub_resource type="ShaderMaterial" id=6]
render_priority = 0
shader = SubResource( 5 )
[sub_resource type="CylinderMesh" id=7]
custom_aabb = AABB( 0, 0, 0, 0, 0, 0 )
top_radius = 1.0
@ -126,7 +136,7 @@ height = 2.0
radial_segments = 64
rings = 4
[sub_resource type="Animation" id=6]
[sub_resource type="Animation" id=8]
length = 1.0
loop = true
@ -144,7 +154,7 @@ tracks/0/keys = {
"values": [ Vector3( 0, 0, 0 ), Vector3( 0, 360, 0 ) ]
}
[sub_resource type="ProceduralSky" id=7]
[sub_resource type="ProceduralSky" id=9]
radiance_size = 4
sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 )
@ -165,10 +175,10 @@ sun_energy = 16.0
texture_size = 2
_sections_unfolded = [ "Sky" ]
[sub_resource type="Environment" id=8]
[sub_resource type="Environment" id=10]
background_mode = 2
background_sky = SubResource( 7 )
background_sky = SubResource( 9 )
background_sky_custom_fov = 0.0
background_color = Color( 0, 0, 0, 1 )
background_energy = 1.0
@ -245,7 +255,7 @@ adjustment_contrast = 1.0
adjustment_saturation = 1.0
_sections_unfolded = [ "Background" ]
[sub_resource type="Shader" id=9]
[sub_resource type="Shader" id=11]
code = "shader_type canvas_item;
@ -255,12 +265,12 @@ void fragment() {
"
_sections_unfolded = [ "Resource" ]
[sub_resource type="ShaderMaterial" id=10]
[sub_resource type="ShaderMaterial" id=12]
render_priority = 0
shader = SubResource( 9 )
shader = SubResource( 11 )
[sub_resource type="Shader" id=11]
[sub_resource type="Shader" id=13]
code = "shader_type canvas_item;
@ -383,18 +393,18 @@ float perlin(vec2 p, vec2 scale, int iterations, float persistance) {
return n/normK;
}
float Perlin_f(vec2 uv) { return perlin(uv, vec2(8, 9), 7, 1); }
uniform sampler2D Image_tex;
void fragment() {
float Perlin_0_f = Perlin_f(UV);
vec3 Colorize_0_rgb = mix(vec3(0,0,0), vec3(1,1,1), Perlin_0_f);
COLOR = vec4(Colorize_0_rgb, 1.0);
vec3 Image_0_rgb = texture(Image_tex, UV).rgb;
COLOR = vec4(Image_0_rgb, 1.0);
}
"
[sub_resource type="ShaderMaterial" id=12]
[sub_resource type="ShaderMaterial" id=14]
render_priority = 0
shader = SubResource( 11 )
shader = SubResource( 13 )
shader_param/Image_tex = ExtResource( 5 )
[node name="ProceduralMaterialEditor" type="MarginContainer" index="0"]
@ -464,7 +474,7 @@ mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
popup_exclusive = false
items = [ "Load texture", null, 0, false, false, 0, 0, null, "", false, "Save texture", null, 0, false, false, 1, 0, null, "", false, "Sine", null, 0, false, false, 2, 0, null, "", false, "Bricks", null, 0, false, false, 3, 0, null, "", false, "IQ Noise", null, 0, false, false, 4, 0, null, "", false, "Perlin noise", null, 0, false, false, 5, 0, null, "", false, "Transform", null, 0, false, false, 6, 0, null, "", false, "Warp", null, 0, false, false, 7, 0, null, "", false, "Colorize", null, 0, false, false, 8, 0, null, "", false, "Normal Map", null, 0, false, false, 9, 0, null, "", false, "Blend", null, 0, false, false, 10, 0, null, "", false ]
items = [ "Load texture", null, 0, false, false, 0, 0, null, "", false, "Save texture", null, 0, false, false, 1, 0, null, "", false, "Export texture", null, 0, false, false, 2, 0, null, "", false, "Image", null, 0, false, false, 3, 0, null, "", false, "Sine", null, 0, false, false, 4, 0, null, "", false, "Bricks", null, 0, false, false, 5, 0, null, "", false, "IQ Noise", null, 0, false, false, 6, 0, null, "", false, "Perlin noise", null, 0, false, false, 7, 0, null, "", false, "Transform", null, 0, false, false, 8, 0, null, "", false, "Warp", null, 0, false, false, 9, 0, null, "", false, "Colorize", null, 0, false, false, 10, 0, null, "", false, "Normal Map", null, 0, false, false, 11, 0, null, "", false, "Blend", null, 0, false, false, 12, 0, null, "", false ]
hide_on_state_item_selection = false
_sections_unfolded = [ "Rect" ]
@ -553,7 +563,7 @@ _sections_unfolded = [ "GUI", "Render Target", "Rendering" ]
[node name="Objects" type="Spatial" parent="Container/ViewportContainer/MaterialPreview" index="0"]
transform = Transform( -0.989989, 0, 0.141142, 0, 1, 0, -0.141142, 0, -0.989989, 0, 0, 0 )
transform = Transform( -0.978305, 0, 0.207164, 0, 1, 0, -0.207164, 0, -0.978305, 0, 0, 0 )
_sections_unfolded = [ "Transform" ]
[node name="Cube" type="MeshInstance" parent="Container/ViewportContainer/MaterialPreview/Objects" index="0"]
@ -569,7 +579,7 @@ lod_max_distance = 0.0
lod_max_hysteresis = 0.0
mesh = SubResource( 4 )
skeleton = NodePath("..")
material/0 = null
material/0 = SubResource( 6 )
_sections_unfolded = [ "Geometry", "Transform", "material" ]
[node name="Cylinder" type="MeshInstance" parent="Container/ViewportContainer/MaterialPreview/Objects" index="1"]
@ -584,9 +594,9 @@ lod_min_distance = 0.0
lod_min_hysteresis = 0.0
lod_max_distance = 0.0
lod_max_hysteresis = 0.0
mesh = SubResource( 5 )
mesh = SubResource( 7 )
skeleton = NodePath("..")
material/0 = null
material/0 = SubResource( 6 )
_sections_unfolded = [ "Geometry", "Transform", "material" ]
[node name="AnimationPlayer" type="AnimationPlayer" parent="Container/ViewportContainer/MaterialPreview" index="1"]
@ -596,7 +606,7 @@ autoplay = "rotate"
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 0.1
anims/rotate = SubResource( 6 )
anims/rotate = SubResource( 8 )
blend_times = [ ]
_sections_unfolded = [ "Playback Options" ]
@ -628,7 +638,7 @@ _sections_unfolded = [ "Shadow" ]
transform = Transform( 1, 0, 0, 0, 0.766044, 0.642787, 0, -0.642787, 0.766044, 0, 1.83022, 2.2549 )
keep_aspect = 1
cull_mask = 1048575
environment = SubResource( 8 )
environment = SubResource( 10 )
h_offset = 0.0
v_offset = 0.0
doppler_tracking = 0
@ -642,7 +652,7 @@ _sections_unfolded = [ "Transform" ]
[node name="SelectedPreview" type="ColorRect" parent="Container/ViewportContainer" index="1"]
material = SubResource( 10 )
material = SubResource( 12 )
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
@ -673,7 +683,7 @@ hdr = true
disable_3d = false
usage = 2
debug_draw = 0
render_target_v_flip = false
render_target_v_flip = true
render_target_clear_mode = 0
render_target_update_mode = 1
audio_listener_enable_2d = false
@ -690,7 +700,7 @@ _sections_unfolded = [ "GUI", "Render Target" ]
[node name="ColorRect" type="ColorRect" parent="SaveViewport" index="0"]
material = SubResource( 12 )
material = SubResource( 14 )
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
@ -704,7 +714,7 @@ mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
color = Color( 1, 1, 1, 1 )
_sections_unfolded = [ "Material" ]
_sections_unfolded = [ "Material", "Rect" ]
[node name="Timer" type="Timer" parent="SaveViewport" index="1"]

BIN
examples/input_image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -0,0 +1,29 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/input_image.png-6f289ee4d1d220cf5c592c556aa83e9e.stex"
[deps]
source_file="res://examples/input_image.png"
dest_files=[ "res://.import/input_image.png-6f289ee4d1d220cf5c592c556aa83e9e.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 KiB

After

Width:  |  Height:  |  Size: 20 KiB