diff --git a/materials/shader/VoronoiBasedBiomes2D.gdshader b/materials/shader/VoronoiBasedBiomes2D.gdshader new file mode 100644 index 0000000..275df8d --- /dev/null +++ b/materials/shader/VoronoiBasedBiomes2D.gdshader @@ -0,0 +1,122 @@ +shader_type canvas_item; + +uniform vec4 DeepWaterColor : hint_color = vec4(0, 0, 0.6, 1); +uniform vec4 WaterColor : hint_color = vec4(0, 0, 0.7, 1); +uniform vec4 LightWaterColor : hint_color = vec4(0, 0, 1, 1); +uniform vec4 SandColor : hint_color = vec4(0.8, 0.8, 0.1, 1); +uniform vec4 GrassColor : hint_color = vec4(0, 0.6, 0, 1); +uniform vec4 ForestColor : hint_color = vec4(0, 0.4, 0, 1); +uniform vec4 RockColor : hint_color = vec4(0.5, 0.5, 0.4, 1); +uniform vec4 SnowColor : hint_color = vec4(1); + +vec2 rand2d(vec2 uv) { + return vec2(fract(sin(dot(uv.xy, + vec2(12.9898,78.233))) * 43758.5453123)); +} + +float rand1d(vec2 uv){ + return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453); +} + +vec2 voronoi_segment(vec2 uv, float columns, float rows) { + vec2 index_uv = floor(vec2(uv.x * columns, uv.y * rows)); + vec2 fract_uv = fract(vec2(uv.x * columns, uv.y * rows)); + + float minimum_dist = 1.0; + vec2 minimum_point; + vec2 minimum_neighbour; + + for (int y = -1; y <= 1; y++) { + for (int x = -1; x <= 1; x++) { + vec2 neighbour = vec2(float(x), float(y)); + vec2 point = rand2d(index_uv + neighbour); + + vec2 diff = neighbour + point - fract_uv; + float dist = length(diff); + + if (dist < minimum_dist) { + minimum_dist = dist; + minimum_point = point; + minimum_neighbour = neighbour; + } + } + } + + return minimum_point; +} + +ivec2 voronoiCellId(vec2 uv, vec2 grid_size) { + vec2 index_uv = floor(uv * grid_size); + vec2 fract_uv = fract(uv * grid_size); + + float minimum_dist = 1.0; + vec2 minimum_point; + vec2 minimum_neighbour; + + for (int y = -1; y <= 1; y++) { + for (int x = -1; x <= 1; x++) { + vec2 neighbour = vec2(float(x), float(y)); + vec2 point = rand2d(index_uv + neighbour); + + vec2 diff = neighbour + point - fract_uv; + float dist = length(diff); + + if (dist < minimum_dist) { + minimum_dist = dist; + minimum_point = point; + minimum_neighbour = index_uv + neighbour; + } + } + } + + return ivec2(minimum_neighbour); +} + +void fragment() { + // float worley = worley(UV, 6.0, 6.0); + + int biome_count = 4; + float big_columns = 0.2; + float big_rows = 0.2; + + float columns = 0.1; + float rows = 0.1; + vec2 uv = UV / 0.01; + vec2 offset = vec2(sin(TIME * 0.1), cos(TIME * 0.1)); + + uv += offset; + vec2 index_uv = floor(vec2(uv.x * columns, uv.y * rows)); + vec2 segment_big = voronoi_segment(uv + offset + vec2(1.0, 3.0), big_columns, big_rows); + + int biome_big = int(floor(rand1d(segment_big) * float(5))); + vec2 segment = voronoi_segment(uv + offset, columns, rows); + + // segment = index_uv; + int biome_id = int(ceil(rand1d(segment) * float(biome_count))); + if (biome_big < 4) { + biome_id = 0; + } + + int cell_rows = 6; + int cell_cols = 6; + ivec2 cellId = voronoiCellId(uv + offset, vec2(0.125, 0.125)); + vec4 water_land_value = rand1d(vec2(cellId)) < 0.66 ? GrassColor : DeepWaterColor; + + COLOR = water_land_value; + + // COLOR = vec4(float((cellId.x)) * 0.01, 0.0, 0.0, 1.0); + +// if (biome_id == 0) { +// COLOR = DeepWaterColor; +// } else if (biome_id == 1) { +// COLOR = GrassColor; +// } else if (biome_id == 2) { +// COLOR = SandColor; +// } else if (biome_id == 3) { +// COLOR = RockColor; +// } else if (biome_id == 4) { +// COLOR = SnowColor; +// } else { +// COLOR = vec4(float(biome_id) / float(biome_count), 0.0, 0.0, 1.0); +// } +} \ No newline at end of file diff --git a/scenes/VoronoiBasedBiomes2D.tscn b/scenes/VoronoiBasedBiomes2D.tscn new file mode 100644 index 0000000..4f35a9f --- /dev/null +++ b/scenes/VoronoiBasedBiomes2D.tscn @@ -0,0 +1,23 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://icon.png" type="Texture" id=1] +[ext_resource path="res://materials/shader/VoronoiBasedBiomes2D.gdshader" type="Shader" id=2] + +[sub_resource type="ShaderMaterial" id=2] +shader = ExtResource( 2 ) +shader_param/DeepWaterColor = Color( 0, 0, 0.6, 1 ) +shader_param/WaterColor = Color( 0, 0, 0.7, 1 ) +shader_param/LightWaterColor = Color( 0, 0, 1, 1 ) +shader_param/SandColor = Color( 0.8, 0.8, 0.1, 1 ) +shader_param/GrassColor = Color( 0, 0.6, 0, 1 ) +shader_param/ForestColor = Color( 0, 0.4, 0, 1 ) +shader_param/RockColor = Color( 0.5, 0.5, 0.4, 1 ) +shader_param/SnowColor = Color( 1, 1, 1, 1 ) + +[node name="Node2D" type="Node2D"] + +[node name="Sprite" type="Sprite" parent="."] +material = SubResource( 2 ) +position = Vector2( 195, 368 ) +scale = Vector2( 5.89062, 5.29688 ) +texture = ExtResource( 1 )