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:

Static FTL

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.

Dynamic FTL

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.

Hair-hair interaction and collision with static/kinematic objects

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!

Hair on a character

Code Repository

GitHub Repo: HairSim

Acknowledgements