stick-the-quick/shaders/sky.gdshader

111 lines
3.7 KiB
Plaintext

shader_type sky;
/// Procedural sky supporting overcast and time of day.
/// Color of the sky in the daytime.
const vec3 COLOR_DAY = vec3(0.0, 0.41, 0.8);
/// Color of the horizon at sunrise and sunset.
const vec3 COLOR_TWILIGHT = vec3(1.0, 0.29, 0.0);
/// Color of the sky at night.
const vec3 COLOR_NIGHT = vec3(0.01, 0.0, 0.03);
/// Typical color of the clouds.
const vec3 COLOR_CLOUDS_LIGHT = vec3(2.0);
/// Shade the clouds take on at peak overcast.
const vec3 COLOR_CLOUDS_HEAVY = vec3(0.25);
/// Multipliers for the clouds' color at night.
const vec3 MUL_CLOUDS_NIGHT = vec3(0.0);
/// Multiplier for the clouds' color at their edges.
const vec3 MUL_CLOUDS_EDGE = vec3(0.75);
/// Threshold between 0-to-mask and mask-to-1 interpolation of cloud alpha.
const float ALPHA_THRESHOLD_CLOUDS = 0.25;
/// Color of the stars.
const vec3 COLOR_STARS = vec3(2.0);
/// Radiance color of the sky in the daytime.
const vec3 RADIANCE_DAY = vec3(0.625);
/// Radiance color of the sky at sunrise and sunset.
const vec3 RADIANCE_TWILIGHT = COLOR_TWILIGHT/2.0;
/// Radiance color of the sky at night.
const vec3 RADIANCE_NIGHT = 3.0*COLOR_NIGHT;
/// Multipliers for the radiance color of the sky at peak overcast.
const vec3 MUL_RADIANCE_OVERCAST = vec3(0.875);
/// Peak wind velocity in UV units per second.
const vec2 PEAK_WIND = vec2(0.25, 0.0);
/// Alpha mask for the cloud layer.
uniform sampler2D cloud_map:
source_color, filter_linear, repeat_enable, hint_default_black;
/// Alpha mask for the star layer.
uniform sampler2D star_map:
source_color, filter_linear, repeat_enable, hint_default_black;
/// Interpolates between brightest time of day and darkest time of night.
global uniform float night;
/// Interpolates quadratically between clear sky and cloudy sky.
global uniform float overcast;
/// Interpolates quadratically between no wind and maximum wind.
global uniform float wind;
/// Computes cloud RGBA at given UV.
vec4 clouds(vec2 uv) {
float sq = overcast*overcast;
float m = texture(cloud_map, uv).r;
float s = step(ALPHA_THRESHOLD_CLOUDS, sq);
return vec4(
mix(COLOR_CLOUDS_LIGHT, COLOR_CLOUDS_HEAVY, sq) *
mix(MUL_CLOUDS_EDGE, vec3(1.0), m) *
mix(vec3(1.0), MUL_CLOUDS_NIGHT, night),
mix(
mix(0.0, m, smoothstep(0.0, ALPHA_THRESHOLD_CLOUDS, sq)),
mix(m, 1.0, smoothstep(ALPHA_THRESHOLD_CLOUDS, 1.0, sq)),
s
)
);
}
/// Computes star RGBA at given UV.
vec4 stars(vec2 uv) {
float m = texture(star_map, uv).r;
return vec4(COLOR_STARS, mix(mix(0.0, m, night), 0.0, sqrt(overcast)));
}
/// Computes atmospheric scattering RGB at given UV.
vec3 background(vec2 uv) {
vec3 top = mix(COLOR_DAY, COLOR_NIGHT, night);
vec3 bottom = mix(
top, COLOR_TWILIGHT,
smoothstep(0.5, 0.0, abs(0.5 - night))
);
return mix(
mix(top, bottom, uv.y),
COLOR_CLOUDS_HEAVY * MUL_CLOUDS_EDGE *
mix(vec3(1.0), MUL_CLOUDS_NIGHT, night),
overcast
);
}
/// Computes solid radiance color for entire sky.
vec3 radiance() {
return mix(
mix(RADIANCE_DAY, RADIANCE_NIGHT, night),
RADIANCE_TWILIGHT,
smoothstep(1.0, 0.0, abs(0.5 - night))
)*mix(vec3(1.0), MUL_RADIANCE_OVERCAST, overcast);
}
/// Alpha-blends overlay over opaque underlay.
vec3 alpha_blend_opaque(vec4 overlay, vec3 underlay) {
return mix(underlay, overlay.rgb, overlay.a);
}
/// Composites clouds over stars over background, plus wind and edge fading.
vec3 composite(vec2 uv) {
vec2 uv_after_wind = fract(uv + TIME*wind*wind*PEAK_WIND);
vec3 color = background(uv);
vec4 fade = sqrt(vec4(vec3(1.0), smoothstep(0.5, 0.0, abs(0.5 - uv.y))));
color = alpha_blend_opaque(stars(uv)*fade, color);
color = alpha_blend_opaque(clouds(uv_after_wind)*fade, color);
return color;
}
/// Shader sky pass.
void sky() {
COLOR = AT_CUBEMAP_PASS? radiance() : composite(SKY_COORDS);
}