diff --git a/.clang-format b/.clang-format deleted file mode 100644 index fd2b623..0000000 --- a/.clang-format +++ /dev/null @@ -1,51 +0,0 @@ - -AccessModifierOffset: -1 -AlignAfterOpenBracket: AlwaysBreak -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlinesLeft: true -AlignOperands: false -AlignTrailingComments: false -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Inline -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: true -BinPackArguments: false -BinPackParameters: false -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Allman -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: true -BreakStringLiterals: true -ColumnLimit: 100 -ConstructorInitializerAllOnOneLineOrOnePerLine: true -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DisableFormat: false -FixNamespaceComments: true -IncludeCategories: - - Regex: '^<' - Priority: 1 - - Regex: '^"' - Priority: 2 -IndentCaseLabels: true -IndentWidth: 2 -KeepEmptyLinesAtTheStartOfBlocks: false -Language: Cpp -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -PenaltyReturnTypeOnItsOwnLine: 5000 -PointerAlignment: Left -SortIncludes: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements -SpaceInEmptyParentheses: false -Standard: Cpp11 -TabWidth: 2 -UseTab: Never diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a31b0b0..a025334 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -69,8 +69,9 @@ repos: name: check shaders entry: clang-format args: - - --style=file + - --style=llvm - -Werror + - -i language: system files: \.gdshader$ exclude: ^addons/ diff --git a/shaders/explosion.gdshader b/shaders/explosion.gdshader index b916b81..09c4bdf 100644 --- a/shaders/explosion.gdshader +++ b/shaders/explosion.gdshader @@ -1,6 +1,7 @@ shader_type spatial; -render_mode blend_mix,depth_draw_opaque,cull_disabled,diffuse_burley,specular_schlick_ggx,unshaded; +render_mode blend_mix, depth_draw_opaque, cull_disabled, diffuse_burley, + specular_schlick_ggx, unshaded; uniform vec4 fire_color : source_color = vec4(0.99, 0.31, 0.01, 1.0); uniform float fire_strength = 4.3; uniform float warble_strength = 0.2; @@ -11,32 +12,34 @@ uniform sampler2D green_texture : source_color; uniform sampler2D blue_texture : source_color; uniform sampler2D noise_texture : source_color; -vec3 lerp(vec3 a, vec3 b, float t){ - return a * (1.0 - t) + b * t; -} +vec3 lerp(vec3 a, vec3 b, float t) { return a * (1.0 - t) + b * t; } -float fresnel(float amount, vec3 normal, vec3 view) -{ - return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0 )), amount); +float fresnel(float amount, vec3 normal, vec3 view) { + return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0)), + amount); } - void vertex() { - mat4 mat_world = mat4(normalize(VIEW_MATRIX[0])*length(MODEL_MATRIX[0]),normalize(VIEW_MATRIX[1])*length(MODEL_MATRIX[0]),normalize(VIEW_MATRIX[2])*length(MODEL_MATRIX[2]),MODEL_MATRIX[3]); - mat_world = mat_world * mat4( vec4(cos(INSTANCE_CUSTOM.x),-sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0),vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0, 1.0)); - MODELVIEW_MATRIX = INV_VIEW_MATRIX * mat_world; + mat4 mat_world = mat4(normalize(VIEW_MATRIX[0]) * length(MODEL_MATRIX[0]), + normalize(VIEW_MATRIX[1]) * length(MODEL_MATRIX[0]), + normalize(VIEW_MATRIX[2]) * length(MODEL_MATRIX[2]), + MODEL_MATRIX[3]); + mat_world = + mat_world * + mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), + vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); + MODELVIEW_MATRIX = INV_VIEW_MATRIX * mat_world; } - - - void fragment() { - vec2 base_uv = UV; - vec3 r = texture(red_texture, base_uv).rgb; - vec3 g = texture(green_texture, base_uv).rgb; - vec3 b = texture(blue_texture, base_uv).rgb; - ALPHA = clamp(b.b * COLOR.a, 0.0, 1.0) + texture(noise_texture, UV + TIME * time_scale).r * warble_strength; - ALPHA_SCISSOR_THRESHOLD = alpha_scissor; - vec3 fragment_world_pos = (PROJECTION_MATRIX * vec4(VERTEX, 1.0)).xyz; - ALBEDO = lerp(g * fire_color.rgb * fire_strength, r, COLOR.r); + vec2 base_uv = UV; + vec3 r = texture(red_texture, base_uv).rgb; + vec3 g = texture(green_texture, base_uv).rgb; + vec3 b = texture(blue_texture, base_uv).rgb; + ALPHA = clamp(b.b * COLOR.a, 0.0, 1.0) + + texture(noise_texture, UV + TIME * time_scale).r * warble_strength; + ALPHA_SCISSOR_THRESHOLD = alpha_scissor; + vec3 fragment_world_pos = (PROJECTION_MATRIX * vec4(VERTEX, 1.0)).xyz; + ALBEDO = lerp(g * fire_color.rgb * fire_strength, r, COLOR.r); } diff --git a/shaders/sky.gdshader b/shaders/sky.gdshader index 277ed14..5c04fe2 100644 --- a/shaders/sky.gdshader +++ b/shaders/sky.gdshader @@ -1,290 +1,328 @@ shader_type sky; render_mode use_quarter_res_pass; -// Originally based on https://godotshaders.com/shader/stylized-sky-shader-with-clouds/ but there's not much left +// Originally 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 ); +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; +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; +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; +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, useful 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; +// 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, useful 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; +// 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; +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 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 ); +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 there 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 ); - } +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 there 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); + } }