Weekly Development Notes #50 – Collision Handling Improvements

Covering the week of March 1st – 5th, 2021.

Welcome to our 50th development update for the FLIP Fluids liquid simulation addon for Blender! Last week’s development mainly involved fixing a few bugs and adding a few small improvements. A nice improvement is that we were able to find a fix for a simulation stability bug that could cause simulations to ‘explode’ in certain conditions, and that is what will be covered in this post.

Melting Gold

A cool new test from Dennis! In this animation, the Blender 2.79 Fracture Modifier build was used to fracture the sphere along a path, letting molten gold to flow out. All materials were from the Extreme PBR Evo addon.

Fixing a Collision Handling Bug

This section will detail an important fix for a bug that could cause particles to become stuck on sharp edges of an obstacle, and in some cases would cause an unstable simulation.

Bug Report #1

In December 2020, PavelBlend reported an issue where fluid particles would become stuck to the borders of an obstacle (See issue #508). From the fluid particle debugging tool, it can be seen that the particles in red color have quite a high velocity even though they are not moving:

Particles stuck to obstacle edges

The reason for the high velocity particles is a side effect of how the FLIP method works where stuck particles can gain velocity and accelerate from the surrounding particles that are moving. If you set the PIC/FLIP ratio to 1.0 to make a completely PIC simulation, they wont have as high velocity but they will still stick.

Bug Report #2

Last week PavelBlend reported that a simulation becoming unstable and exploding. On the left is the unstable simulation, on the right is the simulation after fixing this bug:

After checking out the simulation, it looks like this instability was a side effect of the particles becoming stuck and gaining a high amount of velocity. In this image, the yellow highlighted particles show which particles are stuck while having a high velocity:

Particles stuck to obstacle edges

In the simulation, the stuck particles would continue to gain higher and higher velocities. Eventually a single particle would shift and become loose. Due to the particle’s extreme velocity, it would affect surrounding particles and create a chain reaction that would cause the entire simulation to explode.

There is an option that is enabled by default to automatically detect and remove particles with extreme velocities that would prevent this situation. However, this is not a good workaround for this bug. Due to the large number of particles that could become unstable, it would be better to fix the underlying problem that is causing particles to become stuck in the first place rather than using a workaround.

This bug was marked as a high priority to fix due to the potential problems this could cause in other situations.

Solving and fixing the issue

My guess was that the area of code that handles collision detection and collision response would be the cause of this bug.

Collision Detection and Response

Ideally, in a perfect simulation, the solver would never allow particles to flow into an obstacle and collisions would never happen. But due to limits in simulation resolution and numerical error, collision are inevitable and need to be handled.

In short, here is how the simulator handles fluid particle collisions:

  • Obstacles are converted to volumetric data as a signed distance field (SDF). Collision detection is much quicker to compute with a SDF than a triangle mesh. SDFs are also already computed and used in many other areas of the simulator.
  • If a particle is close to an obstacle’s surface, a collision check is run:
    • A particle’s path with be incrementally traced from it’s start location to it’s end location. If at any point this path intersects the obstacle’s volume, a collision will be detected and then handled.
    • If a collision is detected, the simulator will attempt to use the SDF data to project the particle to the closest location that is outside of the obstacle. If the simulator is unable to find a suitable location, such as if the projected position ends up inside another area of the obstacle or inside another obstacle, the collision response will have failed and will be handled by reverting the particle back to it’s starting location.

Detecting Stuck Particles

The way I usually start with bugs related to particle behavior is to detect the problem particles, isolate them into a smaller group and output what those particles are doing in the code to find a pattern.

In this bug fix, I started with detecting which particles have become stuck. I considered a particle that remained in a position close to it’s starting position and also that has also failed it’s last two collision responses to be ‘stuck’. This text output prints the number of stuck particles frame by frame:

2, 4, 5, 7, 10, 16, 19, 26, 32, 37, 44, 52, 57, 68, 81, 97, 109, 121, 131, 152, 170, 12, 12, 37, 41, 106, 108, 138, 150, 179, 196, 212, 229, 244, 265, 281, 298, 324, 378, 405, 422, 442, 466, 504, 535, 561, 583, 643, 8, 8, 632, 24, 24, 631, 188, 195, 575, 431, 446, 565, 557, 574, 605, 622, 646, 669, 682, 704, 729, 748, 771, 794, 66, 66, 702, 723, 741, 764, 784, 811, 793, 817, 864, 888, 368, 375, 760, 782, 593, 608, 740, 769, 741, 760, 788, 808, 822, 842, 863, 878, 892, 909, 935, 956, 970, 997, 1016, 1041, 1047, 1062, 1089, 1105, 1102, 1119, 1152, 1169, 1158, 1172, 1191, 1209, 1214, 1229, 1263, 1285, 1253, 1273, 1316, 1340, 1242, 1253, 1336, 1355, 973, 987, 1212, 1230, 1178, 1186, 1238, 1249, 1245, 1260, 1284, 1300, 1318, 1338, 1346, 1357, 1360, 1409, 1416, 1423, 1429, 1426, 1421, 1458, 1468, 1482, 1502, 1523, 1527, 1567, 1582, 1590,

The number of particles peaks at about 1600 before becoming unstable. There are about 160,000 particles in this simulation and having 1% of them becoming stuck is not good at all.

Why are particles becoming stuck?

Visualizing the obstacle’s SDF using the obstacle debugging tool shows jagged artefacts at the obstacle’s edges:

Obstacle to SDF

These jagged artefacts are due to the SDF data being aligned to a 3D grid of voxels. Since the obstacle is at a slight angle and the simulation is relatively low, these artefacts are quite noticeable in the underlying simulation. Particles are becoming stuck near these artefact locations:

Obstacle to SDF

The SDF data near these sharp jagged edges is not very good or consistent, and this affects how particles are projected outside of the obstacle in a collision response. The collision response is failing in part due to artefacts in the SDF data.

Improvement #1: More accurate collision detection

After looking at the SDF data, I found that the accuracy decreases as the particle penetrates deeper into the obstacle’s volume. But the SDF data very close to the surface of the obstacle is much better. The fix for this is to detect the collision point closer to the surface before the particle becomes too embedded inside of the obstacle.

This can be improved by decreasing the incremental distance that a particle is traced in a collision detection. Before this change, a particle was stepped in increments of 0.5 voxels. Changing this to 0.1 voxels makes it so that the collision is detected at most 0.1 voxels deep into the obstacle. Here are the stuck particle counts after this change:

1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 5, 5, 6, 6, 6, 8, 9, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 8, 9, 10, 14, 17, 19, 22, 24, 26, 30, 36, 37, 38, 40, 42, 45, 46, 47, 48, 47, 49, 50, 53, 54, 56, 56, 60, 62, 64, 66, 67, 71, 72, 73, 75, 76, 81, 81, 81, 81, 84, 0, 0, 24, 66, 69, 71, 72, 72, 72, 75, 77, 79, 83, 86, 87, 88, 93, 95, 99, 103, 104, 105, 107, 107, 108, 110, 111, 114, 116, 119, 116, 116, 118, 120, 121, 121, 121, 121, 121, 123, 126, 124, 127, 127, 125, 125, 124, 121, 121, 123, 123, 123, 126, 126, 125, 128, 128, 128, 129, 131, 131, 132, 131, 132, 133, 133, 133, 135, 136, 135, 135, 135, 134, 135, 135, 134, 135, 135, 136, 136, 136, 136, 136, 136, 136, 136, 136, 137, 137, 138, 138, 138, 138, 139, 140, 140, 140, 141, 142, 144, 141, 142, 143, 146, 147, 148, 142, 143, 142, 143, 142, 143, 141, 141, 140, 140, 137, 137, 126, 126, 127, 130, 128, 129, 129, 129, 113, 113, 113, 116, 117, 118,

The counts are much lower after this change! But still not great. The step distance could be changed to 0.01 or 0.001 for a better result, but the returns are diminishing and has a larger performance impact.

It looks like particles are not becoming stuck permanently, and this is preventing the simulation from becoming unstable. So that’s a good start.

Improvement #2: Randomizing starting position

In addition to the first improvement, I tested randomizing the starting position of the collision test for particles that continue to be stuck. Remember: in the case that a collision response fails, the particle reverts back to it’s original location before the collision. By adding a very small randomness to the starting position, it seems that this helps prevent particles from trying to solve and fail at the same collision check over and over again.

Here are the stuck particle accounts with improvements 1 and 2 applied:

1, 1, 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 11, 14, 17, 19, 19, 21, 22, 27, 28, 3, 4, 6, 9, 9, 14, 16, 20, 20, 23, 25, 25, 29, 30, 31, 34, 37, 40, 38, 43, 42, 43, 44, 46, 49, 50, 51, 53, 53, 55, 52, 54, 41, 42, 0, 0, 0, 0, 14, 20, 11, 10, 10, 13, 13, 14, 15, 17, 17, 18, 19, 22, 24, 25, 28, 29, 29, 32, 17, 19, 23, 24, 0, 0, 1, 2, 3, 4, 4, 5, 5, 7, 9, 15, 13, 13, 3, 3, 5, 6, 7, 10, 13, 15, 18, 19, 23, 24, 27, 29, 30, 32, 32, 36, 38, 40, 41, 43, 44, 45, 47, 46, 45, 46, 49, 49, 0, 0, 3, 25, 0, 0, 2, 8, 0, 0, 0, 0, 0, 0, 1, 6, 9, 12, 13, 14, 17, 20, 21, 23, 22, 24, 25, 26, 28, 30, 25, 27, 0, 0, 0, 8, 8, 10, 11, 13, 14, 15, 16, 18, 22, 24, 25, 26, 28, 31, 31, 33, 34, 0, 0, 0, 2, 2, 2, 2,

Better, but can still be improved!

Improvement #3: Resetting particle velocity

As a last resort, in the case that the particles are still stuck, they will have their velocities manually reset to a velocity based on nearby stable particles. This will be like the stuck particles being simulated with 100% PIC velocity for a frame while disregarding FLIP velocity. I usually like to leave velocity handling completely to the solver, but in this case I think it is acceptable to modify the small number of particles.

After this change, there are 0 particles that are stuck for more than one frame in a row. In these following counts, these are the number of particles that become stuck for a single frame rather than two frames:

1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 4, 5, 5, 7, 8, 10, 10, 13, 14, 13, 12, 10, 9, 10, 10, 8, 6, 6, 7, 6, 6, 5, 4, 4, 3, 3, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 6, 6, 5, 5, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 3, 3,

Those are nice low numbers for how many particles are failing their collision responses! The changes to the code are very small, but we will still keep an eye on fluid-obstacle collision and interaction to make sure there are no bad side-effects.

Force Field Experimental Version 9.0.9.16

Want to try out these updates? They can be tested in our Force Field Experimental Builds Package in the latest version!

Release Notes v9.0.9.16 (10-MAR-2021)

  • This version adds a few bug fixes and improvements.
  • Bug Fix: Fixed an issue where many particles could become stuck to sharp obstacle edges which could lead to an unstable simulation (issue #508).
  • Bug Fix: Potential fix for render crashes when the Fluid Particle Debugging or Force Field Debugging tools are enabled (issue #521).
  • Bug Fix: Fixed error messages in Blender 2.79 due to difference in icon names in Blender 2.8+.
  • Bug Fix: Fixed issue in Blender 2.91+ where rendering fluid meshes with motion blur enabled could result in longer Cycles render times.
    • Note: Motion Blur Rendering of fluid surfaces or whitewater particles is not currently supported (See: Motion Blur Support).
    • This fix will only apply to newly created scenes. To workaround this issue in an existing scene, select a fluid/whitewater object and disable the Object Properties > Motion Blur option (only applies if Cycles is the selected renderer).
  • Added a UI warning and tooltip if the Estimated Surface Tension Substeps info value exceeds the allowed Max Frame Substeps Value (Documentation).
  • Added viewport visibility toggles to the fluid particle, force field, and obstacle debug tools.