Hair Simulation with Position Based Dynamics
Overview
The goal of the project was to simulate multiple hair strands based on the paper “Fast Simulation of Inextensible Hair and Fur” by Müller, et.al. The technique extends Position Based Dynamics and Follow-The-Leader to simulate inextensible strands. In addition, the paper presents a way to handle hair-hair interaction (including friction and hair-hair repulsion) that uses a variant of the technique presented in “Volumetric Methods for Simulation and Rendering of Hair” by Petrovic, Henne and Anderson.
Algorithm and Results
PBD/FTL
The paper extends FTL (Follow-the-Leader) for dynamic simulation. FTL deals with the behavior of a single strand. This is very similar to simulating an n-pendulum using PBD. With PBD, connected particles are moved towards each other in the inverse proportion of their masses. But to maintain inextensibility, we move only the second particle in each pair along the strand. If interpreted as mving particles in inverse proportion of masses, this results in the first particle having infinite mass, and the second particle having all the energy. This yields strange behavior:
The technique proposed by Müller, et.al. introduces intentional numerical damping to hide the uneven mass distribution inherent to FTL. The steps for dynamic FTL with damping are:
\(\mathbf{p} \xleftarrow{} \mathbf{x} \mathbf{+} \mathbf{\Delta} \mathbf{tv} \mathbf{+} \mathbf{\Delta} \mathbf{t^2 f}\)
\(\mathbf{p} \xleftarrow{} \mathbf{solveConstraints(p)}\)
\(\mathbf{d_i = \textbf{correction vector while solving constraints}}\)
\(\mathbf{v_i} \xleftarrow{} \mathbf{\frac{p_i - x_i}{\Delta t}} + s_{damping} \mathbf{\frac{-d_{i+1}}{\Delta t}}\)
\(\mathbf{x} \xleftarrow{} \mathbf{p}\)
On implementing this we get a more reasonable strand simulation with a damping factor of 0.9.
Hair-hair interaction
A hair density voxel is created, and then additionally populated with particle velocities in order to find a weighted average. Averaging the velocity based on voxel density makes the particles close to each other move with similar velocities thereby imitating friction.
Voxel density is given by:
\(\mathbf{D_{xyz} = \sum^{}_{i} (1 - |P_x^i - x|)(1 - |P_y^i - y|)(1 - |P_z^i - z|)}\)
And the average velocity at each point is given by:
\(\mathbf{V_{xyz} = \frac{\sum^{}_{i} (1 - |P_x^i - x|)(1 - |P_y^i - y|)(1 - |P_z^i - z|)v^i}{D_{xyz}} }\)
The final particle velocity is updated as follows:
\(\mathbf{v \xleftarrow{} (1 - s_{friction} v + s_{friction}v_{grid})}\)
In order to implement repulsion, the technique presented by Müller, et.al. uses the above mentioned density voxel by Petrovic, et.al., but updates the velocities in a different way. First the normalized density gradient is computed at each point (\(\mathbf{g = \nabla \rho / \vert\nabla \rho\vert}\)). Then the velocity is updated as follows:
\(\mathbf{v \xleftarrow{} v + s_{repulsion}g/\Delta t}\)
Collision with static/kinematic objects (in this case, spheres) has been implemented using a penalty force based approach. Generally PBD collisions with static/kinematic objects are implemented by either solving a collision constraint or directly moving the colliding particle to the surface of the object. Since hair is inextensible, this technique yields unusual behaviour. The current workaround is to use a penalty force based technique, where at the beginning of each time-step, for each collision an extra force opposite to the collision vector is added along with a proportionality constant. The downside of this method is that the proportionality constant is empirical. But with some efforts it yields decent results.
Finally I built a scene with the Victor 3d model from from A3, and gave him some hair! First I imported the mesh in blender, separated the scalp vertices and exported it to an obj. I then imported the scalp mesh into my hair simulator, genrated random points within the triangulated scalp mesh, which were then used as roots for the hair. The body mesh is approximated with 5 spheres for collision (one for each, head, nech, left shoulder, right shoulder and chest). Additionally I also added an osscilating wind force field to make things interesting. Here’s the result!
Code Repository
GitHub Repo: HairSim
Acknowledgements
- The OpenGL boilerplate code has been borrowed from Prof. Sueda’s assignment material and has been modified for OpenGL 4.x.
- The project is based on the papers:
- “Fast Simulation of Inextensible Hair and Fur” by Müller, et.al.
- “Volumetric Methods for Simulation and Rendering of Hair” by Petrovic, Henne and Anderson
- GLM and Eigen were used for vector math
- oneTBB was used for multi-threading
- The Victor 3D Model is from facewaretech.com
Enjoy Reading This Article?
Here are some more articles you might like to read next: