Covering the week of May 25th – 29th, 2020.
Hello and welcome to our 21st weekly development update of the FLIP Fluids addon for Blender! Last week was great for development progress of our upcoming force fields feature set. Last week’s work mainly involved finishing up our surface force field mode as well as starting work on our volume force field mode, and that is what I’ll cover in this post.
Volume Force Fields
Our volume force field mode is quite similar to the surface force field mode discussed in the last few development updates. Surface forces attract fluid to the surface of an object- it creates a shell of fluid around the object. Volume forces attract fluid into the interior of an object’s volume. Here is a simple test using Blender’s Suzanne Monkey model:
If you are familiar with Blender’s older Elbeem liquid simulator, our volume force mode is similar to the Fluid Control object type. We are basing our implementation of this force mode after Houdini’s Suction Fluid tool.
I started running this simulation as a test before finishing work for the weekend, and I did not expect this to turn out as well as it did! In this animation, a volume force field is used on an animated character from Mixamo:
This test at a low resolution of 150 to make sure animated volume force fields would work correctly, and it seemed it did!
A few modifications were made to the setup and the resolution was cranked up to 450 before I let the simulation run over the weekend. Here is an OpenGL scene view of the simulation:
For this week, I will be finishing up the volume force field mode, and if I’m as productive as last week, I’m hoping I’ll be able to start on adding another mode. There are a few features left to do on this mode as well as some simple bug fixes:
- Anti-gravity – A useful feature for volume forces is to be able to alter the gravity strength/direction within the interior of the object. For example, it may be desirable to have no gravity (or low gravity) inside of the object, which could help with filling up the volume more evenly.
- Optimization Bug – Before running these tests, I noticed there was a bug that prevented using some force field optimizations that would help speed up the simulation.
- Stability Bug – Something is causing volume forces to become unstable in rare cases. I have found that the instability is related to nonsense data in the force field calculations. Before running animation tests, I quickly added a workaround for this by detecting and replacing bad data, but it will be better to find the root cause and fix this bug properly. The good news is that this fix should be simple since I have a .blend file that can consistently and quickly reproduce the bug.
Stabilizing Surface Force Fields
In last week’s development notes I had mentioned that there was a stability issue where surface force fields could become unstable if they were animated. My hypothesis was that the force field data was changing too abruptly and more substeps would be needed to keep the simulation stable. After testing this last week, it turns out I was quite wrong!
It turns out the stability issue was caused by a divide-by-zero bug, and it was an easy fix of adding a few checks to prevent the simulator from dividing by zero and generating bad data.
Although the fix was easy, this was a frustrating bug to find the root of the problem. This was a rare bug to reproduce and I started noticing a weird pattern in my tests. In all three of my scene setups that could reproduce this issue, a common pattern was that the bug would only occur if the animation keyframes were set to bezier and would not occur if set to linear. This made me assume that the bug was related to how meshes are interpolated within the simulator, which was wrong. It turns out this pattern was a complete coincidence and it led me to initially look into an unrelated area of the simulator during debugging, and that wasted quite a bit of time!
More Development Notes
- Added functionality to re-compute force fields on substeps between frames – Originally, force fields were only recomputed at the start of a frame, and not on substeps. This will be needed to compute accurate motion for fast moving force fields. TODO: it would be good to have an option to only re-compute force fields at the start of a frame. For slower moving force fields, re-computing on substeps would add extra simulation time and be overkill. Perhaps this could be automatic and made adaptive?
- Added UI setting to limit maximum strength of a force field – For usability, it is important that we add a limit to the maximum strength of a force field. Depending of the force field falloff, the evaluated force strength can be inversely proportional to distance (1 / distance^falloff). In fluid simulation, the particles can become very close to the force field origin and can take on near infinite force field values that can cause the simulation to become unstable. To make our force field system easier to use, force fields will have a Maximum Force Factor value. This value will limit the maximum force field strength to the max_force_factor * base_strength. The default value is currently set at 3.0. For example, if your force field base strength is set to 9.81 (default strength of gravity), the maximum force field strength will be capped at 3.0 * 9.81 = 29.43.
- Bug Fix: Estimated Surface Tension Substeps value would not update after a frame change (issue #497) – This info UI element displays the estimated number of substeps that the simulator will compute depending on amount of surface tension, surface tension accuracy, physical domain scale, and framerate. It was reported to us that the value would not be updated on a frame change when the simulation time scale (speed) was animated.
- Possible workaround for rendering OpenGL debug visualizations – A common request we receive is to be able to render the OpenGL particle debugging visualization into an animation. I asked in this Twitter thread if this was possible, and received some very helpful info. Unfortunately, it looks like it is not possible to render custom OpenGL drawing in regular Blender rendering, but there is a workaround where we can do this by scripting a special render operator.