Files
tgcc/core/daynight/sky.gdshader

141 lines
5.0 KiB
Plaintext

shader_type sky;
uniform vec3 sky_top_color : source_color;
uniform vec3 sky_horizon_color : source_color;
uniform float night_intensity : hint_range(0.0, 1.0) = 0.0;
group_uniforms Clouds;
uniform sampler2D cloud_noise : filter_linear_mipmap, repeat_enable;
uniform vec3 sun_color : source_color = vec3(1.0);
uniform vec4 cloud_center_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform vec4 cloud_edge_color : source_color = vec4(0.8, 0.85, 0.9, 1.0);
uniform vec2 cloud_direction = vec2(0.5, 0.2);
uniform float cloud_speed : hint_range(0.0, 2.0) = 0.1;
uniform float cloud_scale = 0.5;
uniform float cloud_threshold : hint_range(0.0, 1.0) = 0.5;
uniform float cloud_edge_thickness : hint_range(0.0, 0.5) = 0.1;
uniform float cloud_edge_softness : hint_range(0.0, 0.5) = 0.05;
group_uniforms Fixed_Start;
uniform float star_density : hint_range(0.0, 2000.0) = 1500.0;
uniform float star_rarity : hint_range(100.0, 5000.0) = 2500.0;
uniform float star_scale_variation : hint_range(0.0, 1.0) = 0.5;
group_uniforms Shooting_Stars;
uniform sampler2D shooting_star_texture : hint_default_black, filter_linear_mipmap;
uniform vec4 shooting_star_color : source_color = vec4(1.0, 0.9, 0.7, 1.0);
uniform float shooting_star_density : hint_range(0.0, 1.0) = 0.3;
uniform float shooting_star_speed : hint_range(0.1, 3.0) = 1.0;
uniform float shooting_star_scale : hint_range(0.1, 20.0) = 5.0;
uniform float shooting_star_lifetime : hint_range(0.1, 1.0) = 0.5;
uniform float shooting_star_travel_dist : hint_range(1.0, 30.0) = 15.0;
//Utility
float hash(vec3 p) {
p = fract(p * 0.1031);
p += dot(p, p.yzx + 33.33);
return fract((p.x + p.y) * p.z);
}
vec2 hash2(vec3 p) {
float h1 = hash(p);
float h2 = hash(p + vec3(57.1, 13.7, 9.3));
return vec2(h1, h2);
}
vec3 hash3(float seed) {
vec3 p = fract(vec3(seed) * vec3(0.1031, 0.1030, 0.0973));
p += dot(p, p.yzx + 33.33);
return fract((p.xxy + p.yzz) * p.zyx);
}
void sky() {
float sky_v = clamp(EYEDIR.y, 0.0, 1.0);
vec3 final_sky = mix(sky_horizon_color, sky_top_color, sky_v);
if (night_intensity > 0.05) {
//Fixed Start
vec3 star_pos = EYEDIR * star_density;
vec2 rnd = hash2(star_pos);
float star_shape = pow(rnd.x, star_rarity);
float scale_factor = mix(1.0, (rnd.y * 0.8 + 0.2), star_scale_variation);
star_shape *= scale_factor;
star_shape *= pow(sky_v, 4.0);
float twinkle_speed = TIME * (1.0 + rnd.y * 5.0);
float twinkle_phase = rnd.x * 100.0;
float twinkle = sin(twinkle_speed + twinkle_phase) * 0.25 + 0.75;
star_shape *= twinkle;
final_sky += star_shape * night_intensity;
//Shooting Stars
if (shooting_star_density > 0.001) {
float time_scaled = TIME * shooting_star_speed;
float time_seed = floor(time_scaled);
float time_progress = fract(time_scaled);
vec3 shoot_rnd = hash3(time_seed);
if (shoot_rnd.z < shooting_star_density * night_intensity) {
vec3 center = normalize(vec3(shoot_rnd.x * 2.0 - 1.0, shoot_rnd.y * 0.6 + 0.4, shoot_rnd.z * 2.0 - 1.0));
vec3 up = vec3(0.0, 1.0, 0.0);
vec3 tangent = normalize(cross(up, center));
vec3 bitangent = cross(center, tangent);
float random_angle = hash(vec3(time_seed)) * 6.28318;
float s = sin(random_angle);
float c = cos(random_angle);
vec3 flight_axis = tangent * c - bitangent * s;
vec3 side_axis = tangent * s + bitangent * c;
if (flight_axis.y > 0.0) {
flight_axis = -flight_axis;
side_axis = -side_axis;
}
float proj_x = dot(EYEDIR, side_axis);
float proj_y = dot(EYEDIR, flight_axis);
float proj_z = dot(EYEDIR, center);
if (proj_z > 0.0) {
vec2 uv = vec2(proj_x, -proj_y) * shooting_star_scale;
uv.y += (time_progress - (shooting_star_lifetime * 0.5)) * shooting_star_travel_dist;
uv.x += 0.5;
float bounds = step(0.0, uv.x) * step(uv.x, 1.0) * step(0.0, uv.y) * step(uv.y, 1.0);
if (bounds > 0.5) {
float star_tex = texture(shooting_star_texture, uv).r;
float fade_in = smoothstep(0.0, shooting_star_lifetime * 0.2, time_progress);
float fade_out = 1.0 - smoothstep(shooting_star_lifetime * 0.7, shooting_star_lifetime, time_progress);
float fade = fade_in * fade_out;
final_sky += star_tex * shooting_star_color.rgb * night_intensity * fade;
}
}
}
}
}
//Clouds
vec2 cloud_uv = EYEDIR.xz / (EYEDIR.y + 0.5);
cloud_uv = cloud_uv * cloud_scale + (TIME * cloud_direction * cloud_speed);
float noise = texture(cloud_noise, cloud_uv).r;
float cloud_alpha = smoothstep(cloud_threshold, cloud_threshold + cloud_edge_softness, noise);
float color_gradient = smoothstep(cloud_threshold, cloud_threshold + cloud_edge_thickness, noise);
vec3 tinted_center = cloud_center_color.rgb * sun_color;
vec3 tinted_edge = cloud_edge_color.rgb * sun_color;
vec3 day_cloud_color = mix(tinted_edge, tinted_center, color_gradient);
vec3 night_cloud_color = sky_top_color * 0.4;
vec3 current_cloud_color = mix(day_cloud_color, night_cloud_color, night_intensity);
cloud_alpha *= smoothstep(0.1, 0.4, EYEDIR.y);
//Apply clouds to sky
final_sky = mix(final_sky, current_cloud_color, cloud_alpha);
COLOR = final_sky;
}