From a152e4dfb4eb552259bbdcf4c2f63171cd609582 Mon Sep 17 00:00:00 2001 From: Isse Date: Thu, 28 Sep 2023 01:03:42 +0200 Subject: [PATCH] time-proof usages of tick --- assets/voxygen/shaders/fluid-frag/cheap.glsl | 26 +++++++------ assets/voxygen/shaders/fluid-frag/shiny.glsl | 37 ++++++++++--------- assets/voxygen/shaders/fluid-vert.glsl | 2 +- assets/voxygen/shaders/include/globals.glsl | 20 ++++++++++ .../voxygen/shaders/include/point_glow.glsl | 2 +- assets/voxygen/shaders/include/sky.glsl | 6 +-- assets/voxygen/shaders/particle-vert.glsl | 22 +++++++---- assets/voxygen/shaders/postprocess-frag.glsl | 4 +- assets/voxygen/shaders/sprite-vert.glsl | 6 +-- assets/voxygen/shaders/terrain-frag.glsl | 14 ++++--- assets/voxygen/shaders/terrain-vert.glsl | 2 +- client/src/lib.rs | 8 +++- common/net/src/msg/server.rs | 1 + server/src/sys/msg/general.rs | 4 +- server/src/sys/msg/register.rs | 4 +- voxygen/src/render/pipelines/mod.rs | 13 +++++-- voxygen/src/render/pipelines/particle.rs | 16 ++++++-- 17 files changed, 121 insertions(+), 66 deletions(-) diff --git a/assets/voxygen/shaders/fluid-frag/cheap.glsl b/assets/voxygen/shaders/fluid-frag/cheap.glsl index b13e97c75d..05584aaccf 100644 --- a/assets/voxygen/shaders/fluid-frag/cheap.glsl +++ b/assets/voxygen/shaders/fluid-frag/cheap.glsl @@ -52,22 +52,24 @@ 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 = pos + focus_off.xy; + vec2 v = floor(f_vel); + float x0 = tick_loop(1, -v.x * 0.1, pos.x * 0.1); + float x1 = tick_loop(1, -(v.x + 1) * 0.1, pos.x * 0.1); + float y0 = tick_loop(1, -v.y * 0.1, pos.y * 0.1); + float y1 = tick_loop(1, -(v.y + 1) * 0.1, pos.y * 0.1); + 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), vec2(x0, y0), 0).x, + textureLod(sampler2D(t_noise, s_noise), vec2(x1, y0), 0).x, + textureLod(sampler2D(t_noise, s_noise), vec2(x0, y1), 0).x, + textureLod(sampler2D(t_noise, s_noise), vec2(x1, y1), 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)), @@ -183,7 +185,7 @@ void main() { // vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0)); float max_light = 0.0; - max_light += get_sun_diffuse2(sun_info, moon_info, f_norm, sun_view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, /*vec3(0.0)*/k_d, k_s, alpha, f_norm, 1.0, emitted_light, reflected_light); + max_light += get_sun_diffuse2(sun_info, moon_info, f_norm, /*time_of_day.x*//*-cam_to_frag*/sun_view_dir/*view_dir*/, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, /*vec3(0.0)*/k_d, 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-frag/shiny.glsl b/assets/voxygen/shaders/fluid-frag/shiny.glsl index 2b6e436b5a..56958ce57d 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) { +void wave_dx(vec2 pos, vec2 dir, float speed, float frequency, float factor, vec4 accumx, vec4 accumy, out vec4 wave, out vec4 dx) { + vec2 v = floor(f_vel); + float ff = frequency * factor; 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; + tick_loop(2.0 * PI, speed - ff * (dir.x * v.x + dir.y * v.y), frequency * (dir.x * (factor * pos.x + accumx.x) + dir.y * (factor * pos.y + accumy.x))), + tick_loop(2.0 * PI, speed - ff * (dir.x * (v.x + 1.0) + dir.y * v.y), frequency * (dir.x * (factor * pos.x + accumx.y) + dir.y * (factor * pos.y + accumy.y))), + tick_loop(2.0 * PI, speed - ff * (dir.x * v.x + dir.y * (v.y + 1.0)), frequency * (dir.x * (factor * pos.x + accumx.z) + dir.y * (factor * pos.y + accumy.z))), + tick_loop(2.0 * PI, speed - ff * (dir.x * (v.x + 1.0) + dir.y * (v.y + 1.0)), frequency * (dir.x * (factor * pos.x + accumx.w) + dir.y * (factor * pos.y + accumy.w))) + ); + 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; + 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; + 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)), 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/globals.glsl b/assets/voxygen/shaders/include/globals.glsl index 0012dab2ca..a77f6658a9 100644 --- a/assets/voxygen/shaders/include/globals.glsl +++ b/assets/voxygen/shaders/include/globals.glsl @@ -39,4 +39,24 @@ mat4 threshold_matrix = mat4( float distance_divider = 2; float shadow_dithering = 0.5; +float tick_loop_time = 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_loop_time * 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); +} + +// Only works if t happened within tick_loop_time +float time_since(float t) { + return tick.x > t ? (tick_loop_time - t + tick.x) : (tick.x - t); +} + #endif 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 a5c871b171..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); @@ -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); diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 6352fde4b9..d08e7dd0d2 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -20,7 +20,7 @@ layout(location = 0) in vec3 v_pos; // in uint v_col; layout(location = 1) in uint v_norm_ao; -layout(location = 2) in float inst_time; +layout(location = 2) in vec3 inst_time; layout(location = 3) in float inst_lifespan; layout(location = 4) in float inst_entropy; layout(location = 5) in int inst_mode; @@ -94,7 +94,13 @@ struct Attr { mat4 rot; }; -float lifetime = tick.x - inst_time; +float lifetime = max((tick.y - inst_time.y - 1.0), 0.0) * tick_loop_time + (tick.y > inst_time.y ? (tick_loop_time - inst_time.x + tick.x) : (tick.x - inst_time.x)); + +float loop_inst_time(float period) { + float rest = mod(tick_loop_time, period) * inst_time.y; + + return mod(rest + inst_time.x, period); +} vec3 linear_motion(vec3 init_offs, vec3 vel) { return init_offs + vel * lifetime; @@ -419,14 +425,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(tick_loop(2 * PI, 4, lifetime * 4)) - min(max(green_col - 1, 0), 0.3); + float red_col = 1.15 + 0.1 * sin(tick_loop(2 * PI, 3, lifetime * 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(PI * 2.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 74f88d91e6..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 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 1e38de4a6d..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); 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 21a482e56b..22fb7e3464 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -376,6 +376,7 @@ impl Client { let ServerInit::GameSync { entity_package, time_of_day, + true_time, max_group_size, client_timeout, world_map, @@ -414,6 +415,7 @@ impl Client { state.ecs_mut().register::>(); let entity = state.ecs_mut().apply_entity_package(entity_package); *state.ecs_mut().write_resource() = time_of_day; + *state.ecs_mut().write_resource() = true_time; *state.ecs_mut().write_resource() = PlayerEntity(Some(entity)); state.ecs_mut().insert(material_stats); state.ecs_mut().insert(ability_map); @@ -2276,12 +2278,13 @@ impl Client { self.target_time_of_day = Some(time_of_day); *self.state.ecs_mut().write_resource() = calendar; *self.state.ecs_mut().write_resource() = new_true_time; + *self.state.ecs_mut().write_resource() = time_scale; let mut time = self.state.ecs_mut().write_resource::