diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp index 73d7e340d2a..599412c5b2d 100644 --- a/drivers/gles3/storage/particles_storage.cpp +++ b/drivers/gles3/storage/particles_storage.cpp @@ -513,7 +513,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - double new_phase = Math::fmod(p_particles->phase + (p_delta / p_particles->lifetime) * p_particles->speed_scale, 1.0); + double new_phase = Math::fmod(p_particles->phase + (p_delta / p_particles->lifetime), 1.0); //update current frame ParticlesFrameParams frame_params; @@ -534,7 +534,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta p_particles->phase = new_phase; frame_params.time = RSG::rasterizer->get_total_time(); - frame_params.delta = p_delta * p_particles->speed_scale; + frame_params.delta = p_delta; frame_params.random_seed = p_particles->random_seed; frame_params.explosiveness = p_particles->explosiveness; frame_params.randomness = p_particles->randomness; @@ -1097,8 +1097,6 @@ void ParticlesStorage::update_particles() { fixed_fps = particles->fixed_fps; } - bool zero_time_scale = Engine::get_singleton()->get_time_scale() <= 0.0; - if (particles->clear && particles->pre_process_time > 0.0) { double frame_time; if (fixed_fps > 0) { @@ -1115,37 +1113,27 @@ void ParticlesStorage::update_particles() { } } + double time_scale = MAX(particles->speed_scale, 0.0); + if (fixed_fps > 0) { - double frame_time; - double decr; - if (zero_time_scale) { - frame_time = 0.0; - decr = 1.0 / fixed_fps; - } else { - frame_time = 1.0 / fixed_fps; - decr = frame_time; - } + double frame_time = 1.0 / fixed_fps; double delta = RSG::rasterizer->get_frame_delta_time(); if (delta > 0.1) { //avoid recursive stalls if fps goes below 10 delta = 0.1; } else if (delta <= 0.0) { //unlikely but.. delta = 0.001; } - double todo = particles->frame_remainder + delta; + double todo = particles->frame_remainder + delta * time_scale; while (todo >= frame_time) { _particles_process(particles, frame_time); - todo -= decr; + todo -= frame_time; } particles->frame_remainder = todo; } else { - if (zero_time_scale) { - _particles_process(particles, 0.0); - } else { - _particles_process(particles, RSG::rasterizer->get_frame_delta_time()); - } + _particles_process(particles, RSG::rasterizer->get_frame_delta_time() * time_scale); } if (particles->request_process_time > 0.0) { diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp index 2c54564ff7b..6fd5741d107 100644 --- a/scene/resources/particle_process_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -1034,7 +1034,7 @@ void ParticleProcessMaterial::_update_shader() { code += " {\n"; } code += " float vel_mag = length(VELOCITY);\n"; - code += " float vel_infl = clamp(dynamic_params.turb_influence * turbulence_influence, 0.0, 1.0);\n"; + code += " float vel_infl = clamp(dynamic_params.turb_influence * turbulence_influence, 0.0, 1.0) * (DELTA <= 0.0 ? 0.0 : 1.0);\n"; code += " VELOCITY = mix(VELOCITY, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; code += " vel_mag = length(controlled_displacement);\n"; code += " controlled_displacement = mix(controlled_displacement, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index d82ffed646a..6924f11e346 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -814,7 +814,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta p_particles->particles_material_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, particles_shader.default_shader_rd, 1); } - double new_phase = Math::fmod((double)p_particles->phase + (p_delta / p_particles->lifetime) * p_particles->speed_scale, 1.0); + double new_phase = Math::fmod((double)p_particles->phase + (p_delta / p_particles->lifetime), 1.0); //move back history (if there is any) for (uint32_t i = p_particles->frame_history.size() - 1; i > 0; i--) { @@ -839,7 +839,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta p_particles->phase = new_phase; frame_params.time = RendererCompositorRD::get_singleton()->get_total_time(); - frame_params.delta = p_delta * p_particles->speed_scale; + frame_params.delta = p_delta; frame_params.random_seed = p_particles->random_seed; frame_params.explosiveness = p_particles->explosiveness; frame_params.randomness = p_particles->randomness; @@ -1158,6 +1158,10 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta //fill the trail params for (uint32_t i = 0; i < p_particles->trail_params.size(); i++) { uint32_t src_idx = i * p_particles->frame_history.size() / p_particles->trail_params.size(); + if (p_particles->speed_scale <= 0.0) { + // Stop trails. + src_idx = 0; + } p_particles->trail_params[i] = p_particles->frame_history[src_idx]; } } else { @@ -1529,7 +1533,6 @@ void ParticlesStorage::update_particles() { } } - bool zero_time_scale = Engine::get_singleton()->get_time_scale() <= 0.0; double todo = particles->request_process_time; if (particles->clear) { todo += particles->pre_process_time; @@ -1554,37 +1557,26 @@ void ParticlesStorage::update_particles() { particles->speed_scale = tmp_scale; } + double time_scale = MAX(particles->speed_scale, 0.0); + if (fixed_fps > 0) { - double frame_time; - double decr; - if (zero_time_scale) { - frame_time = 0.0; - decr = 1.0 / fixed_fps; - } else { - frame_time = 1.0 / fixed_fps; - decr = frame_time; - } + double frame_time = 1.0 / fixed_fps; double delta = RendererCompositorRD::get_singleton()->get_frame_delta_time(); if (delta > 0.1) { //avoid recursive stalls if fps goes below 10 delta = 0.1; } else if (delta <= 0.0) { //unlikely but.. delta = 0.001; } - todo = particles->frame_remainder + delta; + todo = particles->frame_remainder + delta * time_scale; while (todo >= frame_time || particles->clear) { _particles_process(particles, frame_time); - todo -= decr; + todo -= frame_time; } particles->frame_remainder = todo; - } else { - if (zero_time_scale) { - _particles_process(particles, 0.0); - } else { - _particles_process(particles, RendererCompositorRD::get_singleton()->get_frame_delta_time()); - } + _particles_process(particles, RendererCompositorRD::get_singleton()->get_frame_delta_time() * time_scale); } // Ensure that memory is initialized (the code above should ensure that _particles_process is always called at least once upon clearing).