[FIX] Fix particle emission rate when looping#8263
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes an off-by-one error in the particle emission rate calculation that caused incorrect timing when particles loop. The bug affected the formula used to calculate when particles should respawn after their lifetime expires.
Key changes:
- Changed the particle respawn formula from
(numParticles - 1) * particleRatetonumParticles * particleRate - Updated the formula consistently across both GPU (WGSL and GLSL shaders) and CPU particle system implementations
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/scene/shader-lib/wgsl/chunks/particle/frag/particleUpdaterRespawn.js | Fixed respawn calculation for looping particles in WGSL shader |
| src/scene/shader-lib/wgsl/chunks/particle/frag/particleUpdaterNoRespawn.js | Fixed respawn calculation for non-looping particles in WGSL shader |
| src/scene/shader-lib/wgsl/chunks/particle/frag/particleOutputRgba8.js | Fixed max negative life encoding calculation in WGSL output shader |
| src/scene/shader-lib/wgsl/chunks/particle/frag/particleInputRgba8.js | Fixed max negative life decoding calculation in WGSL input shader |
| src/scene/shader-lib/glsl/chunks/particle/frag/particleUpdaterRespawn.js | Fixed respawn calculation for looping particles in GLSL shader |
| src/scene/shader-lib/glsl/chunks/particle/frag/particleUpdaterNoRespawn.js | Fixed respawn calculation for non-looping particles in GLSL shader |
| src/scene/shader-lib/glsl/chunks/particle/frag/particleOutputRgba8.js | Fixed max negative life encoding calculation in GLSL output shader |
| src/scene/shader-lib/glsl/chunks/particle/frag/particleInputRgba8.js | Fixed max negative life decoding calculation in GLSL input shader |
| src/scene/particle-system/cpu-updater.js | Fixed respawn calculation in CPU-based particle updater implementation |
The fix is mathematically correct and has been applied consistently across all affected files. With N particles emitted at rate R, the total emission cycle time is indeed N × R, not (N - 1) × R. This ensures proper timing between particle respawns, especially noticeable in the edge case of a single particle with a long emission rate.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Fixes an off-by-one error in the particle respawn calculation that caused incorrect emission timing when particles loop.
When a particle's life exceeds its lifetime, the system "rewinds" the particle by subtracting a value to simulate the wait until its next emission slot. The formula was:
This is incorrect. With N particles and rate R, the total cycle time should be
N * R, not(N - 1) * R.Example
Configuration: 1 particle, 1s lifetime, 5s emission rate
max(1, (1-1) * 5) = 1→ particle respawns immediately after dyingmax(1, 1 * 5) = 5→ particle waits 4 seconds before respawning (correct behavior)Fixes #4929
Checklist