You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Ticking "Emitting" On in a GPUParticles3D when One Shot is active with Explosiveness 1 will not always loop despite all Particles having already despawned.
#83909
Closed
ArkyonVeil opened this issue
Oct 24, 2023
· 3 comments
Seems like there is a problem when using oneshot particle spawning and looping the emission when mixed with high Explosiveness values.
I'd expect that since it's a oneshot particle emitter, whenever every particle's lifetime reaches 0, activating emission again would loop it. This works perfectly when Explosiveness is 0.
When explosiveness is higher, as more easily seen in explosiveness 1. Ticking emission once all particles have vanished will not cause it to loop reliably. At a glance it appears that it still requires the same amount of time to pass that every particle with explosiveness 0 took for their lifetime to reach 0.
In other words...
If explosiveness is 1 and lifetime 1. The system should reset after 1 second passed.
Instead, it actually takes at least 2 seconds. 1 for the time every particle needs to spawn as if it were in Explosiveness 0 + their lifetime.
In turn, when making animations this can cause loops to not function reliably. Requiring the animation loop to be much larger so when looping, it can cover the emission's expected full cycle duration at explosiveness 0.
Note: Also tested in Godot 4.2 Beta 2/3, bug still occurs.
Steps to reproduce
Create a GPUParticles3D,
Setup with bare minimum to render. (IE DrawPass Mesh, ParticleProcessMaterial)
Tick One Shot
Slide Explosiveness to 1,
Tick emitting on,
Wait a second for the particles to disappear, and then try ticking back on again the moment every particle has despawned. Notice how even though all particles vanished, the spawner will not restart.
Minimal reproduction project
N/A
The text was updated successfully, but these errors were encountered:
Remember that you can use manual particle emission in 4.x using a custom shader. 4.2.beta2 also has an Amount Ratio property in ParticleProcessMaterial to adjust the number of particles emitted without restarting the particle system.
Remember that you can use manual particle emission in 4.x using a custom shader. 4.2.beta2 also has an Amount Ratio property in ParticleProcessMaterial to adjust the number of particles emitted without restarting the particle system.
Not sure if related. Anyhow, I seem to have gotten the issue fixed by modifying the gpu_particles_3d.cpp file.
On the following method, triggering a restart of the particles will cause switching on emission in a one shot to work as expected.
void GPUParticles3D::set_emitting(bool p_emitting) {
// Do not return even if `p_emitting == emitting` because `emitting` is just an approximation.
if (p_emitting && one_shot) {
if (!active && !emitting) {
// Last cycle ended.
active = true;
time = 0;
signal_canceled = false;
emission_time = lifetime;
active_time = lifetime * (2 - explosiveness_ratio);
----> RenderingServer::get_singleton()->particles_restart(particles);
} else {
signal_canceled = true;
}
set_process_internal(true);
} else if (!p_emitting) {
if (one_shot) {
{
set_process_internal(true);
}
} else {
set_process_internal(false);
}
} else {
set_process_internal(true);
}
emitting = p_emitting;
RS::get_singleton()->particles_set_emitting(particles, p_emitting);
}
Potential fix? Or is there a better way?
Edit: Also just tried mixing animation with this fix. If the animation matches the lifetime exactly, it loops roughly 50% of the time, though a 0.05s increase will already increase the chance of a successful loop to near 100% (Depending if there's frame drops or not) which will make working with VFX more fluent. A better fix for this workflow should have the Animator trigger the restart manually, but that is in one's opinion best reserved for a proper VFX focused overhaul.
Closing in favor of godotengine/godot-proposals#7322, as this is ultimately the same problem that you're trying to address here. Feel free to post your findings in a comment though 🙂
Godot version
v4.1.1.stable.mono.official [bd6af8e]
System information
Godot v4.1.1.stable.mono - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3090 (NVIDIA; 31.0.15.3161) - Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz (8 Threads)
Issue description
Simple Example:
https://github.com/godotengine/godot/assets/42283444/830b0fb3-eba1-4c9c-819c-ee792563591e
Seems like there is a problem when using oneshot particle spawning and looping the emission when mixed with high Explosiveness values.
I'd expect that since it's a oneshot particle emitter, whenever every particle's lifetime reaches 0, activating emission again would loop it. This works perfectly when Explosiveness is 0.
When explosiveness is higher, as more easily seen in explosiveness 1. Ticking emission once all particles have vanished will not cause it to loop reliably. At a glance it appears that it still requires the same amount of time to pass that every particle with explosiveness 0 took for their lifetime to reach 0.
In other words...
In turn, when making animations this can cause loops to not function reliably. Requiring the animation loop to be much larger so when looping, it can cover the emission's expected full cycle duration at explosiveness 0.
Workflow with Animation loop showcasing the bug:
https://github.com/godotengine/godot/assets/42283444/9e82095c-e246-43d2-ba84-1d96901e46fb
Note: Also tested in Godot 4.2 Beta 2/3, bug still occurs.
Steps to reproduce
Minimal reproduction project
N/A
The text was updated successfully, but these errors were encountered: