CS 184 Final Project Milestone - FLIPing Fluids
Team Members
Tianchen Liu 3034681144 @tc-liu
Riley Peterlinz 3036754368 @cardiacmangoes
Anders Museth 3034688788 @AndersMuseth
Rhea Senthil Kumar 3034746976 @rheask8246
Abstract
In this project we implemented a 3D FLIP (FLuid Implicit Particle) fluid solver, and rendered the fluid solver using textures made in Blender.
We first implemented a 2D fluid solver using Smoothed-particle hydrodynamics (SPH), then implemented a 3D fluid solver using both Particle-In-Cell (PIC) method and FLIP (FLuid Implicit Particle) method - an upgrade of the PIC method - of particle simulation.
We then import the physical simulation into blender and render the physical simulation with real-life like texture.
Technical Approach
2D SPH Solver
As a warmup to making a 3D solver, we first made a 2D Smoothed-particle hydrodynamics (SPH) solver. SPH is 1) a Lagrangian method and 2) it’s meshfree.
Although it didn’t directly contribute to our ultimate final product - the FLIP fluid simulation, it was a great stepping stone for us to know and learn how a fluid solvers are built.
3D Fluid Solvers
For 3D particle simulation, we first use the Particle-In-Cell (PIC) method, then we upgrade it to FLIP method.
Particle-In-Cell (PIC)
Overview
The key of the Particle-In-Cell method is that instead of keeping track of the velocity and position of each particle in each timestep, we “export” all velocities of particles in a cell to the cell, then we interpolate new particle velocities and positions from the exported “grid velocities”. We then do some additional bookkeeping to make sure the simulation is a more accurate discription of real world although we’re using this technique.
Simulating Particles
To simulate the particules, we use semi-implicit Euler method taught in lecture, which is a more stable upgrade of the Euler method.
Velocity Transfers
For ease of explanation, we use 2D to explain how velocities transfer work. We then generalize this to 3D in our implementation of PIC and FLIP. Here’s a picture demonstrating the ideas of PIC/FLIP in a 3D staggered grid.
Velocity Transfers: Particle to Grid
Velocity transfers is the key part and backbone of the Particle-In-Cell method. A velocity of a particle is “spread” to the four nearest grids, with a closer one “having a larger share” of that particle’s velocity. Do that for every particle and each grid has an “average” of the particles’ velocities in the four adjacent grids, while each grid velocity possessing more of the velocities of particles near that grid.
Forcing Incompressibility
There is a problem that arrives if all we do is the step above. Using just these calculations, a cell could have a net positive or net negative of outflow of particles. This could never happen in real life so we correct it by calculating the net outflow (divergence) and spread it four ways in each side of the cell thereby making the divergence zero in a cell.
Velocity Transfers: Grid to Particle
After each grid velocity is calculated, we then calculate new velocities and positions of particle by doing a similar procedure: each particle takes the grid velocities of the four nearest grids and computes a weighted average of the four velocities, with a nearer grid having a larger weight.
Problems Encounterd
There is a problem in the PIC method that a majority of individual velocities in the same cell are lost (see picture below) because of the velocity transfers - each velocities are transferred first to the grid velocities then transferred back to each individual particles, hence we may see a problem like the below picture occurring.
To fix this, we use the FLIP method.
FLIP (FLuid Implicit Particle)
The key idea of the FLIP upgrade from the PIC method is: we still want to scale up our abilities to process particules using velocity transfers, but we keep the “individuality” of velocities intact by adding the “difference” of the grid velocities to each particle after a velocity transfer.
In other words, as we notice the key step in changing the velocity in each timestep happens in making the grid velocities incompressible - we add the difference of grid velocities caused in this timestep to all particles in the grid. In this way, the “individuality” of velocities are preserved!
Rendering in Blender
We iterated through 3 different methods to generate meshes, each mesh we create would eventually make it to blender where we use a refractive shader and a HDRI of a sunset in venice.
1. Marching Squares
Given particles in a scene and make a level set grid from these particles
We perform marching cubes (source) on a discritized grid to generate the mesh and store it as a .obj which we then export to blender.
We decided to forgoe this method as it was too slow for large numbers of particles.
For rendering in blender we exported simulation’s positions of particles at each time step into a [num_steps, num_particles, 3]
dimensional vector. For each time step, we placed the particles according to the simulation’s output. This was automated using scripting in blender and the bpy
blender-python package. We then attach a metaball to each particle.
This method gives good results, but the fluid ends up looking more like orbeez than water.
To solve the orbeez look, we used OpenVDB to create a series of .obj
meshes from our sparse points. We then took the .obj files and using the power of the Stop-motion-OBJ blender add-on we created an animation of meshes. These results turned out to be much smoother than the metaballs.
Lessons Learned
- How to utilize blender scripting for automation
- 3D visualization and animation in Python (Matplotlib)
- Simulation to image rendering pipeline
- Creating simulations in Blender
Results
Final Project Video
Openvdb Mesh
FLIP
PIC
FLIP
2D SPH Simulation
Drive Link
References
Contributions from each team member
Tianchen Liu:
Wrote technical explanation on our approach of how SPH, PIC, and FLIP is implemented in the writeup & slide decks + contributed to other parts in the writeup + slide decks (background, abstract, etc.).
Riley Peterlinz:
Blender rendering pipeline. Coded a marching squares solver, then a blender script for metaballs, finally converting results from OpenVDB to blender results. Created materials for fluids and created environment in blender for renders.
Anders Museth:
Developed the entire 3D fluid solver based on the FLIP and PIC algorithms. Specifically, this included the Grid-to-Particle and Particle-to-Grid conversion, enforced zero-divergence of the fluid velocities on a staggered MAC grid, drift and density management, particle separation, boundary collision, and particle advection functions. Additionally, implemented a 2D SPH solver based on a tutorial, as well as various utility functions for both FLIP and structural components. Used OpenVdb to generate surface meshs for our final render.
Rhea Senthil Kumar:
Developed the Python simulation pipeline. Created 3D PIC and FLIP Renders in Python. Coded 3D Matplotlib Renders. Voiced the final video and created presentation slides.
Slides
Slide Deck for FLIPing Fluids
Code
Fluid-Sim Github
CS 184 Final Project Milestone - FLIPing Fluids
Team Members
Tianchen Liu 3034681144 @tc-liu
Riley Peterlinz 3036754368 @cardiacmangoes
Anders Museth 3034688788 @AndersMuseth
Rhea Senthil Kumar 3034746976 @rheask8246
Abstract
In this project we implemented a 3D FLIP (FLuid Implicit Particle) fluid solver, and rendered the fluid solver using textures made in Blender.
We first implemented a 2D fluid solver using Smoothed-particle hydrodynamics (SPH), then implemented a 3D fluid solver using both Particle-In-Cell (PIC) method and FLIP (FLuid Implicit Particle) method - an upgrade of the PIC method - of particle simulation.
We then import the physical simulation into blender and render the physical simulation with real-life like texture.
Technical Approach
2D SPH Solver
As a warmup to making a 3D solver, we first made a 2D Smoothed-particle hydrodynamics (SPH) solver. SPH is 1) a Lagrangian method and 2) it’s meshfree.
Although it didn’t directly contribute to our ultimate final product - the FLIP fluid simulation, it was a great stepping stone for us to know and learn how a fluid solvers are built.
3D Fluid Solvers
For 3D particle simulation, we first use the Particle-In-Cell (PIC) method, then we upgrade it to FLIP method.
Particle-In-Cell (PIC)
Overview
The key of the Particle-In-Cell method is that instead of keeping track of the velocity and position of each particle in each timestep, we “export” all velocities of particles in a cell to the cell, then we interpolate new particle velocities and positions from the exported “grid velocities”. We then do some additional bookkeeping to make sure the simulation is a more accurate discription of real world although we’re using this technique.
Simulating Particles
To simulate the particules, we use semi-implicit Euler method taught in lecture, which is a more stable upgrade of the Euler method.
Velocity Transfers
For ease of explanation, we use 2D to explain how velocities transfer work. We then generalize this to 3D in our implementation of PIC and FLIP. Here’s a picture demonstrating the ideas of PIC/FLIP in a 3D staggered grid.
Velocity Transfers: Particle to Grid
Velocity transfers is the key part and backbone of the Particle-In-Cell method. A velocity of a particle is “spread” to the four nearest grids, with a closer one “having a larger share” of that particle’s velocity. Do that for every particle and each grid has an “average” of the particles’ velocities in the four adjacent grids, while each grid velocity possessing more of the velocities of particles near that grid.
Forcing Incompressibility
There is a problem that arrives if all we do is the step above. Using just these calculations, a cell could have a net positive or net negative of outflow of particles. This could never happen in real life so we correct it by calculating the net outflow (divergence) and spread it four ways in each side of the cell thereby making the divergence zero in a cell.
Velocity Transfers: Grid to Particle
After each grid velocity is calculated, we then calculate new velocities and positions of particle by doing a similar procedure: each particle takes the grid velocities of the four nearest grids and computes a weighted average of the four velocities, with a nearer grid having a larger weight.
Problems Encounterd
There is a problem in the PIC method that a majority of individual velocities in the same cell are lost (see picture below) because of the velocity transfers - each velocities are transferred first to the grid velocities then transferred back to each individual particles, hence we may see a problem like the below picture occurring.
To fix this, we use the FLIP method.
FLIP (FLuid Implicit Particle)
The key idea of the FLIP upgrade from the PIC method is: we still want to scale up our abilities to process particules using velocity transfers, but we keep the “individuality” of velocities intact by adding the “difference” of the grid velocities to each particle after a velocity transfer.
In other words, as we notice the key step in changing the velocity in each timestep happens in making the grid velocities incompressible - we add the difference of grid velocities caused in this timestep to all particles in the grid. In this way, the “individuality” of velocities are preserved!
Rendering in Blender
We iterated through 3 different methods to generate meshes, each mesh we create would eventually make it to blender where we use a refractive shader and a HDRI of a sunset in venice.
1. Marching Squares
Given particles in a scene and make a level set grid from these particles
We perform marching cubes (source) on a discritized grid to generate the mesh and store it as a .obj which we then export to blender.
We decided to forgoe this method as it was too slow for large numbers of particles.
2. Metaballs
For rendering in blender we exported simulation’s positions of particles at each time step into a
[num_steps, num_particles, 3]
dimensional vector. For each time step, we placed the particles according to the simulation’s output. This was automated using scripting in blender and thebpy
blender-python package. We then attach a metaball to each particle.This method gives good results, but the fluid ends up looking more like orbeez than water.
3. OpenVDB Tools
To solve the orbeez look, we used OpenVDB to create a series of
.obj
meshes from our sparse points. We then took the .obj files and using the power of the Stop-motion-OBJ blender add-on we created an animation of meshes. These results turned out to be much smoother than the metaballs.Lessons Learned
Results
Final Project Video
Openvdb Mesh
FLIP
Metaball Meshes
PIC
FLIP
2D SPH Simulation
Drive Link
References
Contributions from each team member
Tianchen Liu:
Wrote technical explanation on our approach of how SPH, PIC, and FLIP is implemented in the writeup & slide decks + contributed to other parts in the writeup + slide decks (background, abstract, etc.).
Riley Peterlinz:
Blender rendering pipeline. Coded a marching squares solver, then a blender script for metaballs, finally converting results from OpenVDB to blender results. Created materials for fluids and created environment in blender for renders.
Anders Museth:
Developed the entire 3D fluid solver based on the FLIP and PIC algorithms. Specifically, this included the Grid-to-Particle and Particle-to-Grid conversion, enforced zero-divergence of the fluid velocities on a staggered MAC grid, drift and density management, particle separation, boundary collision, and particle advection functions. Additionally, implemented a 2D SPH solver based on a tutorial, as well as various utility functions for both FLIP and structural components. Used OpenVdb to generate surface meshs for our final render.
Rhea Senthil Kumar:
Developed the Python simulation pipeline. Created 3D PIC and FLIP Renders in Python. Coded 3D Matplotlib Renders. Voiced the final video and created presentation slides.
Slides
Slide Deck for FLIPing Fluids
Code
Fluid-Sim Github