From 8e0578f8b0b4eda381a545290980e8e493ceade9 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 16 Nov 2020 22:46:31 +0000 Subject: [PATCH] Added occasional sky emission at night --- .../shaders/include/cloud/regular.glsl | 14 ++++- assets/voxygen/shaders/include/sky.glsl | 8 +-- server/src/cmd.rs | 57 +++++++++++-------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/assets/voxygen/shaders/include/cloud/regular.glsl b/assets/voxygen/shaders/include/cloud/regular.glsl index 79f8ddad72..1fa0584325 100644 --- a/assets/voxygen/shaders/include/cloud/regular.glsl +++ b/assets/voxygen/shaders/include/cloud/regular.glsl @@ -16,7 +16,7 @@ vec2 get_cloud_heights(vec2 pos) { } // Returns vec4(r, g, b, density) -vec4 cloud_at(vec3 pos, float dist) { +vec4 cloud_at(vec3 pos, float dist, out vec4 emission) { // Natural attenuation of air (air naturally attenuates light that passes through it) // Simulate the atmosphere thinning above 3000 metres down to nothing at 5000 metres float air = 0.0001 * clamp((10000.0 - pos.z) / 7000, 0, 1); @@ -84,6 +84,14 @@ vec4 cloud_at(vec3 pos, float dist) { float not_underground = clamp(1.0 - (alt_at(pos.xy - focus_off.xy) - (pos.z - focus_off.z)) / 80.0, 0, 1); float vapor_density = (mist + cloud) * not_underground; + float tail = sin(wind_pos.x * 0.001) * pos.z * 0.0005; + vec3 emission_col = vec3(0.1 + tail, 1.0, 0.3 + tail * 0.3); + float emission_alt = 3000.0 + sin(wind_pos.x + time_of_day.x * 0.0002); + float emission_nz = max(texture(t_noise, wind_pos.xy * 0.00001).x - 0.5, 0) * 20 / (10.0 + abs(pos.z - emission_alt) / 80) + * (1.0 + (noise_3d(vec3(wind_pos.xy * 0.05, time_of_day.x * 0.3) * 0.004) - 0.5) * 2.0); + emission_nz *= max(sin(time_of_day.x / (3600 * 24)) - 0.8, 0) / 0.2; + emission = vec4(emission_col, emission_nz * sun_dir.z); + // We track vapor density and air density separately. Why? Because photons will ionize particles in air // leading to rayleigh scattering, but water vapor will not. Tracking these indepedently allows us to // get more correct colours. @@ -149,7 +157,8 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of float cdist = max_dist; while (cdist > 1) { float ndist = step_to_dist(trunc(dist_to_step(cdist - 0.25))); - vec4 sample = cloud_at(origin + (dir + dir_diff / ndist) * ndist * splay, ndist); + vec4 emission; + vec4 sample = cloud_at(origin + (dir + dir_diff / ndist) * ndist * splay, ndist, emission); vec2 density_integrals = max(sample.zw, vec2(0)) * (cdist - ndist); @@ -168,6 +177,7 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of get_sun_color() * sun_scatter * sun_access * scatter_factor * get_sun_brightness() + // Really we should multiple by just moon_brightness here but this just looks better given that we lack HDR get_moon_color() * moon_scatter * moon_access * scatter_factor * get_moon_brightness() * 4.0 + + emission.rgb * emission.a * density_integrals.y + // Global illumination (uniform scatter from the sky) sky_color * sun_access * scatter_factor * get_sun_brightness() + sky_color * moon_access * scatter_factor * get_moon_brightness(); diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index 2c8704f08d..f6129477ee 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -22,8 +22,8 @@ const vec3 SUN_HALO_DAY = vec3(0.35, 0.35, 0.05); const vec3 SKY_DUSK_TOP = vec3(0.06, 0.1, 0.20); const vec3 SKY_DUSK_MID = vec3(0.35, 0.1, 0.15); const vec3 SKY_DUSK_BOT = vec3(0.0, 0.1, 0.23); -const vec3 DUSK_LIGHT = vec3(9.0, 1.5, 0.15); -const vec3 SUN_HALO_DUSK = vec3(1.2, 0.025, 0.0); +const vec3 DUSK_LIGHT = vec3(9.0, 1.0, 0.05); +const vec3 SUN_HALO_DUSK = vec3(1.2, 0.05, 0.01); const vec3 SKY_NIGHT_TOP = vec3(0.001, 0.001, 0.0025); const vec3 SKY_NIGHT_MID = vec3(0.001, 0.005, 0.02); @@ -393,7 +393,7 @@ float is_star_at(vec3 dir) { // Star threshold if (dist < 0.0015) { - return 1.0; + return 2.5; } return 0.0; @@ -435,7 +435,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q // Moon const vec3 MOON_SURF_COLOR = vec3(0.7, 1.0, 1.5) * 10.0; - const vec3 MOON_HALO_COLOR = vec3(0.015, 0.015, 0.05) * 20; + const vec3 MOON_HALO_COLOR = vec3(0.015, 0.015, 0.05) * 10; vec3 moon_halo_color = MOON_HALO_COLOR; vec3 moon_halo = moon_halo_color * pow(max(dot(dir, -moon_dir), 0), 50.0); diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 88fca9a976..3558872456 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -423,23 +423,31 @@ fn handle_time( ) { let time = scan_fmt_some!(&args, &action.arg_fmt(), String); let new_time = match time.as_deref() { - Some("midnight") => NaiveTime::from_hms(0, 0, 0), - Some("night") => NaiveTime::from_hms(20, 0, 0), - Some("dawn") => NaiveTime::from_hms(5, 0, 0), - Some("morning") => NaiveTime::from_hms(8, 0, 0), - Some("day") => NaiveTime::from_hms(10, 0, 0), - Some("noon") => NaiveTime::from_hms(12, 0, 0), - Some("dusk") => NaiveTime::from_hms(17, 0, 0), + Some("midnight") => NaiveTime::from_hms(0, 0, 0).num_seconds_from_midnight() as f64, + Some("night") => NaiveTime::from_hms(20, 0, 0).num_seconds_from_midnight() as f64, + Some("dawn") => NaiveTime::from_hms(5, 0, 0).num_seconds_from_midnight() as f64, + Some("morning") => NaiveTime::from_hms(8, 0, 0).num_seconds_from_midnight() as f64, + Some("day") => NaiveTime::from_hms(10, 0, 0).num_seconds_from_midnight() as f64, + Some("noon") => NaiveTime::from_hms(12, 0, 0).num_seconds_from_midnight() as f64, + Some("dusk") => NaiveTime::from_hms(17, 0, 0).num_seconds_from_midnight() as f64, Some(n) => match n.parse() { Ok(n) => n, Err(_) => match NaiveTime::parse_from_str(n, "%H:%M") { - Ok(time) => time, - Err(_) => { - server.notify_client( - client, - ChatType::CommandError.server_msg(format!("'{}' is not a valid time.", n)), - ); - return; + Ok(time) => time.num_seconds_from_midnight() as f64, + // Accept `u12345`, seconds since midnight day 0` + Err(_) => match n + .get(1..) + .filter(|_| n.chars().next() == Some('u')) + .and_then(|n| n.trim_left_matches('u').parse::().ok()) + { + Some(n) => n as f64, + None => { + server.notify_client( + client, + ChatType::CommandError.server_msg(format!("'{}' is not a valid time.", n)), + ); + return; + }, }, }, }, @@ -460,16 +468,19 @@ fn handle_time( }, }; - server.state.ecs_mut().write_resource::().0 = - new_time.num_seconds_from_midnight() as f64; + server.state.ecs_mut().write_resource::().0 = new_time; - server.notify_client( - client, - ChatType::CommandInfo.server_msg(format!( - "Time changed to: {}", - new_time.format("%H:%M").to_string() - )), - ); + if let Some(new_time) = NaiveTime::from_num_seconds_from_midnight_opt(((new_time as u64) % 86400) as u32, 0) { + server.notify_client( + client, + ChatType::CommandInfo.server_msg(format!( + "Time changed to: {}", + new_time + .format("%H:%M") + .to_string(), + )), + ); + } } fn handle_health(