diff --git a/Zennysoft.Game.Ma/src/map/dungeon/floors/Floor 00 Sky.gdshader b/Zennysoft.Game.Ma/src/map/dungeon/floors/Floor 00 Sky.gdshader new file mode 100644 index 00000000..9f9f29f6 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/floors/Floor 00 Sky.gdshader @@ -0,0 +1,290 @@ +shader_type sky; +render_mode use_quarter_res_pass; + +// Originaly based on https://godotshaders.com/shader/stylized-sky-shader-with-clouds/ but there's not much left + +group_uniforms sky; + uniform vec3 day_top_color : source_color = vec3( 0.1, 0.6, 1.0 ); + uniform vec3 day_bottom_color : source_color = vec3( 0.4, 0.8, 1.0 ); + uniform vec3 sunset_top_color : source_color = vec3( 0.7, 0.75, 1.0 ); + uniform vec3 sunset_bottom_color : source_color = vec3( 1.0, 0.5, 0.7 ); + uniform vec3 night_top_color : source_color = vec3( 0.02, 0.0, 0.04 ); + uniform vec3 night_bottom_color : source_color = vec3( 0.1, 0.0, 0.2 ); + +group_uniforms horizon; + uniform vec3 horizon_color : source_color = vec3( 0.0, 0.7, 0.8 ); + uniform float horizon_blur : hint_range( 0.0, 1.0, 0.01 ) = 0.05; + +group_uniforms sun; // First DirectionalLight3D will be the sun + uniform vec3 sun_color : source_color = vec3( 10.0, 8.0, 1.0 ); + uniform vec3 sun_sunset_color : source_color = vec3( 10.0, 0.0, 0.0 ); + uniform float sun_size : hint_range( 0.01, 1.0 ) = 0.2; + uniform float sun_blur : hint_range( 0.01, 20.0 ) = 10.0; + +group_uniforms moon; // Second DirectionalLight3D will be the moon + uniform vec3 moon_color : source_color = vec3( 1.0, 0.95, 0.7 ); + uniform float moon_size : hint_range( 0.01, 1.0 ) = 0.06; + uniform float moon_blur : hint_range( 0.01, 10.0 ) = 0.1; + +group_uniforms clouds; + // Replaced by noise functions, unncomment if you want to use graphical textures +// uniform sampler2D clouds_top_texture : filter_linear_mipmap, hint_default_black; +// uniform sampler2D clouds_middle_texture : filter_linear_mipmap, hint_default_black; +// uniform sampler2D clouds_bottom_texture : filter_linear_mipmap, hint_default_black; + uniform vec3 clouds_edge_color : source_color = vec3( 0.8, 0.8, 0.98 ); + uniform vec3 clouds_top_color : source_color = vec3( 1.0, 1.0, 1.00 ); + uniform vec3 clouds_middle_color : source_color = vec3( 0.92, 0.92, 0.98 ); + uniform vec3 clouds_bottom_color : source_color = vec3( 0.83, 0.83, 0.94 ); + uniform float clouds_speed : hint_range( 0.0, 20.0, 0.01 ) = 2.0; + uniform float clouds_direction : hint_range( -0.5, 0.5, 0.0 ) = 0.2; + uniform float clouds_scale : hint_range( 0.0, 4.0, 0.01 ) = 1.0; + uniform float clouds_cutoff : hint_range( 0.0, 1.0, 0.01 ) = 0.3; + uniform float clouds_fuzziness : hint_range( 0.0, 2.0, 0.01 ) = 0.5; + // More weight is simply a darker color, usefull for rain/storm + uniform float clouds_weight : hint_range( 0.0, 1.0, 0.01 ) = 0.0; + uniform float clouds_blur : hint_range( 0.0, 1.0, 0.01 ) = 0.25; + +group_uniforms stars; + // Stars should be at black background + uniform sampler2D stars_texture : filter_linear_mipmap, hint_default_black; + uniform float stars_speed : hint_range( 0.0, 20.0, 0.01 ) = 1.0; + +group_uniforms settings; + uniform float overwritten_time = 0.0; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + // Function for clouds noises. You can replace using "gen_fractal_ping_pong" with a simple texture reading. + // I was frustrated with the repeating texture that's why I included the algorithm in the code. + // Source: https://github.com/Auburn/FastNoiseLite/tree/master + const int PRIME_X = 501125321; + const int PRIME_Y = 1136930381; + float lerp( float a, float b, float t ) + { + return a + t * ( b - a ); + } + float cubic_lerp( float a, float b, float c, float d, float t ) + { + float p = d - c - ( a - b ); + return t * t * t * p + t * t * ( a - b - p ) + t * ( c - a ) + b; + } + float ping_pong( float t ) + { + t -= trunc( t * 0.5 ) * 2.0; + return t < 1.0 ? t : 2.0 - t; + } + int hash( int seed, int x_primed, int y_primed ) + { + return ( seed ^ x_primed ^ y_primed ) * 0x27d4eb2d; + } + float val_coord( int seed, int x_primed, int y_primed ) + { + int hash = hash( seed, x_primed, y_primed ); + hash *= hash; + hash ^= hash << 19; + return float( hash ) * ( 1.0 / 2147483648.0 ); + } + float single_value_cubic( int seed, float x, float y ) + { + int x1 = int( floor( x )); + int y1 = int( floor( y )); + + float xs = x - float( x1 ); + float ys = y - float( y1 ); + + x1 *= PRIME_X; + y1 *= PRIME_Y; + int x0 = x1 - PRIME_X; + int y0 = y1 - PRIME_Y; + int x2 = x1 + PRIME_X; + int y2 = y1 + PRIME_Y; + int x3 = x1 + ( PRIME_X << 1 ); + int y3 = y1 + ( PRIME_Y << 1 ); + + return cubic_lerp( + cubic_lerp( val_coord( seed, x0, y0 ), val_coord( seed, x1, y0 ), val_coord( seed, x2, y0 ), val_coord( seed, x3, y0 ), xs ), + cubic_lerp( val_coord( seed, x0, y1 ), val_coord( seed, x1, y1 ), val_coord( seed, x2, y1 ), val_coord( seed, x3, y1 ), xs ), + cubic_lerp( val_coord( seed, x0, y2 ), val_coord( seed, x1, y2 ), val_coord( seed, x2, y2 ), val_coord( seed, x3, y2 ), xs ), + cubic_lerp( val_coord( seed, x0, y3 ), val_coord( seed, x1, y3 ), val_coord( seed, x2, y3 ), val_coord( seed, x3, y3 ), xs ), + ys ) * ( 1.0 / ( 1.5 * 1.5 )); + } + // Params can be change in the same way as in noise settings in Godot + const float FRACTAL_BOUNDING = 1.0 / 1.75; + const int OCTAVES = 5; + const float PING_PONG_STRENGTH = 2.0; + const float WEIGHTED_STRENGTH = 0.0; + const float GAIN = 0.5; + const float LACUNARITY = 2.0; + float gen_fractal_ping_pong( vec2 pos, int seed, float frequency ) + { + float x = pos.x * frequency; + float y = pos.y * frequency; + float sum = 0.0; + float amp = FRACTAL_BOUNDING; + for( int i = 0; i < OCTAVES; i++ ) + { + float noise = ping_pong(( single_value_cubic( seed++, x, y ) + 1.0 ) * PING_PONG_STRENGTH ); + sum += ( noise - 0.5 ) * 2.0 * amp; + amp *= lerp( 1.0, noise, WEIGHTED_STRENGTH ); + x *= LACUNARITY; + y *= LACUNARITY; + amp *= GAIN; + } + return sum * 0.5 + 0.5; + } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// Function needed to calculate the phase of the moon +// Source: https://kelvinvanhoorn.com/2022/03/17/skybox-tutorial-part-1/ +float sphere_intersect( vec3 view_dir, vec3 sphere_pos, float radius ) +{ + float b = dot( -sphere_pos, view_dir ); + float c = dot( -sphere_pos, -sphere_pos ) - pow( radius, 2 ); + float h = pow( b, 2 ) - c; + return h < 0.0 ? -1.0 : -b - sqrt( h ); +} + +void sky() +{ + float time = overwritten_time != 0.0 ? overwritten_time : TIME; + + //////////////////// SKY /////////////////////////////////////////////////////////////////////// + float _eyedir_y = abs( sin( EYEDIR.y * PI * 0.5 )); + + // The day color will be our base color + vec3 _sky_color = mix( day_bottom_color, day_top_color, _eyedir_y ); + _sky_color = mix( _sky_color, vec3( 0.0 ), clamp(( 0.7 - clouds_cutoff ) * clouds_weight, 0.0, 1.0 )); + + float _sunset_amount = clamp( 0.5 - abs( LIGHT0_DIRECTION.y ), 0.0, 0.5 ) * 2.0; + // The sky should be more red around the west, on the opposite side you don't see it as much + float _sunset_distance = clamp( 1.0 - pow( distance( EYEDIR, LIGHT0_DIRECTION ), 2 ), 0.0, 1.0 ); + vec3 _sky_sunset_color = mix( sunset_bottom_color, sunset_top_color, _eyedir_y + 0.5 ); + _sky_sunset_color = mix( _sky_sunset_color, sunset_bottom_color, _sunset_amount * _sunset_distance ); + _sky_color = mix( _sky_color, _sky_sunset_color, _sunset_amount ); + + float _night_amount = clamp( -LIGHT0_DIRECTION.y + 0.7, 0.0, 1.0 ); + vec3 _sky_night_color = mix( night_bottom_color, night_top_color, _eyedir_y ); + _sky_color = mix( _sky_color, _sky_night_color, _night_amount ); + + // Final sky color + COLOR = _sky_color; + + //////////////////// HORIZON /////////////////////////////////////////////////////////////////// + float _horizon_amount = 0.0; + if( EYEDIR.y < 0.0 ) + { + _horizon_amount = clamp( abs( EYEDIR.y ) / horizon_blur, 0.0, 1.0 ); + // Mixing with the color of the night sky to make the horizon darker + vec3 _horizon_color = mix( horizon_color, _sky_color, _night_amount * 0.9 ); + // And if ther are many dark clouds, we also make the horizon darker + _horizon_color = mix( _horizon_color, vec3( 0.0 ), ( 1.0 - clouds_cutoff ) * clouds_weight * 0.7 ); + COLOR = mix( COLOR, _horizon_color, _horizon_amount ); + } + + //////////////////// MOON ////////////////////////////////////////////////////////////////////// + float _moon_amount = 0.0; + if( LIGHT1_ENABLED ) + { + // Bigger moon near the horizon + float _moon_size = moon_size + cos( LIGHT1_DIRECTION.y * PI ) * moon_size * 0.25; + float _moon_distance = distance( EYEDIR, LIGHT1_DIRECTION ) / _moon_size; + // Finding moon disc and edge blur + _moon_amount = clamp(( 1.0 - _moon_distance ) / moon_blur, 0.0, 1.0 ); + if( _moon_amount > 0.0 ) + { + // Moon illumination depending on the position of the sun + float _moon_intersect = sphere_intersect( EYEDIR, LIGHT1_DIRECTION, _moon_size ); + vec3 _moon_normal = normalize( LIGHT1_DIRECTION - EYEDIR * _moon_intersect ); + // Power on the result gives a better effect + float _moon_n_dot_l = pow( clamp( dot( _moon_normal, -LIGHT0_DIRECTION ), 0.05, 1.0 ), 2 ); + // Hiding the moon behind the horizon + _moon_amount *= 1.0 - _horizon_amount; + COLOR = mix( COLOR, moon_color, _moon_n_dot_l * _moon_amount ); + } + } + + //////////////////// SUN /////////////////////////////////////////////////////////////////////// + float _sun_distance = 0.0; + if( LIGHT0_ENABLED ) + { + _sun_distance = distance( EYEDIR, LIGHT0_DIRECTION ); + // Bigger sun near the horizon + float _sun_size = sun_size + cos( LIGHT0_DIRECTION.y * PI ) * sun_size * 0.25; + // Finding sun disc and edge blur + float _sun_amount = clamp(( 1.0 - _sun_distance / _sun_size ) / sun_blur, 0.0, 1.0 ); + if( _sun_amount > 0.0 ) + { + // Changing color of the sun during sunset + float _sunset_amount = 1.0; + if( LIGHT0_DIRECTION.y > 0.0 ) + _sunset_amount = clamp( cos( LIGHT0_DIRECTION.y * PI ), 0.0, 1.0 ); + vec3 _sun_color = mix( sun_color, sun_sunset_color, _sunset_amount ); + // Hiding the sun behind the moon + _sun_amount = clamp( _sun_amount * ( 1.0 - _moon_amount ), 0.0, 1.0 ); + // Hiding the sun behind the horizon + _sun_amount *= 1.0 - _horizon_amount; + // Leveling the "glow" in color + if( _sun_color.r > 1.0 || _sun_color.g > 1.0 || _sun_color.b > 1.0 ) + _sun_color *= _sun_amount; + COLOR = mix( COLOR, _sun_color, _sun_amount ); + } + } + + //////////////////// STARS ///////////////////////////////////////////////////////////////// + vec2 _sky_uv = EYEDIR.xz / sqrt( EYEDIR.y ); + if( EYEDIR.y > -0.01 && LIGHT0_DIRECTION.y < 0.0 ) + { + // Stars UV rotation + float _stars_speed_cos = cos( stars_speed * time * 0.005 ); + float _stars_speed_sin = sin( stars_speed * time * 0.005 ); + vec2 _stars_uv = vec2( + _sky_uv.x * _stars_speed_cos - _sky_uv.y * _stars_speed_sin, + _sky_uv.x * _stars_speed_sin + _sky_uv.y * _stars_speed_cos + ); + // Stars texture + vec3 _stars_color = texture( stars_texture, _stars_uv ).rgb * -LIGHT0_DIRECTION.y; + // Hiding stars behind the moon + _stars_color *= 1.0 - _moon_amount; + COLOR += _stars_color; + } + + //////////////////// CLOUDS //////////////////////////////////////////////////////////////// + if( EYEDIR.y > 0.0 ) + { + // Clouds UV movement direction + float _clouds_speed = time * clouds_speed * 0.01; + float _sin_x = sin( clouds_direction * PI * 2.0 ); + float _cos_y = cos( clouds_direction * PI * 2.0 ); + // I using 3 levels of clouds. Top is the lightes and botom the darkest. + // The speed of movement (and direction a little) is different for the illusion of the changing shape of the clouds. + vec2 _clouds_movement = vec2( _sin_x, _cos_y ) * _clouds_speed; +// float _noise_top = texture( clouds_top_texture, ( _sky_uv + _clouds_movement ) * clouds_scale ).r; + float _noise_top = gen_fractal_ping_pong( ( _sky_uv + _clouds_movement ) * clouds_scale, 0, 0.5 ); + _clouds_movement = vec2( _sin_x * 0.97, _cos_y * 1.07 ) * _clouds_speed * 2.89; +// float _noise_middle = texture( clouds_middle_texture, ( _sky_uv + _clouds_movement ) * clouds_scale ).r; + float _noise_middle = gen_fractal_ping_pong( ( _sky_uv + _clouds_movement ) * clouds_scale, 1, 0.75 ); + _clouds_movement = vec2( _sin_x * 1.01, _cos_y * 0.89 ) * _clouds_speed * 0.79; +// float _noise_bottom = texture( clouds_bottom_texture, ( _sky_uv + _clouds_movement ) * clouds_scale ).r; + float _noise_bottom = gen_fractal_ping_pong( ( _sky_uv + _clouds_movement ) * clouds_scale, 2, 1.0 ); + // Smoothstep with the addition of a noise value from a lower level gives a nice, deep result + _noise_bottom = smoothstep( clouds_cutoff, clouds_cutoff + clouds_fuzziness, _noise_bottom ); + _noise_middle = smoothstep( clouds_cutoff, clouds_cutoff + clouds_fuzziness, _noise_middle + _noise_bottom * 0.2 ) * 1.1; + _noise_top = smoothstep( clouds_cutoff, clouds_cutoff + clouds_fuzziness, _noise_top + _noise_middle * 0.4 ) * 1.2; + float _clouds_amount = clamp( _noise_top + _noise_middle + _noise_bottom, 0.0, 1.0 ); + // Fading clouds near the horizon + _clouds_amount *= clamp( abs( EYEDIR.y ) / clouds_blur, 0.0, 1.0 ); + + vec3 _clouds_color = mix( vec3( 0.0 ), clouds_top_color, _noise_top ); + _clouds_color = mix( _clouds_color, clouds_middle_color, _noise_middle ); + _clouds_color = mix( _clouds_color, clouds_bottom_color, _noise_bottom ); + // The edge color gives a nice smooth edge, you can try turning this off if you need sharper edges + _clouds_color = mix( clouds_edge_color, _clouds_color, _noise_top ); + // The sun passing through the clouds effect + _clouds_color = mix( _clouds_color, clamp( sun_color, 0.0, 1.0 ), pow( 1.0 - clamp( _sun_distance, 0.0, 1.0 ), 5 )); + // Color combined with sunset condition + _clouds_color = mix( _clouds_color, sunset_bottom_color, _sunset_amount * 0.75 ); + // Color depending on the "progress" of the night. + _clouds_color = mix( _clouds_color, _sky_color, clamp( _night_amount, 0.0, 0.98 )); + _clouds_color = mix( _clouds_color, vec3( 0.0 ), clouds_weight * 0.9 ); + COLOR = mix( COLOR, _clouds_color, _clouds_amount ); + } +} \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/map/dungeon/floors/Floor 00 Sky.gdshader.uid b/Zennysoft.Game.Ma/src/map/dungeon/floors/Floor 00 Sky.gdshader.uid new file mode 100644 index 00000000..e023311c --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/floors/Floor 00 Sky.gdshader.uid @@ -0,0 +1 @@ +uid://f2itisokyicv diff --git a/Zennysoft.Game.Ma/src/map/dungeon/floors/Metal.gdshader b/Zennysoft.Game.Ma/src/map/dungeon/floors/Metal.gdshader new file mode 100644 index 00000000..d96ec45e --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/floors/Metal.gdshader @@ -0,0 +1,14 @@ +shader_type spatial; + +void vertex() { + // Called for every vertex the material is visible on. +} + +void fragment() { + // Called for every pixel the material is visible on. +} + +//void light() { +// // Called for every pixel for every light affecting the material. +// // Uncomment to replace the default light processing function with this one. +//} diff --git a/Zennysoft.Game.Ma/src/map/dungeon/floors/Metal.gdshader.uid b/Zennysoft.Game.Ma/src/map/dungeon/floors/Metal.gdshader.uid new file mode 100644 index 00000000..ea078b23 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/floors/Metal.gdshader.uid @@ -0,0 +1 @@ +uid://brhf7s3riyag5 diff --git a/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/BOSS ROOM BOXES.glb b/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/BOSS ROOM BOXES.glb new file mode 100644 index 00000000..64ee49b7 Binary files /dev/null and b/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/BOSS ROOM BOXES.glb differ diff --git a/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/BOSS ROOM BOXES.glb.import b/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/BOSS ROOM BOXES.glb.import new file mode 100644 index 00000000..77e58f68 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/BOSS ROOM BOXES.glb.import @@ -0,0 +1,37 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bwsflqggxhsnb" +path="res://.godot/imported/BOSS ROOM BOXES.glb-1d73b52d0c29fc94237c791acc7100a2.scn" + +[deps] + +source_file="res://src/map/dungeon/models/Set A/15. Boss Floor A/BOSS ROOM BOXES.glb" +dest_files=["res://.godot/imported/BOSS ROOM BOXES.glb-1d73b52d0c29fc94237c791acc7100a2.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +_subresources={} +gltf/naming_version=1 +gltf/embedded_image_handling=1 diff --git a/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/stars.png b/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/stars.png new file mode 100644 index 00000000..5866e2d6 Binary files /dev/null and b/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/stars.png differ diff --git a/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/stars.png.import b/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/stars.png.import new file mode 100644 index 00000000..79172860 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/models/Set A/15. Boss Floor A/stars.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bk50l4ie462me" +path="res://.godot/imported/stars.png-80b61076bd81595661c3abd53181dd3e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://src/map/dungeon/models/Set A/15. Boss Floor A/stars.png" +dest_files=["res://.godot/imported/stars.png-80b61076bd81595661c3abd53181dd3e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set A/Clouds 2.gdshader b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set A/Clouds 2.gdshader new file mode 100644 index 00000000..6a6caf5d --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set A/Clouds 2.gdshader @@ -0,0 +1,87 @@ +shader_type spatial; + +render_mode blend_mix, depth_draw_opaque, cull_back, unshaded; + +// Uniformy dla zmiennych konfigurowalnych +uniform vec4 cloud_color = vec4(1.0, 1.0, 1.0, 1.0); // Kolor chmur (w tym przezroczystość) +uniform float cloud_opacity : hint_range(0.0, 1.0) = 0.1; // Przezroczystość chmur + +// Funkcja do interpolacji (fade) używana w szumie Perlin'a +float fade(float t) { + return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); +} + +// Funkcja do generowania gradientu +float grad(int hash, float x, float y) { + int h = hash & 7; // maska hash + float u = h < 4 ? x : y; + float v = h < 4 ? y : x; + return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); +} + +// Funkcja do generowania prostego szumu Perlin'a +float perlin_noise(vec2 coord) { + vec2 p = floor(coord); + vec2 f = fract(coord); + f = f * f * (3.0 - 2.0 * f); + + float n = p.x + p.y * 57.0; + float res = mix( + mix(grad(int(n + 0.0), f.x, f.y), + grad(int(n + 1.0), f.x - 1.0, f.y), fade(f.x)), + mix(grad(int(n + 57.0), f.x, f.y - 1.0), + grad(int(n + 58.0), f.x - 1.0, f.y - 1.0), fade(f.x)), + fade(f.y)); + return res; +} + +// Funkcja do generowania warstwowego szumu dla bardziej chmurowego efektu +float layered_perlin_noise(vec2 coord, float scale, float amplitude) { + float noise = 0.0; + float persistence = 0.5; // Ustawienie wpływu kolejnych warstw szumu + + // Dodajemy kilka warstw szumu, aby uzyskać bardziej złożony efekt + for (int i = 0; i < 5; i++) { + noise += perlin_noise(coord * scale) * amplitude; + scale *= 2.0; + amplitude *= persistence; + } + return noise; +} + +void fragment() { + // Pobranie współrzędnych UV + vec2 uv = UV; + + // Dodanie animacji do współrzędnych UV + float speed = 0.01; // Prędkość przesuwania chmur + vec2 animated_uv = uv + vec2(TIME * speed, TIME * speed); + + // Parametry dla różnych chmur + int num_clouds = 23; // Więcej chmur + float cloud_size = 0.001; // Bardzo mały rozmiar chmury + float scale = 9000.0; // Zmniejszona skala szumu + + // Inicjalizacja zmiennej do przechowywania wyniku końcowego + float final_noise = 0.0; + + for (int i = 0; i < num_clouds; i++) { + // Losowe przesunięcie dla każdej chmury + float random_offset = float(i) * 0.01; + vec2 cloud_center = vec2(fract(sin(float(i) * 0.1) * 43758.5453), fract(cos(float(i) * 0.1) * 43758.5453)); + + // Modyfikacja współrzędnych UV dla efektu szumu + vec2 cloud_uv = (animated_uv - cloud_center) * (scale * cloud_size); + float noise = layered_perlin_noise(cloud_uv, 1.0, 1.0); + + // Wygładzanie i ograniczenie wartości szumu + noise = smoothstep(0.3, 0.7, noise); + final_noise = max(final_noise, noise); + } + + // Ustawienie koloru chmur na podstawie uniformu + vec4 color = vec4(cloud_color.rgb, cloud_color.a * final_noise * cloud_opacity); + + ALBEDO = color.rgb; + ALPHA = color.a; +} diff --git a/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set A/Clouds 2.gdshader.uid b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set A/Clouds 2.gdshader.uid new file mode 100644 index 00000000..dd70367e --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set A/Clouds 2.gdshader.uid @@ -0,0 +1 @@ +uid://kqp7mww6drrx diff --git a/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/Night Sky Boss B.gdshader b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/Night Sky Boss B.gdshader new file mode 100644 index 00000000..8c79fdd3 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/Night Sky Boss B.gdshader @@ -0,0 +1,291 @@ +shader_type sky; + +render_mode use_quarter_res_pass; + +// Originaly based on https://godotshaders.com/shader/stylized-sky-shader-with-clouds/ but there's not much left + +group_uniforms sky; + uniform vec3 day_top_color : source_color = vec3( 0.1, 0.6, 1.0 ); + uniform vec3 day_bottom_color : source_color = vec3( 0.4, 0.8, 1.0 ); + uniform vec3 sunset_top_color : source_color = vec3( 0.7, 0.75, 1.0 ); + uniform vec3 sunset_bottom_color : source_color = vec3( 1.0, 0.5, 0.7 ); + uniform vec3 night_top_color : source_color = vec3( 0.02, 0.0, 0.04 ); + uniform vec3 night_bottom_color : source_color = vec3( 0.1, 0.0, 0.2 ); + +group_uniforms horizon; + uniform vec3 horizon_color : source_color = vec3( 0.0, 0.7, 0.8 ); + uniform float horizon_blur : hint_range( 0.0, 1.0, 0.01 ) = 0.05; + +group_uniforms sun; // First DirectionalLight3D will be the sun + uniform vec3 sun_color : source_color = vec3( 10.0, 8.0, 1.0 ); + uniform vec3 sun_sunset_color : source_color = vec3( 10.0, 0.0, 0.0 ); + uniform float sun_size : hint_range( 0.01, 1.0 ) = 0.2; + uniform float sun_blur : hint_range( 0.01, 20.0 ) = 10.0; + +group_uniforms moon; // Second DirectionalLight3D will be the moon + uniform vec3 moon_color : source_color = vec3( 1.0, 0.95, 0.7 ); + uniform float moon_size : hint_range( 0.01, 1.0 ) = 0.06; + uniform float moon_blur : hint_range( 0.01, 10.0 ) = 0.1; + +group_uniforms clouds; + // Replaced by noise functions, unncomment if you want to use graphical textures +// uniform sampler2D clouds_top_texture : filter_linear_mipmap, hint_default_black; +// uniform sampler2D clouds_middle_texture : filter_linear_mipmap, hint_default_black; +// uniform sampler2D clouds_bottom_texture : filter_linear_mipmap, hint_default_black; + uniform vec3 clouds_edge_color : source_color = vec3( 0.8, 0.8, 0.98 ); + uniform vec3 clouds_top_color : source_color = vec3( 1.0, 1.0, 1.00 ); + uniform vec3 clouds_middle_color : source_color = vec3( 0.92, 0.92, 0.98 ); + uniform vec3 clouds_bottom_color : source_color = vec3( 0.83, 0.83, 0.94 ); + uniform float clouds_speed : hint_range( 0.0, 20.0, 0.01 ) = 2.0; + uniform float clouds_direction : hint_range( -0.5, 0.5, 0.0 ) = 0.2; + uniform float clouds_scale : hint_range( 0.0, 4.0, 0.01 ) = 1.0; + uniform float clouds_cutoff : hint_range( 0.0, 1.0, 0.01 ) = 0.3; + uniform float clouds_fuzziness : hint_range( 0.0, 2.0, 0.01 ) = 0.5; + // More weight is simply a darker color, usefull for rain/storm + uniform float clouds_weight : hint_range( 0.0, 1.0, 0.01 ) = 0.0; + uniform float clouds_blur : hint_range( 0.0, 1.0, 0.01 ) = 0.25; + +group_uniforms stars; + // Stars should be at black background + uniform sampler2D stars_texture : filter_linear_mipmap, hint_default_black; + uniform float stars_speed : hint_range( 0.0, 20.0, 0.01 ) = 1.0; + +group_uniforms settings; + uniform float overwritten_time = 0.0; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + // Function for clouds noises. You can replace using "gen_fractal_ping_pong" with a simple texture reading. + // I was frustrated with the repeating texture that's why I included the algorithm in the code. + // Source: https://github.com/Auburn/FastNoiseLite/tree/master + const int PRIME_X = 501125321; + const int PRIME_Y = 1136930381; + float lerp( float a, float b, float t ) + { + return a + t * ( b - a ); + } + float cubic_lerp( float a, float b, float c, float d, float t ) + { + float p = d - c - ( a - b ); + return t * t * t * p + t * t * ( a - b - p ) + t * ( c - a ) + b; + } + float ping_pong( float t ) + { + t -= trunc( t * 0.5 ) * 2.0; + return t < 1.0 ? t : 2.0 - t; + } + int hash( int seed, int x_primed, int y_primed ) + { + return ( seed ^ x_primed ^ y_primed ) * 0x27d4eb2d; + } + float val_coord( int seed, int x_primed, int y_primed ) + { + int hash = hash( seed, x_primed, y_primed ); + hash *= hash; + hash ^= hash << 19; + return float( hash ) * ( 1.0 / 2147483648.0 ); + } + float single_value_cubic( int seed, float x, float y ) + { + int x1 = int( floor( x )); + int y1 = int( floor( y )); + + float xs = x - float( x1 ); + float ys = y - float( y1 ); + + x1 *= PRIME_X; + y1 *= PRIME_Y; + int x0 = x1 - PRIME_X; + int y0 = y1 - PRIME_Y; + int x2 = x1 + PRIME_X; + int y2 = y1 + PRIME_Y; + int x3 = x1 + ( PRIME_X << 1 ); + int y3 = y1 + ( PRIME_Y << 1 ); + + return cubic_lerp( + cubic_lerp( val_coord( seed, x0, y0 ), val_coord( seed, x1, y0 ), val_coord( seed, x2, y0 ), val_coord( seed, x3, y0 ), xs ), + cubic_lerp( val_coord( seed, x0, y1 ), val_coord( seed, x1, y1 ), val_coord( seed, x2, y1 ), val_coord( seed, x3, y1 ), xs ), + cubic_lerp( val_coord( seed, x0, y2 ), val_coord( seed, x1, y2 ), val_coord( seed, x2, y2 ), val_coord( seed, x3, y2 ), xs ), + cubic_lerp( val_coord( seed, x0, y3 ), val_coord( seed, x1, y3 ), val_coord( seed, x2, y3 ), val_coord( seed, x3, y3 ), xs ), + ys ) * ( 1.0 / ( 1.5 * 1.5 )); + } + // Params can be change in the same way as in noise settings in Godot + const float FRACTAL_BOUNDING = 1.0 / 1.75; + const int OCTAVES = 5; + const float PING_PONG_STRENGTH = 2.0; + const float WEIGHTED_STRENGTH = 0.0; + const float GAIN = 0.5; + const float LACUNARITY = 2.0; + float gen_fractal_ping_pong( vec2 pos, int seed, float frequency ) + { + float x = pos.x * frequency; + float y = pos.y * frequency; + float sum = 0.0; + float amp = FRACTAL_BOUNDING; + for( int i = 0; i < OCTAVES; i++ ) + { + float noise = ping_pong(( single_value_cubic( seed++, x, y ) + 1.0 ) * PING_PONG_STRENGTH ); + sum += ( noise - 0.5 ) * 2.0 * amp; + amp *= lerp( 1.0, noise, WEIGHTED_STRENGTH ); + x *= LACUNARITY; + y *= LACUNARITY; + amp *= GAIN; + } + return sum * 0.5 + 0.5; + } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// Function needed to calculate the phase of the moon +// Source: https://kelvinvanhoorn.com/2022/03/17/skybox-tutorial-part-1/ +float sphere_intersect( vec3 view_dir, vec3 sphere_pos, float radius ) +{ + float b = dot( -sphere_pos, view_dir ); + float c = dot( -sphere_pos, -sphere_pos ) - pow( radius, 2 ); + float h = pow( b, 2 ) - c; + return h < 0.0 ? -1.0 : -b - sqrt( h ); +} + +void sky() +{ + float time = overwritten_time != 0.0 ? overwritten_time : TIME; + + //////////////////// SKY /////////////////////////////////////////////////////////////////////// + float _eyedir_y = abs( sin( EYEDIR.y * PI * 0.5 )); + + // The day color will be our base color + vec3 _sky_color = mix( day_bottom_color, day_top_color, _eyedir_y ); + _sky_color = mix( _sky_color, vec3( 0.0 ), clamp(( 0.7 - clouds_cutoff ) * clouds_weight, 0.0, 1.0 )); + + float _sunset_amount = clamp( 0.5 - abs( LIGHT0_DIRECTION.y ), 0.0, 0.5 ) * 2.0; + // The sky should be more red around the west, on the opposite side you don't see it as much + float _sunset_distance = clamp( 1.0 - pow( distance( EYEDIR, LIGHT0_DIRECTION ), 2 ), 0.0, 1.0 ); + vec3 _sky_sunset_color = mix( sunset_bottom_color, sunset_top_color, _eyedir_y + 0.5 ); + _sky_sunset_color = mix( _sky_sunset_color, sunset_bottom_color, _sunset_amount * _sunset_distance ); + _sky_color = mix( _sky_color, _sky_sunset_color, _sunset_amount ); + + float _night_amount = clamp( -LIGHT0_DIRECTION.y + 0.7, 0.0, 1.0 ); + vec3 _sky_night_color = mix( night_bottom_color, night_top_color, _eyedir_y ); + _sky_color = mix( _sky_color, _sky_night_color, _night_amount ); + + // Final sky color + COLOR = _sky_color; + + //////////////////// HORIZON /////////////////////////////////////////////////////////////////// + float _horizon_amount = 0.0; + if( EYEDIR.y < 0.0 ) + { + _horizon_amount = clamp( abs( EYEDIR.y ) / horizon_blur, 0.0, 1.0 ); + // Mixing with the color of the night sky to make the horizon darker + vec3 _horizon_color = mix( horizon_color, _sky_color, _night_amount * 0.9 ); + // And if ther are many dark clouds, we also make the horizon darker + _horizon_color = mix( _horizon_color, vec3( 0.0 ), ( 1.0 - clouds_cutoff ) * clouds_weight * 0.7 ); + COLOR = mix( COLOR, _horizon_color, _horizon_amount ); + } + + //////////////////// MOON ////////////////////////////////////////////////////////////////////// + float _moon_amount = 0.0; + if( LIGHT1_ENABLED ) + { + // Bigger moon near the horizon + float _moon_size = moon_size + cos( LIGHT1_DIRECTION.y * PI ) * moon_size * 0.25; + float _moon_distance = distance( EYEDIR, LIGHT1_DIRECTION ) / _moon_size; + // Finding moon disc and edge blur + _moon_amount = clamp(( 1.0 - _moon_distance ) / moon_blur, 0.0, 1.0 ); + if( _moon_amount > 0.0 ) + { + // Moon illumination depending on the position of the sun + float _moon_intersect = sphere_intersect( EYEDIR, LIGHT1_DIRECTION, _moon_size ); + vec3 _moon_normal = normalize( LIGHT1_DIRECTION - EYEDIR * _moon_intersect ); + // Power on the result gives a better effect + float _moon_n_dot_l = pow( clamp( dot( _moon_normal, -LIGHT0_DIRECTION ), 0.05, 1.0 ), 2 ); + // Hiding the moon behind the horizon + _moon_amount *= 1.0 - _horizon_amount; + COLOR = mix( COLOR, moon_color, _moon_n_dot_l * _moon_amount ); + } + } + + //////////////////// SUN /////////////////////////////////////////////////////////////////////// + float _sun_distance = 0.0; + if( LIGHT0_ENABLED ) + { + _sun_distance = distance( EYEDIR, LIGHT0_DIRECTION ); + // Bigger sun near the horizon + float _sun_size = sun_size + cos( LIGHT0_DIRECTION.y * PI ) * sun_size * 0.25; + // Finding sun disc and edge blur + float _sun_amount = clamp(( 1.0 - _sun_distance / _sun_size ) / sun_blur, 0.0, 1.0 ); + if( _sun_amount > 0.0 ) + { + // Changing color of the sun during sunset + float _sunset_amount = 1.0; + if( LIGHT0_DIRECTION.y > 0.0 ) + _sunset_amount = clamp( cos( LIGHT0_DIRECTION.y * PI ), 0.0, 1.0 ); + vec3 _sun_color = mix( sun_color, sun_sunset_color, _sunset_amount ); + // Hiding the sun behind the moon + _sun_amount = clamp( _sun_amount * ( 1.0 - _moon_amount ), 0.0, 1.0 ); + // Hiding the sun behind the horizon + _sun_amount *= 1.0 - _horizon_amount; + // Leveling the "glow" in color + if( _sun_color.r > 1.0 || _sun_color.g > 1.0 || _sun_color.b > 1.0 ) + _sun_color *= _sun_amount; + COLOR = mix( COLOR, _sun_color, _sun_amount ); + } + } + + //////////////////// STARS ///////////////////////////////////////////////////////////////// + vec2 _sky_uv = EYEDIR.xz / sqrt( EYEDIR.y ); + if( EYEDIR.y > -0.01 && LIGHT0_DIRECTION.y < 0.0 ) + { + // Stars UV rotation + float _stars_speed_cos = cos( stars_speed * time * 0.005 ); + float _stars_speed_sin = sin( stars_speed * time * 0.005 ); + vec2 _stars_uv = vec2( + _sky_uv.x * _stars_speed_cos - _sky_uv.y * _stars_speed_sin, + _sky_uv.x * _stars_speed_sin + _sky_uv.y * _stars_speed_cos + ); + // Stars texture + vec3 _stars_color = texture( stars_texture, _stars_uv ).rgb * -LIGHT0_DIRECTION.y; + // Hiding stars behind the moon + _stars_color *= 1.0 - _moon_amount; + COLOR += _stars_color; + } + + //////////////////// CLOUDS //////////////////////////////////////////////////////////////// + if( EYEDIR.y > 0.0 ) + { + // Clouds UV movement direction + float _clouds_speed = time * clouds_speed * 0.01; + float _sin_x = sin( clouds_direction * PI * 2.0 ); + float _cos_y = cos( clouds_direction * PI * 2.0 ); + // I using 3 levels of clouds. Top is the lightes and botom the darkest. + // The speed of movement (and direction a little) is different for the illusion of the changing shape of the clouds. + vec2 _clouds_movement = vec2( _sin_x, _cos_y ) * _clouds_speed; +// float _noise_top = texture( clouds_top_texture, ( _sky_uv + _clouds_movement ) * clouds_scale ).r; + float _noise_top = gen_fractal_ping_pong( ( _sky_uv + _clouds_movement ) * clouds_scale, 0, 0.5 ); + _clouds_movement = vec2( _sin_x * 0.97, _cos_y * 1.07 ) * _clouds_speed * 0.89; +// float _noise_middle = texture( clouds_middle_texture, ( _sky_uv + _clouds_movement ) * clouds_scale ).r; + float _noise_middle = gen_fractal_ping_pong( ( _sky_uv + _clouds_movement ) * clouds_scale, 1, 0.75 ); + _clouds_movement = vec2( _sin_x * 1.01, _cos_y * 0.89 ) * _clouds_speed * 0.79; +// float _noise_bottom = texture( clouds_bottom_texture, ( _sky_uv + _clouds_movement ) * clouds_scale ).r; + float _noise_bottom = gen_fractal_ping_pong( ( _sky_uv + _clouds_movement ) * clouds_scale, 2, 1.0 ); + // Smoothstep with the addition of a noise value from a lower level gives a nice, deep result + _noise_bottom = smoothstep( clouds_cutoff, clouds_cutoff + clouds_fuzziness, _noise_bottom ); + _noise_middle = smoothstep( clouds_cutoff, clouds_cutoff + clouds_fuzziness, _noise_middle + _noise_bottom * 0.2 ) * 1.1; + _noise_top = smoothstep( clouds_cutoff, clouds_cutoff + clouds_fuzziness, _noise_top + _noise_middle * 0.4 ) * 1.2; + float _clouds_amount = clamp( _noise_top + _noise_middle + _noise_bottom, 0.0, 1.0 ); + // Fading clouds near the horizon + _clouds_amount *= clamp( abs( EYEDIR.y ) / clouds_blur, 0.0, 1.0 ); + + vec3 _clouds_color = mix( vec3( 0.0 ), clouds_top_color, _noise_top ); + _clouds_color = mix( _clouds_color, clouds_middle_color, _noise_middle ); + _clouds_color = mix( _clouds_color, clouds_bottom_color, _noise_bottom ); + // The edge color gives a nice smooth edge, you can try turning this off if you need sharper edges + _clouds_color = mix( clouds_edge_color, _clouds_color, _noise_top ); + // The sun passing through the clouds effect + _clouds_color = mix( _clouds_color, clamp( sun_color, 0.0, 1.0 ), pow( 1.0 - clamp( _sun_distance, 0.0, 1.0 ), 5 )); + // Color combined with sunset condition + _clouds_color = mix( _clouds_color, sunset_bottom_color, _sunset_amount * 0.75 ); + // Color depending on the "progress" of the night. + _clouds_color = mix( _clouds_color, _sky_color, clamp( _night_amount, 0.0, 0.98 )); + _clouds_color = mix( _clouds_color, vec3( 0.0 ), clouds_weight * 0.9 ); + COLOR = mix( COLOR, _clouds_color, _clouds_amount ); + } +} \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/Night Sky Boss B.gdshader.uid b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/Night Sky Boss B.gdshader.uid new file mode 100644 index 00000000..f02052b3 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/Night Sky Boss B.gdshader.uid @@ -0,0 +1 @@ +uid://crbilces53hat