diff --git a/addons/procedural_material/material_preview.gd b/addons/procedural_material/material_preview.gd new file mode 100644 index 0000000..6b7cf18 --- /dev/null +++ b/addons/procedural_material/material_preview.gd @@ -0,0 +1,11 @@ +tool +extends Viewport + +var material = null + +func _ready(): + material = ShaderMaterial.new() + material.shader = Shader.new() + $Objects/Cube.set_surface_material(0, material) + $Objects/Cylinder.set_surface_material(0, material) + $AnimationPlayer.play("rotate") diff --git a/addons/procedural_material/nodes/bricks.gd b/addons/procedural_material/nodes/bricks.gd index b22f2f3..a573ee7 100644 --- a/addons/procedural_material/nodes/bricks.gd +++ b/addons/procedural_material/nodes/bricks.gd @@ -22,6 +22,3 @@ func get_shader_code(uv): rv.code = "float "+name+"_"+str(variant_index)+"_f = "+name+"_f("+uv+");\n" rv.f = name+"_"+str(variant_index)+"_f" return rv - -func _get_state_variables(): - return [ "rows", "columns", "row_offset", "mortar", "bevel" ] diff --git a/addons/procedural_material/nodes/perlin.gd b/addons/procedural_material/nodes/perlin.gd index f619446..9c6e156 100644 --- a/addons/procedural_material/nodes/perlin.gd +++ b/addons/procedural_material/nodes/perlin.gd @@ -1,17 +1,19 @@ tool extends "res://addons/procedural_material/node_base.gd" +var scale_x +var scale_y var iterations -var turbulence +var persistance func _ready(): set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) - initialize_properties([ $GridContainer/iterations, $GridContainer/turbulence ]) + initialize_properties([ $GridContainer/scale_x, $GridContainer/scale_y, $GridContainer/iterations, $GridContainer/persistance ]) func get_shader_code(uv): var rv = { defs="", code="" } if generated_variants.empty(): - rv.defs = "float "+name+"_f(vec2 uv) { return perlin(uv, "+str(iterations)+", "+str(turbulence)+"); }\n" + rv.defs = "float "+name+"_f(vec2 uv) { return perlin(uv, vec2("+str(scale_x)+", "+str(scale_y)+"), "+str(iterations)+", "+str(persistance)+"); }\n" var variant_index = generated_variants.find(uv) if variant_index == -1: variant_index = generated_variants.size() diff --git a/addons/procedural_material/nodes/perlin.tscn b/addons/procedural_material/nodes/perlin.tscn index 188d429..c747a6f 100644 --- a/addons/procedural_material/nodes/perlin.tscn +++ b/addons/procedural_material/nodes/perlin.tscn @@ -2,7 +2,6 @@ [ext_resource path="res://addons/procedural_material/nodes/perlin.gd" type="Script" id=1] - [sub_resource type="Theme" id=1] @@ -14,8 +13,8 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 1.0 margin_top = 2.0 -margin_right = 166.0 -margin_bottom = 83.0 +margin_right = 189.0 +margin_bottom = 139.0 rect_pivot_offset = Vector2( 0, 0 ) rect_clip_content = false mouse_filter = 1 @@ -47,8 +46,8 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 16.0 margin_top = 24.0 -margin_right = 149.0 -margin_bottom = 76.0 +margin_right = 172.0 +margin_bottom = 132.0 rect_pivot_offset = Vector2( 0, 0 ) rect_clip_content = false mouse_filter = 1 @@ -64,7 +63,7 @@ anchor_top = 0.0 anchor_right = 0.0 anchor_bottom = 0.0 margin_top = 5.0 -margin_right = 71.0 +margin_right = 78.0 margin_bottom = 19.0 rect_pivot_offset = Vector2( 0, 0 ) rect_clip_content = false @@ -72,80 +71,180 @@ mouse_filter = 2 mouse_default_cursor_shape = 0 size_flags_horizontal = 1 size_flags_vertical = 4 +text = "Scale X:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="scale_x" type="SpinBox" parent="GridContainer" index="1"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 82.0 +margin_right = 156.0 +margin_bottom = 24.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +mouse_default_cursor_shape = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +min_value = 0.0 +max_value = 32.0 +step = 1.0 +page = 0.0 +value = 4.0 +exp_edit = false +rounded = false +editable = true +prefix = "" +suffix = "" +_sections_unfolded = [ "Caret", "Placeholder" ] + +[node name="Label2" type="Label" parent="GridContainer" index="2"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 33.0 +margin_right = 78.0 +margin_bottom = 47.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 = "Scale Y:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="scale_y" type="SpinBox" parent="GridContainer" index="3"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 82.0 +margin_top = 28.0 +margin_right = 156.0 +margin_bottom = 52.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +mouse_default_cursor_shape = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +min_value = 0.0 +max_value = 32.0 +step = 1.0 +page = 0.0 +value = 4.0 +exp_edit = false +rounded = false +editable = true +prefix = "" +suffix = "" +_sections_unfolded = [ "Caret", "Placeholder" ] + +[node name="Label3" type="Label" parent="GridContainer" index="4"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 61.0 +margin_right = 78.0 +margin_bottom = 75.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 = "Iterations:" percent_visible = 1.0 lines_skipped = 0 max_lines_visible = -1 -[node name="iterations" type="LineEdit" parent="GridContainer" index="1"] +[node name="iterations" type="SpinBox" parent="GridContainer" index="5"] anchor_left = 0.0 anchor_top = 0.0 anchor_right = 0.0 anchor_bottom = 0.0 -margin_left = 75.0 -margin_right = 133.0 -margin_bottom = 24.0 +margin_left = 82.0 +margin_top = 56.0 +margin_right = 156.0 +margin_bottom = 80.0 rect_pivot_offset = Vector2( 0, 0 ) rect_clip_content = false -focus_mode = 2 mouse_filter = 0 -mouse_default_cursor_shape = 1 +mouse_default_cursor_shape = 0 size_flags_horizontal = 1 size_flags_vertical = 1 -text = "3" -focus_mode = 2 -context_menu_enabled = true -placeholder_alpha = 0.6 -caret_blink = false -caret_blink_speed = 0.65 -caret_position = 0 +min_value = 1.0 +max_value = 10.0 +step = 1.0 +page = 0.0 +value = 3.0 +exp_edit = false +rounded = false +editable = true +prefix = "" +suffix = "" _sections_unfolded = [ "Caret", "Placeholder" ] -[node name="Label2" type="Label" parent="GridContainer" index="2"] +[node name="Label4" type="Label" parent="GridContainer" index="6"] anchor_left = 0.0 anchor_top = 0.0 anchor_right = 0.0 anchor_bottom = 0.0 -margin_top = 33.0 -margin_right = 71.0 -margin_bottom = 47.0 +margin_top = 89.0 +margin_right = 78.0 +margin_bottom = 103.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 = "Turbulence" +text = "Persistance:" percent_visible = 1.0 lines_skipped = 0 max_lines_visible = -1 -[node name="turbulence" type="LineEdit" parent="GridContainer" index="3"] +[node name="persistance" type="SpinBox" parent="GridContainer" index="7"] anchor_left = 0.0 anchor_top = 0.0 anchor_right = 0.0 anchor_bottom = 0.0 -margin_left = 75.0 -margin_top = 28.0 -margin_right = 133.0 -margin_bottom = 52.0 +margin_left = 82.0 +margin_top = 84.0 +margin_right = 156.0 +margin_bottom = 108.0 rect_pivot_offset = Vector2( 0, 0 ) rect_clip_content = false -focus_mode = 2 mouse_filter = 0 -mouse_default_cursor_shape = 1 +mouse_default_cursor_shape = 0 size_flags_horizontal = 1 size_flags_vertical = 1 -text = "0.5" -focus_mode = 2 -context_menu_enabled = true -placeholder_alpha = 0.6 -caret_blink = false -caret_blink_speed = 0.65 -caret_position = 0 +min_value = 0.0 +max_value = 1.0 +step = 0.05 +page = 0.0 +value = 0.5 +exp_edit = false +rounded = false +editable = true +prefix = "" +suffix = "" _sections_unfolded = [ "Caret", "Placeholder" ] [connection signal="close_request" from="." to="." method="queue_free"] diff --git a/addons/procedural_material/nodes/transform.gd b/addons/procedural_material/nodes/transform.gd index 4924d1e..e496d4e 100644 --- a/addons/procedural_material/nodes/transform.gd +++ b/addons/procedural_material/nodes/transform.gd @@ -1,11 +1,12 @@ tool extends "res://addons/procedural_material/node_base.gd" -var angle = 0.0 +var rotate = 0.0 +var scale = 0.0 func _ready(): set_slot(0, true, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) - initialize_properties([ $rotate ]) + initialize_properties([ $GridContainer/rotate, $GridContainer/scale ]) func get_shader_code(uv): var rv = { defs="", code="" } @@ -15,7 +16,7 @@ func get_shader_code(uv): rv.uv = name+"_uv("+uv+")" var src_code = src.get_shader_code(rv.uv) if !generated: - rv.defs = src_code.defs+"vec2 "+name+"_uv(vec2 uv) { return rotate(uv, "+str(angle)+"); }\n" + rv.defs = src_code.defs+"vec2 "+name+"_uv(vec2 uv) { return transform(uv, "+str(3.1415928*rotate/180.0)+", "+str(scale)+"); }\n" generated = true rv.code = src_code.code; if src_code.has("f"): @@ -23,7 +24,3 @@ func get_shader_code(uv): if src_code.has("rgb"): rv.rgb = src_code.rgb return rv - -func _on_Rotate_text_changed(new_text): - angle = float(new_text)*3.1415928/180.0 - get_parent().get_parent().generate_shader() diff --git a/addons/procedural_material/nodes/transform.tscn b/addons/procedural_material/nodes/transform.tscn index 083824a..1f6383c 100644 --- a/addons/procedural_material/nodes/transform.tscn +++ b/addons/procedural_material/nodes/transform.tscn @@ -38,7 +38,7 @@ slot/0/right_color = Color( 0.5, 0.5, 1, 1 ) script = ExtResource( 1 ) _sections_unfolded = [ "Theme" ] -[node name="rotate" type="LineEdit" parent="." index="0"] +[node name="GridContainer" type="GridContainer" parent="." index="0"] anchor_left = 0.0 anchor_top = 0.0 @@ -46,26 +46,111 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 16.0 margin_top = 24.0 -margin_right = 93.0 -margin_bottom = 48.0 +margin_right = 139.0 +margin_bottom = 76.0 rect_pivot_offset = Vector2( 0, 0 ) rect_clip_content = false -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 1 +mouse_filter = 1 +mouse_default_cursor_shape = 0 size_flags_horizontal = 1 size_flags_vertical = 1 -text = "0" -focus_mode = 2 -context_menu_enabled = true -placeholder_alpha = 0.6 -caret_blink = false -caret_blink_speed = 0.65 -caret_position = 0 +columns = 2 + +[node name="Label1" type="Label" parent="GridContainer" index="0"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 5.0 +margin_right = 45.0 +margin_bottom = 19.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 = "Rotate:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="rotate" type="SpinBox" parent="GridContainer" index="1"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 49.0 +margin_right = 123.0 +margin_bottom = 24.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +mouse_default_cursor_shape = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +min_value = 0.0 +max_value = 360.0 +step = 5.0 +page = 0.0 +value = 0.0 +exp_edit = false +rounded = false +editable = true +prefix = "" +suffix = "" +_sections_unfolded = [ "Caret", "Placeholder" ] + +[node name="Label2" type="Label" parent="GridContainer" index="2"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_top = 33.0 +margin_right = 45.0 +margin_bottom = 47.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 = "Scale:" +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="scale" type="SpinBox" parent="GridContainer" index="3"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 49.0 +margin_top = 28.0 +margin_right = 123.0 +margin_bottom = 52.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +mouse_default_cursor_shape = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +min_value = 0.05 +max_value = 50.0 +step = 0.05 +page = 0.0 +value = 1.0 +exp_edit = false +rounded = false +editable = true +prefix = "" +suffix = "" _sections_unfolded = [ "Caret", "Placeholder" ] [connection signal="close_request" from="." to="." method="queue_free"] -[connection signal="text_changed" from="rotate" to="." method="_on_Rotate_text_changed"] - diff --git a/addons/procedural_material/pm_editor.gd b/addons/procedural_material/pm_editor.gd index c53e8d1..65edd4c 100644 --- a/addons/procedural_material/pm_editor.gd +++ b/addons/procedural_material/pm_editor.gd @@ -10,6 +10,7 @@ var texture_preview_shader = null const MENU = [ { command="load_texture", description="Load texture" }, { command="save_texture", description="Save texture" }, + { command="export_texture", description="Export texture" }, { name="sine", description="Sine" }, { name="bricks", description="Bricks" }, { name="iqnoise", description="IQ Noise" }, @@ -22,16 +23,14 @@ const MENU = [ ] func _ready(): - # Duplicate the materials we'll modify and store the shaders - $Container/ViewportContainer/Viewport/Cube.set_surface_material(0, $Container/ViewportContainer/Viewport/Cube.get_surface_material(0).duplicate(true)) - material_preview_shader = $Container/ViewportContainer/Viewport/Cube.get_surface_material(0).shader + # Duplicate the material we'll modify and store the shaders + material_preview_shader = $Container/ViewportContainer/MaterialPreview.material.shader $Container/ViewportContainer/SelectedPreview.material = $Container/ViewportContainer/SelectedPreview.material.duplicate(true) texture_preview_shader = $Container/ViewportContainer/SelectedPreview.material.shader $GraphEdit.add_valid_connection_type(0, 0) $GraphEdit/PopupMenu.clear() for i in MENU.size(): $GraphEdit/PopupMenu.add_item(MENU[i].description, i) - $Container/ViewportContainer/Viewport/AnimationPlayer.play("rotate") func _on_GraphEdit_popup_request(position): popup_position = position @@ -108,6 +107,21 @@ func save_file(filename): file.store_string(to_json(data)) file.close() +func export_texture(): + var size = 1024 + $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)) + $SaveViewport.render_target_update_mode = Viewport.UPDATE_ONCE + #$SaveViewport/ColorRect.update() + $SaveViewport.update_worlds() + $SaveViewport/Timer.start() + 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") + func generate_shader(): material_preview_shader.set_code($GraphEdit.generate_shader($GraphEdit/Material, 1)) if selected_node != null: diff --git a/addons/procedural_material/pm_editor.tscn b/addons/procedural_material/pm_editor.tscn index b0dc922..1958407 100644 --- a/addons/procedural_material/pm_editor.tscn +++ b/addons/procedural_material/pm_editor.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=15 format=2] +[gd_scene load_steps=17 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] [sub_resource type="ProceduralSky" id=1] @@ -116,27 +117,22 @@ subdivide_width = 0 subdivide_height = 0 subdivide_depth = 0 -[sub_resource type="Shader" id=5] +[sub_resource type="CylinderMesh" id=5] -code = "shader_type spatial; +custom_aabb = AABB( 0, 0, 0, 0, 0, 0 ) +top_radius = 1.0 +bottom_radius = 1.0 +height = 2.0 +radial_segments = 64 +rings = 4 -void fragment() { - ALBEDO = vec3(1.0); -} -" - -[sub_resource type="ShaderMaterial" id=6] - -render_priority = 0 -shader = SubResource( 5 ) - -[sub_resource type="Animation" id=7] +[sub_resource type="Animation" id=6] length = 1.0 loop = true step = 0.1 tracks/0/type = "value" -tracks/0/path = NodePath("Cube:rotation_degrees") +tracks/0/path = NodePath("Objects:rotation_degrees") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/imported = false @@ -148,7 +144,7 @@ tracks/0/keys = { "values": [ Vector3( 0, 0, 0 ), Vector3( 0, 360, 0 ) ] } -[sub_resource type="ProceduralSky" id=8] +[sub_resource type="ProceduralSky" id=7] radiance_size = 4 sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) @@ -169,10 +165,10 @@ sun_energy = 16.0 texture_size = 2 _sections_unfolded = [ "Sky" ] -[sub_resource type="Environment" id=9] +[sub_resource type="Environment" id=8] background_mode = 2 -background_sky = SubResource( 8 ) +background_sky = SubResource( 7 ) background_sky_custom_fov = 0.0 background_color = Color( 0, 0, 0, 1 ) background_energy = 1.0 @@ -249,7 +245,7 @@ adjustment_contrast = 1.0 adjustment_saturation = 1.0 _sections_unfolded = [ "Background" ] -[sub_resource type="Shader" id=10] +[sub_resource type="Shader" id=9] code = "shader_type canvas_item; @@ -259,10 +255,146 @@ void fragment() { " _sections_unfolded = [ "Resource" ] -[sub_resource type="ShaderMaterial" id=11] +[sub_resource type="ShaderMaterial" id=10] render_priority = 0 -shader = SubResource( 10 ) +shader = SubResource( 9 ) + +[sub_resource type="Shader" id=11] + +code = "shader_type canvas_item; + +float hash1(vec2 p) { + float q = dot(p,vec2(127.1,311.7)); + return fract(sin(q)*43758.5453); +} + +vec2 hash2(vec2 p) { + vec2 q = vec2( dot(p,vec2(127.1,311.7)), + dot(p,vec2(269.5,183.3)) ); + return fract(sin(q)*43758.5453); +} + +vec3 hash3(vec2 p) { + vec3 q = vec3( dot(p,vec2(127.1,311.7)), + dot(p,vec2(269.5,183.3)), + dot(p,vec2(419.2,371.9)) ); + return fract(sin(q)*43758.5453); +} + +float sine(vec2 uv, float count, float sharpness) { + return max(0.0, min(1.0, (0.5+sharpness*0.5*sin(count*3.1415928*2.0*uv.x)))); +} + +vec2 transform(vec2 uv, float rotate, float scale) { + vec2 rv; + uv -= vec2(0.5); + rv.x = cos(rotate)*uv.x + sin(rotate)*uv.y; + rv.y = -sin(rotate)*uv.x + cos(rotate)*uv.y; + rv /= scale; + rv += vec2(0.5); + return rv; +} + +float bricks(vec2 uv, vec2 count, float offset, float mortar, float bevel) { + mortar /= max(count.x, count.y); + bevel /= max(count.x, count.y); + float fract_x = fract(uv.x*count.x+offset*step(0.5, fract(uv.y*count.y*0.5))); + float slope_x = 1.0/(bevel*count.x); + float off = 0.5*mortar/bevel; + float f1 = fract_x*slope_x-off; + float f2 = (1.0-fract_x)*slope_x-off; + float fract_y = fract(uv.y*count.y); + float slope_y = 1.0/(bevel*count.y); + float f3 = fract_y*slope_y-off; + float f4 = (1.0-fract_y)*slope_y-off; + return max(0.0, min(1.0, min(min(f1, f2), min(f3, f4)))); +} + +float colored_bricks(vec2 uv, vec2 count, float offset) { + float x = floor(uv.x*count.x+offset*step(0.5, fract(uv.y*count.y*0.5))); + float y = floor(uv.y*count.y); + return fract(x/3.0+y/7.0); +} + +float iqnoise(vec2 uv, float s, float u, float v) { + uv *= s; + vec2 p = floor(uv); + vec2 f = fract(uv); + + float k = 1.0+63.0*pow(1.0-v,4.0); + + float va = 0.0; + float wt = 0.0; + for( int j=-2; j<=2; j++ ) + for( int i=-2; i<=2; i++ ) + { + vec2 g = vec2( float(i),float(j) ); + vec3 o = hash3( p + g )*vec3(u,u,1.0); + vec2 r = g - f + o.xy; + float d = dot(r,r); + float ww = pow( 1.0-smoothstep(0.0,1.414,sqrt(d)), k ); + va += o.z*ww; + wt += ww; + } + + return va/wt; +} + +float perlin_old(vec2 uv, vec2 scale, int iterations, float turbulence) { + float f = 0.0; + float c = 1.0; + float m = 0.0; + for(int i = 0; i < iterations; i++) { + vec2 uv2 = scale * mod(uv, vec2(1.0, 1.0)); + vec2 uv2_floor = floor(uv2); + vec2 uv2_fract = fract(uv2); + f += c * ( (1.0 - uv2_fract.x) * ((1.0 - uv2_fract.y) * hash1(uv2_floor) + uv2_fract.y * hash1(uv2_floor+vec2(0.0, 1.0))) + + uv2_fract.x * ((1.0 - uv2_fract.y) * hash1(uv2_floor+vec2(1.0, 0.0)) + uv2_fract.y * hash1(uv2_floor+vec2(1.0, 1.0)))); + m += c; + scale *= 2.0; + c *= turbulence; + } + return f/m; +} + +float noise(vec2 p, vec2 freq ){ + vec2 unit = vec2(1.0)/freq; + vec2 ij = floor(p/unit); + vec2 xy = mod(p,unit)/unit; + float a = hash1((ij+vec2(0.0,0.0))); + float b = hash1((ij+vec2(1.0,0.0))); + float c = hash1((ij+vec2(0.0,1.0))); + float d = hash1((ij+vec2(1.0,1.0))); + return mix(mix(a, b, xy.x), mix(c, d, xy.x), xy.y); +} + +float perlin(vec2 p, vec2 scale, int iterations, float persistance) { + float n = 0.0; + float normK = 0.0; + vec2 f = scale; + float amp = 1.0; + for (int i = 0; i