Giving a generated character hair that can move
By Oleg Sidorkin, CTO and Co-Founder of Cinevva
A generated character can have a convincing hairstyle and still have no hair that can move independently. The output may be one surface, a collection of thin cards, or disconnected pieces. None of those representations tells a simulator where a strand starts, which way it grows, or how it should bend.
Our previous hair experiment began with artist-rigged avatars and a selected ponytail. This time we started with reusable hair meshes and our frog character. The question was more basic: can we fit a hairstyle, trace useful guide curves through it, and keep their roots attached during animation?
Across 46 hairstyles, the current prototype extracts 10,467 candidate guides and finds scalp connections for 10,346 of them—98.84%. That is an attachment result. It is not a 98.84% success rate for natural hair motion.
Try the mesh and its guides
The demo loads immediately. Choose a Hairstyle, then use Hair inspection to switch between the original mesh, mesh plus guides, and guides alone. Drag the preview to orbit; inspect the back as well as the front. Choose an Animation to see whether the attachment follows the moving character.
Cyan curves have a scalp connection. Orange curves were rejected. “Show suggested roots” reveals the proposed attachment points. Long01 is a useful dense example; the French braid variations expose the challenge of joining separate fragments. Download the guide curves to inspect their points and attachment metadata.
Eligible loose hairstyles now use an experimental adapter to the shared hair solver from our earlier article. It selects up to 24 guide chains, creates joints, and gives the visible mesh and guide overlay the same skinning weights. The cap stays pinned; unsupported regions remain head-bound. Short styles without eligible loose guides keep rigid attachment. Two French braid examples retain their separate experimental joint-chain treatment. Switching the inspection view preserves playback.
Fit first, then establish attachment
We assembled 46 CC0 hairstyle options from MakeHuman collections, dreadlock variants, and Quaternius assets. Each option has a source link in the demo; the asset catalog and license inventory preserve provenance. These are reusable mesh assets, not a uniformly rigged strand library.
The first placement failed visibly: the hair sat behind the frog's head. Bounding-box scaling had aligned the objects without identifying the intended scalp. Our fitting pass now estimates the source crown, aligns it to the target head surface, and moves overlapping upper hair outward against an approximate head envelope.
That is similar to the separation we used in the clothing article: placing an asset, fitting its shape, attaching it to a rig, and giving it secondary motion are different jobs. A hair root should stay on the scalp, while the lengths should retain their hairstyle rather than collapse onto the body.
The frog is deliberately awkward: a wide head, raised eyes, and nonhuman proportions. The current upper/rear scalp mask is inferred specifically for this character. It is not an automatic scalp detector for arbitrary generated models. Some styles still obscure the face or have unsuitable proportions.
Trace paths through the existing surface
We build a connectivity graph from each hair mesh. Coincident vertices split by UV seams are welded for this analysis; the rendered source mesh is preserved. Within each connected component, we find surface paths from an initial root candidate toward separated endpoints, then smooth and resample those paths into curves.
For adjacent vertices
This shortest-path construction follows the mesh surface. It does not discover biological growth direction. The initial high-point root is only a proposal; scalp proximity can reverse a curve later. A flat card often provides a useful path, while a closed cap or a disconnected curl is much more ambiguous.
These are candidate guide curves, not recovered individual hairs. One card can represent many visible hairs, and a surface path can cross the intended flow. Dense cyan coverage can look impressive while hiding incorrect directions. Visual inspection remains part of the test.
Make the roots follow the actual scalp
A guide endpoint is matched to an eligible scalp triangle. If it is too far away, we reject the connection rather than stretch it arbitrarily to the head. Accepted roots store the triangle's vertex indices and barycentric weights.
For triangle vertices
The weights stay fixed while the triangle vertices move with the skin. Parenting the entire display only to the head had left up to 0.657 mm of root drift in our sampled Walk check. Following the stored triangle attachment reduced that error to numerical precision: less than
This is a numerical consistency check under the scene's metre convention. It does not establish a perceptually correct hairline, surface clearance along the curve, or stability under every animation.
Join fragments without hiding uncertainty
Some hairstyles arrive as many disconnected pieces. A fragment far from the scalp may be a continuation of an already attached lock. We test both orientations and join it to an accepted guide only when the endpoints are close and their directions agree.
The current joining rule uses a 25 mm distance limit and a tangent dot product above 0.5, under this scene's scale. Only already attached paths can become parents, which avoids cycles. Curve length, point count, and joining passes are bounded. These thresholds are prototype choices, not universal hair parameters.
Joining adds 1,851 connections to the accepted set. The French braid variation goes from 136 directly attached guides to all 509 connected; the unkempt braid reaches 512 of 519. The remaining seven fragments stay orange. A connection still needs review: nearby geometry is not proof that two pieces belong to the same strand.
Explore the measured coverage
Search for a style or show only those with rejected guides. The links open the corresponding live inspection view. These numbers are the saved 46-style audit, not a continuously calculated physics score.
46 of 46 styles · saved audit
Download the complete attachment results.
All 46 styles loaded without browser errors in the audit. The extraction omitted 90 vertices across three Elvs meshes. Four focused tests check connectivity, reporting of omissions, reconstructable scalp attachments, fragment joining, and rejection of remote fragments. Desktop and 390-pixel mobile views were inspected; the mobile page had no horizontal overflow.
The results measure this library fitted to this frog. They do not cover arbitrary generated geometry, all poses, self-collision, or export into another engine.
What has to happen before this becomes hair physics?
The current guides provide roots and candidate paths. A first adapter now reuses our existing fixed-step spring, rest-shape, and contact solver. On Long01 it binds 18,204 of 39,804 mesh vertices to 24 chains; a sampled loose-hair point moved 13.6 mm relative to the head in the controlled test. This verifies secondary deformation, not natural motion or collision-free animation. The mesh and overlay use the same skinning field. Reliable direction, coherent weights across each lock, and broad motion checks remain necessary.
The next gates are to review ambiguous roots and fragment joins, improve guide selection and weights without tearing across separate locks, and validate body contact during motion. Self-contact remains additional work. Export and reload must preserve those bindings too.
For generated characters, replacing a separate hair surface is a practical starting point. A fused head-and-hair mesh adds another prerequisite: identify the hair region and establish a usable scalp underneath it. Our frog experiment does not solve that segmentation problem.
We now have an inspectable intermediate result: a fitted mesh, explicit candidate paths, moving surface attachments, and visible rejections. The next improvement must make those paths behave convincingly—not merely increase the cyan count.