diff --git a/CHANGELOG.md b/CHANGELOG.md index e61c075bcc..b4d10f00ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - You can no longer write messages to old groups after being kicked and not having updated your chat mode. - Location names are now also correct after editing and creating characters - NPC's wont pick up recently dropped items (if not hostile towards you) +- Fixed "low fps" of different shaders caused by low floating point precision when using time. ## [0.15.0] - 2023-07-01 diff --git a/assets/voxygen/shaders/clouds-frag.glsl b/assets/voxygen/shaders/clouds-frag.glsl index f5e31bdfc4..2b5b9afada 100644 --- a/assets/voxygen/shaders/clouds-frag.glsl +++ b/assets/voxygen/shaders/clouds-frag.glsl @@ -236,19 +236,19 @@ void main() { uvec4 new_mat = texelFetch(usampler2D(t_src_mat, s_src_depth), clamp(ivec2(new_uv * mat_sz), ivec2(0), ivec2(mat_sz) - 1), 0); // If it's the sky, just go determine the sky color analytically to avoid sampling the incomplete skybox // Otherwise, pull the color from the screen-space color buffer - vec3 sky_col = min(get_sky_color(refl_dir, time_of_day.x, wpos, vec3(-100000), 0.125, false, 0.0, true, 0.0), vec3(1)) * not_underground; + vec3 sky_col = min(get_sky_color(refl_dir, wpos, vec3(-100000), 0.125, false, 0.0, true, 0.0), vec3(1)) * not_underground; if (new_mat.a == MAT_SKY) { refl_col = sky_col; } else { refl_col = mix(sky_col, texelFetch(sampler2D(t_src_color, s_src_color), clamp(ivec2(new_uv * col_sz), ivec2(0), ivec2(col_sz) - 1), 0).rgb, merge); } // Apply clouds to reflected colour - refl_col = mix(refl_col, get_cloud_color(refl_col, refl_dir, wpos, time_of_day.x, distance(new_wpos, wpos.xyz), 1.0), not_underground); + refl_col = mix(refl_col, get_cloud_color(refl_col, refl_dir, wpos, distance(new_wpos, wpos.xyz), 1.0), not_underground); } else { // No: assume that anything off-screen is the colour of the sky - refl_col = min(get_sky_color(refl_dir, time_of_day.x, wpos, vec3(-100000), 0.125, true, 1.0, true, 1.0) * not_underground, vec3(1)); + refl_col = min(get_sky_color(refl_dir, wpos, vec3(-100000), 0.125, true, 1.0, true, 1.0) * not_underground, vec3(1)); // Apply clouds to reflection - refl_col = mix(refl_col, get_cloud_color(refl_col, refl_dir, wpos, time_of_day.x, 100000.0, 1.0), not_underground); + refl_col = mix(refl_col, get_cloud_color(refl_col, refl_dir, wpos, 100000.0, 1.0), not_underground); } color.rgb = mix(color.rgb, refl_col, color.a); cloud_blend = 1; @@ -260,7 +260,7 @@ void main() { } } } - color.rgb = mix(color.rgb, get_cloud_color(color.rgb, dir, cam_pos.xyz, time_of_day.x, dist, 1.0), cloud_blend); + color.rgb = mix(color.rgb, get_cloud_color(color.rgb, dir, cam_pos.xyz, dist, 1.0), cloud_blend); #if (CLOUD_MODE == CLOUD_MODE_NONE) color.rgb = apply_point_glow(cam_pos.xyz + focus_off.xyz, dir, dist, color.rgb); diff --git a/assets/voxygen/shaders/figure-frag.glsl b/assets/voxygen/shaders/figure-frag.glsl index d64d7a5603..575fbc3dff 100644 --- a/assets/voxygen/shaders/figure-frag.glsl +++ b/assets/voxygen/shaders/figure-frag.glsl @@ -288,8 +288,8 @@ void main() { /* if ((material & (1u << 1u)) > 0u && false) { vec3 reflect_ray_dir = reflect(cam_to_frag, f_norm); - reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.125, true); - reflect_color = get_cloud_color(reflect_color, reflect_ray_dir, cam_pos.xyz, time_of_day.x, 100000.0, 0.25); + reflect_color = get_sky_color(reflect_ray_dir, f_pos, vec3(-100000), 0.125, true); + reflect_color = get_cloud_color(reflect_color, reflect_ray_dir, cam_pos.xyz, 100000.0, 0.25); reflectance = 1.0; } */ diff --git a/assets/voxygen/shaders/fluid-frag/cheap.glsl b/assets/voxygen/shaders/fluid-frag/cheap.glsl index 37f9e5c561..268b0a0b5d 100644 --- a/assets/voxygen/shaders/fluid-frag/cheap.glsl +++ b/assets/voxygen/shaders/fluid-frag/cheap.glsl @@ -52,22 +52,22 @@ layout(location = 1) out uvec4 tgt_mat; #include #include -vec4 water_col(vec4 posx, vec4 posy) { - posx = (posx + focus_off.x) * 0.1; - posy = (posy + focus_off.y) * 0.1; +vec4 water_col(vec2 pos) { + pos += focus_off.xy; + pos *= 0.1; + vec2 v = floor(f_vel) * 0.1; + vec4 uv = tick_loop4(1, -v.xxyy - vec2(0, 0.1).xyxy, pos.xxyy); + return 0.5 + (vec4( - textureLod(sampler2D(t_noise, s_noise), vec2(posx.x, posy.x), 0).x, - textureLod(sampler2D(t_noise, s_noise), vec2(posx.y, posy.y), 0).x, - textureLod(sampler2D(t_noise, s_noise), vec2(posx.z, posy.z), 0).x, - textureLod(sampler2D(t_noise, s_noise), vec2(posx.w, posy.w), 0).x + textureLod(sampler2D(t_noise, s_noise), uv.xz, 0).x, + textureLod(sampler2D(t_noise, s_noise), uv.yz, 0).x, + textureLod(sampler2D(t_noise, s_noise), uv.xw, 0).x, + textureLod(sampler2D(t_noise, s_noise), uv.yw, 0).x ) - 0.5) * 1.0; } float water_col_vel(vec2 pos){ - vec4 cols = water_col( - pos.x - tick.x * floor(f_vel.x) - vec2(0.0, tick.x).xyxy, - pos.y - tick.x * floor(f_vel.y) - vec2(0.0, tick.x).xxyy - ); + vec4 cols = water_col(pos); return mix( mix(cols.x, cols.y, fract(f_vel.x + 1.0)), mix(cols.z, cols.w, fract(f_vel.x + 1.0)), @@ -163,7 +163,7 @@ void main() { vec3 reflect_color = vec3(0.0); #if (REFLECTION_MODE >= REFLECTION_MODE_MEDIUM) - reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); + reflect_color = get_sky_color(reflect_ray_dir, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); #endif vec3 emitted_light, reflected_light; diff --git a/assets/voxygen/shaders/fluid-frag/shiny.glsl b/assets/voxygen/shaders/fluid-frag/shiny.glsl index 6b9e170fda..39b9946f17 100644 --- a/assets/voxygen/shaders/fluid-frag/shiny.glsl +++ b/assets/voxygen/shaders/fluid-frag/shiny.glsl @@ -54,13 +54,16 @@ layout(location = 1) out uvec4 tgt_mat; #include #include -void wave_dx(vec4 posx, vec4 posy, vec2 dir, float speed, float frequency, float timeshift, out vec4 wave, out vec4 dx) { - vec4 x = vec4( - dot(dir, vec2(posx.x, posy.x)), - dot(dir, vec2(posx.y, posy.y)), - dot(dir, vec2(posx.z, posy.z)), - dot(dir, vec2(posx.w, posy.w)) - ) * frequency + timeshift * speed; +void wave_dx(vec2 pos, vec2 dir, float speed, float frequency, float factor, vec4 accumx, vec4 accumy, out vec4 wave, out vec4 dx) { + float ff = frequency * factor; + + vec2 v = floor(f_vel); + vec4 kx = (v.x + vec2(0, 1)).xyxy; + vec4 ky = (v.y + vec2(0, 1)).xxyy; + vec4 p = speed - ff * (dir.x * kx + dir.y * ky); + vec4 q = frequency * ((dir.x * factor * pos.x + accumx) + dir.y * (factor * pos.y + accumy)); + vec4 x = tick_loop4(2 * PI, p, q); + wave = sin(x) + 0.5; wave *= wave; dx = -wave * cos(x); @@ -70,7 +73,7 @@ void wave_dx(vec4 posx, vec4 posy, vec2 dir, float speed, float frequency, float // Modified to allow calculating the wave function 4 times at once using different positions (used for intepolation // for moving water). The general idea is to sample the wave function at different positions, where those positions // depend on increments of the velocity, and then interpolate between those velocities to get a smooth water velocity. -vec4 wave_height(vec4 posx, vec4 posy) { +vec4 wave_height(vec2 pos) { float iter = 0.0; float phase = 4.0; float weight = 1.5; @@ -79,27 +82,28 @@ vec4 wave_height(vec4 posx, vec4 posy) { const float speed_per_iter = 0.1; #if (FLUID_MODE == FLUID_MODE_HIGH) float speed = 1.0; - posx *= 0.2; - posy *= 0.2; + const float factor = 0.2; const float drag_factor = 0.035; const int iters = 21; const float scale = 15.0; #else float speed = 2.0; - posx *= 0.3; - posy *= 0.3; + const float factor = 0.3; const float drag_factor = 0.04; const int iters = 11; const float scale = 3.0; #endif const float iter_shift = (3.14159 * 2.0) / 7.3; + vec4 accumx = vec4(0); + vec4 accumy = vec4(0); + for(int i = 0; i < iters; i ++) { vec2 p = vec2(sin(iter), cos(iter)); vec4 wave, dx; - wave_dx(posx, posy, p, speed, phase, tick.x, wave, dx); - posx += p.x * dx * weight * drag_factor; - posy += p.y * dx * weight * drag_factor; + wave_dx(pos, p, speed, phase, factor, accumx, accumy, wave, dx); + accumx += p.x * dx * weight * drag_factor; + accumy += p.y * dx * weight * drag_factor; w += wave * weight; iter += iter_shift * 1.5; ws += weight; @@ -111,10 +115,7 @@ vec4 wave_height(vec4 posx, vec4 posy) { } float wave_height_vel(vec2 pos) { - vec4 heights = wave_height( - pos.x - tick.x * floor(f_vel.x) - vec2(0.0, tick.x).xyxy, - pos.y - tick.x * floor(f_vel.y) - vec2(0.0, tick.x).xxyy - ); + vec4 heights = wave_height(pos); return mix( mix(heights.x, heights.y, fract(f_vel.x + 1.0)), mix(heights.z, heights.w, fract(f_vel.x + 1.0)), @@ -275,7 +276,7 @@ void main() { /* reflect_color = get_cloud_color(reflect_color, ray_dir, f_pos.xyz, time_of_day.x, 100000.0, 0.1); */ reflect_color = vec3(0); #else - reflect_color = get_sky_color(ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); + reflect_color = get_sky_color(ray_dir, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); #endif // Sort of non-physical, but we try to balance the reflection intensity with the direct light from the sun, // resulting in decent reflection of the ambient environment even after the sun has gone down. @@ -339,7 +340,7 @@ void main() { float passthrough = max(dot(cam_norm, -cam_to_frag), 0) * 0.75; float max_light = 0.0; - max_light += get_sun_diffuse2(sun_info, moon_info, cam_norm, /*time_of_day.x*/sun_view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, vec3(k_d), /*vec3(f_light * point_shadow)*//*reflect_color*/k_s, alpha, f_norm, 1.0, emitted_light, reflected_light); + max_light += get_sun_diffuse2(sun_info, moon_info, cam_norm, sun_view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, vec3(k_d), /*vec3(f_light * point_shadow)*//*reflect_color*/k_s, alpha, f_norm, 1.0, emitted_light, reflected_light); emitted_light *= not_underground; reflected_light *= not_underground; diff --git a/assets/voxygen/shaders/fluid-vert.glsl b/assets/voxygen/shaders/fluid-vert.glsl index 8e84cc7596..2a8ca89eff 100644 --- a/assets/voxygen/shaders/fluid-vert.glsl +++ b/assets/voxygen/shaders/fluid-vert.glsl @@ -65,7 +65,7 @@ void main() { // Terrain 'pop-in' effect #ifndef EXPERIMENTAL_BAREMINIMUM #ifndef EXPERIMENTAL_NOTERRAINPOP - f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0)); + f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(time_since(load_time), 10.0), 1.0)); // f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0)); #endif #endif diff --git a/assets/voxygen/shaders/include/cloud/none.glsl b/assets/voxygen/shaders/include/cloud/none.glsl index 97a6e610e5..05348f94c1 100644 --- a/assets/voxygen/shaders/include/cloud/none.glsl +++ b/assets/voxygen/shaders/include/cloud/none.glsl @@ -1,12 +1,12 @@ #include #include -vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, float time_of_day, float max_dist, float quality) { +vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, float max_dist, float quality) { // Underwater light attenuation surf_color = water_diffuse(surf_color, dir, max_dist); if (max_dist < DIST_CAP) { - vec3 sky_light = get_sky_light(dir, time_of_day, false); + vec3 sky_light = get_sky_light(dir, false); surf_color = mix(sky_light, surf_color, 1.0 / exp(max_dist / 5000.0)); } diff --git a/assets/voxygen/shaders/include/cloud/regular.glsl b/assets/voxygen/shaders/include/cloud/regular.glsl index 636a767f9f..80e870d5a2 100644 --- a/assets/voxygen/shaders/include/cloud/regular.glsl +++ b/assets/voxygen/shaders/include/cloud/regular.glsl @@ -142,7 +142,7 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground if (emission_strength <= 0.0) { emission = vec3(0); } else { - float nz = textureLod(sampler2D(t_noise, s_noise), wind_pos.xy * 0.00005 - time_of_day.x * 0.0001, 0).x;//noise_3d(vec3(wind_pos.xy * 0.00005 + cloud_tendency * 0.2, time_of_day.x * 0.0002)); + float nz = textureLod(sampler2D(t_noise, s_noise), wind_pos.xy * 0.00005 - time_of_day.y * 8.0, 0).x;//noise_3d(vec3(wind_pos.xy * 0.00005 + cloud_tendency * 0.2, time_of_day.x * 0.0002)); float emission_alt = alt * 0.5 + 1000 + 1000 * nz; float emission_height = 1000.0; @@ -195,7 +195,7 @@ float dist_to_step(float dist, float quality) { // consistently support forward declarations (not surprising, it's designed for single-pass compilers). #include -vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of_day, float max_dist, const float quality) { +vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, float max_dist, const float quality) { // Limit the marching distance to reduce maximum jumps max_dist = min(max_dist, DIST_CAP); @@ -205,7 +205,7 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of // improves visual quality for low cloud settings float splay = 1.0; #if (CLOUD_MODE == CLOUD_MODE_MINIMAL) - splay += (textureLod(sampler2D(t_noise, s_noise), vec2(atan2(dir.x, dir.y) * 2 / PI, dir.z) * 5.0 - time_of_day * 0.00005, 0).x - 0.5) * 0.025 / (1.0 + pow(dir.z, 2) * 10); + splay += (textureLod(sampler2D(t_noise, s_noise), vec2(atan2(dir.x, dir.y) * 2 / PI, dir.z) * 5.0 - time_of_day.y * 4.0, 0).x - 0.5) * 0.025 / (1.0 + pow(dir.z, 2) * 10); #endif const vec3 RAYLEIGH = vec3(0.025, 0.1, 0.5); @@ -215,7 +215,7 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of float moon_scatter = dot(-dir, moon_dir.xyz) * 0.5 + 0.7; float net_light = get_sun_brightness() + get_moon_brightness(); vec3 sky_color = RAYLEIGH * net_light; - vec3 sky_light = get_sky_light(dir, time_of_day, false); + vec3 sky_light = get_sky_light(dir, false); vec3 sun_color = get_sun_color(); vec3 moon_color = get_moon_color(); diff --git a/assets/voxygen/shaders/include/globals.glsl b/assets/voxygen/shaders/include/globals.glsl index 0012dab2ca..2d600f9f3f 100644 --- a/assets/voxygen/shaders/include/globals.glsl +++ b/assets/voxygen/shaders/include/globals.glsl @@ -9,9 +9,14 @@ layout(std140, set = 0, binding = 0) uniform u_globals { vec4 focus_off; vec4 focus_pos; vec4 view_distance; + // .x = time of day, repeats every day. + // .y = a continuous value for what day it is. Repeats every `tick_overflow` for precisions sake. vec4 time_of_day; vec4 sun_dir; vec4 moon_dir; + // .x = The `Time` resource, repeated every `tick_overflow` + // .y = a floored (`Time` / `tick_overflow`) + // .z = `Time`, not recommended to be used as it might have low precision vec4 tick; vec4 screen_res; uvec4 light_shadow_count; @@ -39,4 +44,33 @@ mat4 threshold_matrix = mat4( float distance_divider = 2; float shadow_dithering = 0.5; +float tick_overflow = 300000.0; + +// Get a scaled time with an offset that loops at a period. +float tick_loop(float period, float scale, float offset) { + float loop = tick_overflow * scale; + float rem = mod(loop, period); + float rest = rem * tick.y; + + return mod(rest + tick.x * scale + offset, period); +} + +float tick_loop(float period) { + return tick_loop(period, 1.0, 0.0); +} + + +vec4 tick_loop4(float period, vec4 scale, vec4 offset) { + vec4 loop = tick_overflow * scale; + vec4 rem = mod(loop, period); + vec4 rest = rem * tick.y; + + return mod(rest + tick.x * scale + offset, period); +} + +// Only works if t happened within tick_overflow +float time_since(float t) { + return tick.x < t ? (tick_overflow - t + tick.x) : (tick.x - t); +} + #endif diff --git a/assets/voxygen/shaders/include/lod.glsl b/assets/voxygen/shaders/include/lod.glsl index 782770044a..906fca341c 100644 --- a/assets/voxygen/shaders/include/lod.glsl +++ b/assets/voxygen/shaders/include/lod.glsl @@ -152,8 +152,7 @@ float alt_at_real(vec2 pos) { } -float horizon_at2(vec4 f_horizons, float alt, vec3 pos, /*float time_of_day*/vec4 light_dir) { - // vec3 sun_dir = get_sun_dir(time_of_day); +float horizon_at2(vec4 f_horizons, float alt, vec3 pos, vec4 light_dir) { const float PI_2 = 3.1415926535897932384626433832795 / 2.0; const float MIN_LIGHT = 0.0;//0.115/*0.0*/; diff --git a/assets/voxygen/shaders/include/point_glow.glsl b/assets/voxygen/shaders/include/point_glow.glsl index 84291cf60b..855e82d82b 100644 --- a/assets/voxygen/shaders/include/point_glow.glsl +++ b/assets/voxygen/shaders/include/point_glow.glsl @@ -58,7 +58,7 @@ vec3 apply_point_glow(vec3 wpos, vec3 dir, float max_dist, vec3 color) { #endif #ifdef FLASHING_LIGHTS_ENABLED - float time_since_lightning = tick.x - last_lightning.w; + float time_since_lightning = time_since(last_lightning.w); if (time_since_lightning < MAX_LIGHTNING_PERIOD) { // Apply lightning apply_point_glow_light(Light(last_lightning.xyzw + vec4(0, 0, LIGHTNING_HEIGHT, 0), vec4(vec3(0.2, 0.4, 1) * lightning_intensity() * 0.003, 1)), wpos, dir, max_dist, color); diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index a73c95d4bc..0186241756 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -17,7 +17,7 @@ struct DirectionalLight { // float brightness; }; -const float PI = 3.141592; +const float PI = 3.141592653; const vec3 SKY_DAWN_TOP = vec3(0.10, 0.1, 0.10); const vec3 SKY_DAWN_MID = vec3(1.2, 0.3, 0.2); @@ -94,7 +94,7 @@ vec3 glow_light(vec3 pos) { float CLOUD_AVG_ALT = view_distance.z + (view_distance.w - view_distance.z) * 1.25; const float wind_speed = 0.25; -vec2 wind_offset = vec2(time_of_day.x * wind_speed); +vec2 wind_offset = vec2(time_of_day.y * wind_speed * (3600.0 * 24.0)); float cloud_scale = view_distance.z / 150.0; @@ -140,7 +140,7 @@ float cloud_shadow(vec3 pos, vec3 light_dir) { #endif } -float magnetosphere = sin(time_of_day.x / (3600 * 24)); +float magnetosphere = sin(time_of_day.y); #if (CLOUD_MODE <= CLOUD_MODE_LOW) const vec3 magnetosphere_tint = vec3(1); #else @@ -156,7 +156,7 @@ float magnetosphere = sin(time_of_day.x / (3600 * 24)); #if (CLOUD_MODE > CLOUD_MODE_NONE) float emission_strength = clamp((magnetosphere - 0.3) * 1.3, 0, 1) * max(-moon_dir.z, 0); #if (CLOUD_MODE >= CLOUD_MODE_MEDIUM) - float emission_br = abs(pow(fract(time_of_day.x * 0.000005) * 2 - 1, 2)); + float emission_br = abs(pow(fract(time_of_day.y * 0.5) * 2 - 1, 2)); #else float emission_br = 0.5; #endif @@ -236,7 +236,7 @@ const float LIGHTNING_HEIGHT = 25.0; const float MAX_LIGHTNING_PERIOD = 5.0; float lightning_intensity() { - float time_since_lightning = tick.x - last_lightning.w; + float time_since_lightning = time_since(last_lightning.w); return // Strength 1000000 @@ -247,7 +247,7 @@ float lightning_intensity() { } vec3 lightning_at(vec3 wpos) { - float time_since_lightning = tick.x - last_lightning.w; + float time_since_lightning = time_since(last_lightning.w); if (time_since_lightning < MAX_LIGHTNING_PERIOD) { vec3 diff = wpos + focus_off.xyz - (last_lightning.xyz + vec3(0, 0, LIGHTNING_HEIGHT)); float dist = length(diff); @@ -489,7 +489,6 @@ float get_sun_diffuse2(DirectionalLight sun_info, DirectionalLight moon_info, ve // This has been extracted into a function to allow quick exit when detecting a star. float is_star_at(vec3 dir) { - float star_scale = 80.0; // Star positions @@ -516,7 +515,7 @@ float is_star_at(vec3 dir) { return power * max(sun_dir.z, 0.1) / (1.0 + pow(dist * 750, 8)); } -vec3 get_sky_light(vec3 dir, float time_of_day, bool with_stars) { +vec3 get_sky_light(vec3 dir, bool with_stars) { // Add white dots for stars. Note these flicker and jump due to FXAA float star = 0.0; if (with_stars) { @@ -580,15 +579,11 @@ vec3 get_sky_light(vec3 dir, float time_of_day, bool with_stars) { return sky_color * magnetosphere_tint; } -vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_features, float refractionIndex, bool fake_clouds, float sun_shade_frac) { +vec3 get_sky_color(vec3 dir, vec3 origin, vec3 f_pos, float quality, bool with_features, float refractionIndex, bool fake_clouds, float sun_shade_frac) { // Sky color - /* vec3 sun_dir = get_sun_dir(time_of_day); - vec3 moon_dir = get_moon_dir(time_of_day); */ vec3 sun_dir = sun_dir.xyz; vec3 moon_dir = moon_dir.xyz; - // sun_dir = sun_dir.z <= 0 ? refract(sun_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : sun_dir; - // moon_dir = moon_dir.z <= 0 ? refract(moon_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : moon_dir; // Sun const vec3 SUN_SURF_COLOR = vec3(1.5, 0.9, 0.35) * 10.0; @@ -660,10 +655,10 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q #else if (fake_clouds || medium.x == MEDIUM_WATER) { #endif - sky_color = get_sky_light(dir, time_of_day, !fake_clouds); + sky_color = get_sky_light(dir, !fake_clouds); } else { if (medium.x == MEDIUM_WATER) { - sky_color = get_sky_light(dir, time_of_day, true); + sky_color = get_sky_light(dir, true); } else { vec3 star_dir = normalize(sun_dir.xyz * dir.z + cross(sun_dir.xyz, vec3(0, 1, 0)) * dir.x + vec3(0, 1, 0) * dir.y); float star = is_star_at(star_dir); @@ -674,12 +669,12 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q return sky_color + sun_light + moon_light; } -vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_features, float refractionIndex) { - return get_sky_color(dir, time_of_day, origin, f_pos, quality, with_features, refractionIndex, false, 1.0); +vec3 get_sky_color(vec3 dir, vec3 origin, vec3 f_pos, float quality, bool with_features, float refractionIndex) { + return get_sky_color(dir, origin, f_pos, quality, with_features, refractionIndex, false, 1.0); } -vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars) { - return get_sky_color(dir, time_of_day, origin, f_pos, quality, with_stars, 1.0, false, 1.0); +vec3 get_sky_color(vec3 dir, vec3 origin, vec3 f_pos, float quality, bool with_stars) { + return get_sky_color(dir, origin, f_pos, quality, with_stars, 1.0, false, 1.0); } float fog(vec3 f_pos, vec3 focus_pos, uint medium) { diff --git a/assets/voxygen/shaders/lod-terrain-frag.glsl b/assets/voxygen/shaders/lod-terrain-frag.glsl index 498385b3a2..eb6da1bc90 100644 --- a/assets/voxygen/shaders/lod-terrain-frag.glsl +++ b/assets/voxygen/shaders/lod-terrain-frag.glsl @@ -662,10 +662,10 @@ void main() { vec3 reflect_color; #if (FLUID_MODE == FLUID_MODE_HIGH) - reflect_color = get_sky_color(reflect_ray, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); - reflect_color = get_cloud_color(reflect_color, reflect_ray, cam_pos.xyz, time_of_day.x, 100000.0, 0.1); + reflect_color = get_sky_color(reflect_ray, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); + reflect_color = get_cloud_color(reflect_color, reflect_ray, cam_pos.xyz, 100000.0, 0.1); #else - reflect_color = get_sky_color(reflect_ray, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); + reflect_color = get_sky_color(reflect_ray, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); #endif reflect_color *= sun_shade_frac * 0.75 + 0.25; @@ -678,7 +678,7 @@ void main() { surf_alpha = 1.0 - passthrough; #else surf_alpha = 0.9; - surf_color = get_sky_color(reflect_ray, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); + surf_color = get_sky_color(reflect_ray, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac); #endif } else { mat = MAT_LOD; diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 436512dfb3..8a83af9a51 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -95,7 +95,17 @@ struct Attr { mat4 rot; }; -float lifetime = tick.x - inst_time; +float lifetime = time_since(inst_time); + +// Retrieves inst_time, repeating over a period. This will be consistent +// over a time overflow. +float loop_inst_time(float period, float scale) { + if (tick.x < inst_time) { + return mod(mod(tick_overflow * scale, period) + inst_time * scale, period); + } else { + return mod(inst_time * scale, period); + } +} vec3 linear_motion(vec3 init_offs, vec3 vel) { return init_offs + vel * lifetime; @@ -420,14 +430,14 @@ void main() { break; case LIFESTEAL_BEAM: f_reflect = 0.0; - float green_col = 0.8 + 0.8 * sin(tick.x * 5 + lifetime * 5); - float purple_col = 0.6 + 0.5 * sin(tick.x * 4 - lifetime * 4) - min(max(green_col - 1, 0), 0.3); - float red_col = 1.15 + 0.1 * sin(tick.x * 3 - lifetime * 3) - min(max(green_col - 1, 0), 0.3) - max(purple_col - 0.5, 0); + float green_col = 0.8 + 0.8 * sin(tick_loop(2 * PI, 5, lifetime * 5)); + float purple_col = 0.6 + 0.5 * sin(loop_inst_time(2 * PI, 4)) - min(max(green_col - 1, 0), 0.3); + float red_col = 1.15 + 0.1 * sin(loop_inst_time(2 * PI, 3)) - min(max(green_col - 1, 0), 0.3) - max(purple_col - 0.5, 0); attr = Attr( - spiral_motion(inst_dir, 0.3 * (floor(2 * rand0 + 0.5) - 0.5) * min(linear_scale(10), 1), lifetime / inst_lifespan, 10.0, inst_time), - vec3((1.7 - 0.7 * abs(floor(2 * rand0 - 0.5) + 0.5)) * (1.5 + 0.5 * sin(tick.x * 10 - lifetime * 4))), + spiral_motion(inst_dir, 0.3 * (floor(2 * rand0 + 0.5) - 0.5) * min(linear_scale(10), 1), lifetime / inst_lifespan, 10.0, loop_inst_time(2.0 * PI, 1.0)), + vec3((1.7 - 0.7 * abs(floor(2 * rand0 - 0.5) + 0.5)) * (1.5 + 0.5 * sin(tick_loop(2 * PI, 10, -lifetime * 4)))), vec4(vec3(red_col + purple_col * 0.6, green_col + purple_col * 0.35, purple_col), 1), - spin_in_axis(inst_dir, tick.z) + spin_in_axis(inst_dir, tick_loop(2 * PI)) ); break; case ENERGY_NATURE: diff --git a/assets/voxygen/shaders/postprocess-frag.glsl b/assets/voxygen/shaders/postprocess-frag.glsl index 3810c8e647..5fa525517e 100644 --- a/assets/voxygen/shaders/postprocess-frag.glsl +++ b/assets/voxygen/shaders/postprocess-frag.glsl @@ -244,7 +244,9 @@ void main() { vec2 sample_uv = uv; #ifdef EXPERIMENTAL_UNDERWARPER if (medium.x == MEDIUM_WATER) { - sample_uv += sin(uv.yx * 60 + tick.xx * 3.0) * 0.003; + float x = tick_loop(2.0 * PI, 3.0, uv.y * 60); + float y = tick_loop(2.0 * PI, 3.0, uv.x * 60); + sample_uv += sin(vec2(x, y)) * 0.003; } #endif @@ -310,7 +312,7 @@ void main() { float dist = distance(wpos, cam_pos.xyz); vec3 dir = (wpos - cam_pos.xyz) / dist; - aa_color.rgb = get_cloud_color(aa_color.rgb, dir, cam_pos.xyz, time_of_day.x, dist, 1.0); + aa_color.rgb = get_cloud_color(aa_color.rgb, dir, cam_pos.xyz, dist, 1.0); #endif */ diff --git a/assets/voxygen/shaders/skybox-frag.glsl b/assets/voxygen/shaders/skybox-frag.glsl index 704b184d25..fcfc89fa84 100644 --- a/assets/voxygen/shaders/skybox-frag.glsl +++ b/assets/voxygen/shaders/skybox-frag.glsl @@ -56,6 +56,6 @@ void main() { } */ vec3 wpos = cam_pos.xyz + /*normalize(f_pos)*/cam_dir * dist; - tgt_color = vec4(cam_attenuation * get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, wpos, 1.0, true, refractionIndex, false, 1.0), 1.0); + tgt_color = vec4(cam_attenuation * get_sky_color(normalize(f_pos), cam_pos.xyz, wpos, 1.0, true, refractionIndex, false, 1.0), 1.0); tgt_mat = uvec4(uvec3(0), MAT_SKY); } diff --git a/assets/voxygen/shaders/sprite-vert.glsl b/assets/voxygen/shaders/sprite-vert.glsl index 70fe716f15..a17f7be369 100644 --- a/assets/voxygen/shaders/sprite-vert.glsl +++ b/assets/voxygen/shaders/sprite-vert.glsl @@ -83,8 +83,8 @@ float wind_wave(float off, float scaling, float speed, float strength) { strength = max(strength, 6.0); aspeed = max(aspeed, 5.0); - return (sin(tick.x * 0.35 * scaling * floor(aspeed) + off) * (1.0 - fract(aspeed)) - + sin(tick.x * 0.35 * scaling * ceil(aspeed) + off) * fract(aspeed)) * abs(strength) * 0.25; + return (sin(tick_loop(2.0 * PI, 0.35 * scaling * floor(aspeed), off)) * (1.0 - fract(aspeed)) + + sin(tick_loop(2.0 * PI, 0.35 * scaling * ceil(aspeed), off)) * fract(aspeed)) * abs(strength) * 0.25; //return sin(tick.x * 1.5 * scaling + off) + sin(tick.x * 0.35 * scaling + off); } @@ -152,7 +152,7 @@ void main() { #ifndef EXPERIMENTAL_BAREMINIMUM #ifndef EXPERIMENTAL_NOTERRAINPOP // Terrain 'pop-in' effect - f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0)); + f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(time_since(load_time), 10.0), 1.0)); #endif #endif diff --git a/assets/voxygen/shaders/terrain-frag.glsl b/assets/voxygen/shaders/terrain-frag.glsl index d50ba6f941..be359c038a 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -267,12 +267,14 @@ void main() { if (puddle > 0.0) { f_alpha = puddle * 0.2 * max(1.0 + cam_to_frag.z, 0.3); #ifdef EXPERIMENTAL_PUDDLEDETAILS - float h = (noise_2d((f_pos.xy + focus_off.xy) * 0.3) - 0.5) * sin(tick.x * 8.0 + f_pos.x * 3) - + (noise_2d((f_pos.xy + focus_off.xy) * 0.6) - 0.5) * sin(tick.x * 3.5 - f_pos.y * 6); - float hx = (noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.3) - 0.5) * sin(tick.x * 8.0 + f_pos.x * 3) - + (noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.6) - 0.5) * sin(tick.x * 3.5 - f_pos.y * 6); - float hy = (noise_2d((f_pos.xy + focus_off.xy + vec2(0, 0.1)) * 0.3) - 0.5) * sin(tick.x * 8.0 + f_pos.x * 3) - + (noise_2d((f_pos.xy + focus_off.xy + vec2(0, 0.1)) * 0.6) - 0.5) * sin(tick.x * 3.5 - f_pos.y * 6); + let t0 = sin(tick_loop(2.0 * PI, 8.0, f_pos.x * 3)); + let t1 = sin(tick_loop(2.0 * PI, 3.5, -f_pos.x * 6)); + float h = (noise_2d((f_pos.xy + focus_off.xy) * 0.3) - 0.5) * t0 + + (noise_2d((f_pos.xy + focus_off.xy) * 0.6) - 0.5) * t1; + float hx = (noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.3) - 0.5) * t0 + + (noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.6) - 0.5) * t1; + float hy = (noise_2d((f_pos.xy + focus_off.xy + vec2(0, 0.1)) * 0.3) - 0.5) * t0 + + (noise_2d((f_pos.xy + focus_off.xy + vec2(0, 0.1)) * 0.6) - 0.5) * t1; f_norm.xy += mix(vec2(0), vec2(h - hx, h - hy) / 0.1 * 0.03, puddle); #endif alpha = mix(1.0, 0.2, puddle); @@ -387,7 +389,7 @@ void main() { vec3 emitted_light = vec3(1.0); vec3 reflected_light = vec3(1.0); - float sun_diffuse = get_sun_diffuse2(/*time_of_day.x, */sun_info, moon_info, f_norm, view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, f_norm, 1.0, emitted_light, reflected_light); + float sun_diffuse = get_sun_diffuse2(sun_info, moon_info, f_norm, view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, f_norm, 1.0, emitted_light, reflected_light); max_light += sun_diffuse; // emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW); diff --git a/assets/voxygen/shaders/terrain-vert.glsl b/assets/voxygen/shaders/terrain-vert.glsl index 0bec8df876..893c186ea2 100644 --- a/assets/voxygen/shaders/terrain-vert.glsl +++ b/assets/voxygen/shaders/terrain-vert.glsl @@ -82,7 +82,7 @@ void main() { // Terrain 'pop-in' effect #ifndef EXPERIMENTAL_BAREMINIMUM #ifndef EXPERIMENTAL_NOTERRAINPOP - v_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0)); + v_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(time_since(load_time), 10.0), 1.0)); // f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0)); #endif #endif diff --git a/client/src/lib.rs b/client/src/lib.rs index 34ed295b39..7d525585b1 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1929,9 +1929,9 @@ impl Client { self.tick_terrain()?; // Send a ping to the server once every second - if self.state.get_time() - self.last_server_ping > 1. { + if self.state.get_program_time() - self.last_server_ping > 1. { self.send_msg_err(PingMsg::Ping)?; - self.last_server_ping = self.state.get_time(); + self.last_server_ping = self.state.get_program_time(); } // 6) Update the server about the player's physics attributes. @@ -2269,12 +2269,13 @@ impl Client { ServerGeneral::TimeOfDay(time_of_day, calendar, new_time, time_scale) => { self.target_time_of_day = Some(time_of_day); *self.state.ecs_mut().write_resource() = calendar; + *self.state.ecs_mut().write_resource() = time_scale; let mut time = self.state.ecs_mut().write_resource::