|
@@ -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).
|