godotengine / godotengine/godot
GPUparticle rigidbody collision snap delay
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
-Reproducible in 4.2.1 and 4.3 and possibly earlier versions
### System information
Godot v4.2.1.stable - Windows 10.0.22631 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3050 Laptop GPU (NVIDIA; 31.0.15.4633) - 11th Gen Intel(R) Core(TM) i5-11300H @ 3.10GHz (8 Threads)
### Issue description
GPUparticle node seems to have what looks like an incorrect order of code execution when it comes to simulating collision.
**The undesired behavior and potential cause**
The particles upon reaching their heightmap collision instead of snapping instantly to that collision position penetrate through the surface as if nothing was there for one more frame before finally snapping onto collision. The issue is more visible at greater velocities further, but the delay is always one frame, indicating that the GPUparticles likely move the particle after checking for collision, which produces a result of a particle moving into it's next position and rendering before it checks if it can move into that next position, only to check that it shouldn't have moved into that position in the next frame.
**Importance of the issue**
This issue is extremely important for anyone who wants to use GPUparticle's collisions as this can produce some really undesirable results ranging from singular frames where the particles disappear (due to moving below the surface they hit) to making a proper rain collision impossible without needing to convert the particle material into a shader and having to compensate for the offset in code, not to mention how the issue is downright unfixable if you're using varied velocity.
**Solution?**
Fixing the code that processes physics for GPUparticles, seeing as it is an issue with the engine's core functionality.
https://github.com/godotengine/godot/assets/100485785/4eac7740-bb99-41e6-b853-7b1a190f85df
### Steps to reproduce
1. Create a MeshInstance, give it a mesh (preferably something flat to better see the issue, it's present with any shape)
2. Add a GPUParticles3D node
3. In GPUParticles3D :
- add a Draw Pass mesh of any kind (preferably a sphere)
- assign a ParticleProcessMaterial to GPUParticles3D and set Collision -> Mode to Rigid
- move the whole GPUParticles3D node a little bit up (to have some space between the Meshinstance below and the emitter)
4. Add a GPUPariclesCollisionHeightField3D and change it's size property to 12m in every axis (at this point you can already notice the problem)
5. Go to GPUParticles -> Process Material -> Spawn -> Velocity, change the Direction from (1,0,0) to (0,-1,0) and set Spread to 0
6. Then test these values :
Initial_Velocity_Min = 30
Initial_Velocity_Max = 30
Initial_Velocity_Min = 90
Initial_Velocity_Max = 90
Initial_Velocity_Min = 12
Initial_Velocity_Max = 12
Initial_Velocity_Min = 24
Initial_Velocity_Max = 24
Once you've tested each setting you will notice that the scale of the issue directly correlates to velocity.
### Minimal reproduction project (MRP)
The issue is too basic and fundamental for an MRP to be needed
Contributor guide
Assessment
This issue has not been assessed yet.