force_table_of_contents #
This node captures nearby sparse guides and deforms a set of dense curves based on the way those guides have been modified. Nearby guides are selected based on criteria such as hair-guide alignment and similar lengths, up to a limit.
Outputs #
This node produces these outputs:
- Deformed curves.
- Curves that could not find any capture weights, and thus could not be deformed. You can then either leave them out from the output to delete them or deform them in some other manner. These curves can be optionally included in the output as a skin deformation, which is suitable for short hair.
- The rest mesh used for the deformation.
- The target mesh used for the deformation (the rest mesh when no target mesh is connected).
- The points from the sixth input, deformed along with the curves. See Instancer Points.
Workflow #
The general workflow for working with this curve deformation system is:
- Load a dense groom. This may or may not come from Houdini.
- Use the hair_prepare node to transfer necessary skin attachment attributes to each primitive.
- Use hair_select or hair_extract_clumps to select simulation guides from the set of dense curves, or import existing guides and use hair_prepare to similarly prepare the guides for mesh attachment.
- Simulate or otherwise deform the guides (a procedural application of hair_collision may be sufficient).
- Use this node (hair_deform) to associate guides with each curve of the dense set and deform them to the animated guides.
- Use hair_collision to push any guided curves out of the collision shapes in a post sim operation, if necessary.
- Profit.
Capture #
Finds nearby guides to build a weighted deformation spline. The resulting deformation spline will be a weighted composite of the animation on the captured guides.
Capture Criteria #
Many guides are considered as a deformer and the nearest few that meet the following criteria will be used:
- Search Radius Scale: A scale on the guide search radius. Can help dial in the right capture weighting for calculated guide search radius.
- Minimum Guide Alignment: An alignment vector is established by building vectors between the root and tip of the two curves, then comparing the angle between them. The angle must be lower than the provided number of radians to be considered as a guide. This is the maximum number of radians allowed between a guide and a curve. A value of 0 requires the curve and guide to be perfectly aligned. A value of
$PI/2will allow a 180 degree angle (90 degrees on either side) between the guide and curve. - Minimum Length Ratio: Guides must be at least as long as this ratio to be considered. We do not want very short guides to drive the deformation of a long curve, since the tip of a curve could be inappropriately deformed by small guides. The ratio is calculated by multiplying the curve length by this ratio, then comparing the prospective guide to that value.
- Maximum Length Ratio: (Optional) Guides must not be longer than this ratio to be considered. This is optional, since typically a longer guide can still adequately deform a shorter curve. However, since long guides may interact with different colliders, we may want to select only guides that are closer to the curve length.
Capture Radius #
The guide capture radius may be explicitly set or it may be calculated. If the capture radius is calculated, it will be determined based on the distance between nearby guides. This means that tighter guide distribution will have a smaller search radius. This may be beneficial so that localized densities may be used to determine guide weighting.
Capture Iterations #
We begin with the most aggressive capture criteria, but that will often result in many curves uncaptured.
We iteratively capture guides with more and more permissive critera to give ourselves the best possible chance of finding good guides, while still reducing the chances of leaving uncaptured guides.
Existing Capture Attributes #
You can ignore the capture process entirely, if each curve primitive has a guides int array and a weights.
The guides array contains the primitive numbers of the guides on the guide geometry. This means that the guide geometry topology must remain consistent to when the array was initially created. Since this is based on primitive numbers (not id), you cannot build a guides array and then use hair_select, without fixing the guide selection values after selection.
Deformation #
Given a weighted deformation spline, use the curve’s parametric u value to determine an appropriate offset.
Guide Extrapolation #
Captured guides that are shorter than the curve will be extrapolated to the full curve length, which allows for a smooth and natural feel even with less-than-ideal guides.
Guides can be extrapolated linearly or polynomially, which will continue the curvature at the tip.
Redistribute Detail changes how a short guide fills the extra length. By default the guide keeps its shape and a smooth section is added past the tip, so any waves or kinks stay bunched in the original length. With this on, that detail is spread across the whole extended length instead: the guide is split into a broad shape (which still follows the guide and its tip extension) and the detail riding on it, and the detail is stretched to cover the full length. It only has an effect when a guide is shorter than the curve, and guides with no real detail are left as they are.
Smoothing Iterations and Strength set the split between broad shape and detail. More iterations or higher strength treat more of the guide as detail to spread; lighter values stay close to the plain extension. They default to 24 and 0.4.
Styles and Guide Attributes #
Styles #
A groom normally has a single rest shape. Styles let you store alternate rest shapes on the groom, such as a wet or a frizzy version, and blend the hair toward them per region using masks the guides carry.
Name the alternate shape attributes in Style Attributes and the guide masks that drive them in Style Masks. The two lists are paired one to one by position: the first style is driven by the first mask, the second by the second, and so on. The names are arbitrary and the pairing is entirely positional, so Style Attributes wet frizzy with Style Masks style_mask frizzy_mask blends the wet shape by style_mask and the frizzy shape by frizzy_mask.
Each mask is composited from the guides onto the groom like any other attribute, so you do not need to list it under Guide Attributes as well. The composited mask then blends the groom’s rest shape toward the style before anything deforms. Because the blend happens on the rest shape, the styled hair is deformed by the guides in a single pass with no change to the displacement itself. Where a mask reads zero the base shape is kept exactly; where it reads one the strand takes that style’s shape fully; in between it blends. If several masks overlap and sum past one they are scaled down together, so the result never overshoots a style. A style named without a matching shape on the groom is skipped.
Style Mask Extrapolation Mode sets how a mask is read where its guide is shorter than the strand, the same set of choices the composite attributes offer. Normalize remaps the guide’s whole mask onto the full strand, Hold clamps to the guide-tip value, and Linear or Polynomial continue the tip gradient, with Polynomial decaying the added curvature by the extrapolation decay. The one setting drives both the shape blend and the written mask value, so the two stay in step. It defaults to Normalize, which keeps a painted mask following the hair proportionally.
Guide Attribute Transfer #
Any point int, float, vector, or vector4 attribute the guides hold can be composited across the captured guides the same way the deformation spline is, then written onto every deformed curve. This is how a mask, width, color, id, or normal painted on the guides can ride through to the dense hair.
List the attribute names in Guide Attributes, separated by spaces. The values are read from the animated guides, so you get their deformed value rather than a rest snapshot. Anything you leave off the list is untouched on the groom, and an attribute whose name already exists on the groom is overwritten, which is exactly what lets a guide mask land back on the hair under its own name.
Where a captured guide is shorter than the curve, the attribute has to be carried past the guide tip, and there are three ways to do it, matching the guide position extrapolation above:
- By default, the attribute is normalized: its whole root-to-tip profile is remapped onto the full strand, so the guide’s tip value always lands on the real tip.
- Names listed in Guide Extrapolate Attributes continue the gradient the attribute had at the tip instead, extending values linearly.
- Names listed in Guide Hold Attributes clamp to the tip value and stop changing past it, which suits ids or region tags that should not drift.
Within the length a guide actually covers, all three read identically; the mode only matters past a short guide’s tip. Integer attributes round on write, normals are kept unit length, and quaternions stay normalized. Each attribute keeps its type info as well, so a color, normal, point, quaternion, texture coordinate, or vector lands on the groom as that same kind and transforms correctly downstream instead of falling back to a plain vector.
Displacement #
Displacement Modes #
The displacement mode combo offers three choices: Translate, Swing (Slide), and Swing (Pinned). All read the same blended per-curve guide; they differ in how a strand follows it.
Translate #
Each strand keeps its rest shape and is simply moved to follow its guide. However far the guide has shifted from its rest pose to the animated pose, every point on the attached strands is pushed by that same amount, like picking up the hair and setting it down wherever the guide went.
Because the strands only slide with the guide, they do not reorient when the guide bends or twists; they hold their rest orientation, and the clump is kept from stretching or collapsing by the distance constraints. This looks great when the guide motion is mostly drift or sway, and less convincing when the guide bends or curls sharply, since the strands will not rotate to follow that bend.
Swing #
Each strand rides on the guide as if pinned to a frame that bends and spins along with it. As the guide curves or twists from its rest pose into the animated pose, the strand swings and rotates to match, the way clumped hair naturally pivots around the strand it is following.
Instead of just relocating the hair, this preserves the strand’s shape relative to the guide, so curling, bending, and twisting guides all read cleanly.
Swing offers two ways to anchor each point along its guide:
- Slide: points slide freely along the guide so the strand holds its rest length through a bend. This is the right choice for straight or gently bending guides, where keeping exact length matters most.
- Pinned: each point is pinned to a fixed fraction of the guide and never slides, so the motion stays clean on tight curls. The strand’s length then follows the bend rather than being held exactly. Prefer this on curly guides, where a sliding point tends to read as noise crawling down the strand.
Curve Processing #
Curves may change length after the raw offsets are applied, so we also forcibly trim/extend the curves to their original length.
Guide Tightening will attempt to keep a stable distance of the curves to the guides through deformation.
Twist #
If twist is enabled, curves will rotate around the guide at the number of radians, interpolated along its length.
If the guide is shorter than the curve, the twist can be extrapolated, held,or normalized to the full length of the extrapolated guide.
Guide Tightening #
After deformation, it is often the case that a clump shape will splay out, especially if the surface skin has bent relative to its neighbors.
Guide Tightening will pull deformed curves back to their distance from the guide at rest. How it does this depends on the displacement mode:
- Translate: curves that end up further from the guide than at rest are pulled back in. Curves inside that distance are left as they are.
- Swing Pin: each point is pulled in or pushed out to its rest distance from the point on the guide it is pinned to. The curve keeps its length, so a curve that can’t reach its rest distance leans toward it instead of stretching.
- Swing Slide: each point’s distance across the guide is set back to its rest distance, pulled in or pushed out, while it stays free to slide along the guide.
Instancer Points #
The optional sixth input takes points to carry along with the groom, such as the points of a point instancer scattering raindrops, debris or beads through the hair. The deformed points come out of the fifth output, Deformed Instancer Points.
Wire the points in at their rest positions, matching the rest groom. Each point binds to the nearest strand: which strand, and how far along it. On every frame, the node measures how that strand has rotated at that spot between rest and its deformed pose, and applies the same rotation to the point’s offset from the strand and to its orientation. The point keeps its distance from the hair and turns with it. The strand’s frame starts from the skin at the root, so a twist of the skin around the root carries through to the point even when the strand’s shape doesn’t show it.
- Orientation:
orientis rotated if the points have it. OtherwiseNandupare rotated if present. With none of these, the node createsorient, so every point still carries the strand’s rotation (identity at rest). - Velocity: when Transfer Guide Velocity is on, each point gets the motion of its place on the strand, so its motion blur matches the hair’s:
vandaccelfrom the deformed curve at its binding, plus the swing of its offset as the strand turns, andw, the angular velocity its orientation turns at (radians per second). The strand’s turning is measured from the curve’sv, and the skin’s own turning at the root is added as described in Skin Rotation under Velocity. - Max Bind Distance: points farther than this from every strand at rest are passed through untouched. 0 binds every point, however far away.
Points whose strand doesn’t come out of the deform, such as uncaptured curves you’ve deleted, are also passed through untouched. Scale and other attributes are left as they are.
On hair_deform_procedural, list the instancers in Point Instancers. Their instances are deformed in the same cook as the groom, and their positions and orientations are replaced at render time, along with their velocities, accelerations and angular velocities when Transfer Guide Velocity is on.
Velocity #
Transfers velocity and acceleration from the animated guides to the deformed curve points in a single pass. The pass requires v on the incoming guides; accel is an optional value-add that enables the acceleration output and a more accurate reconstruction (see Source Attributes).
The pass is the most expensive part of the deformation. Turn off Transfer Guide Velocity to skip it when you do not need velocity, for example when motion blur comes from subframe samples instead. The deformed curves then carry no v or accel, and instancer points get none either.
Source Attributes #
Velocity is computed upstream on the animated guide points before they enter the guide deformer. Use a Trail SOP on the anim guide curves. Setting it to “Compute Velocity and Acceleration” is recommended: the added accel lets the transfer use that mode’s centered differencing to reconstruct the neighboring frames it reads the guide’s rotation from, and emits an acceleration output. With velocity only it falls back to a backward-difference reconstruction (off by about half a frame) and writes no accel.
| Attribute | Type | Required | Description |
|---|---|---|---|
v |
vector | yes | Point velocity from guide animation |
accel |
vector | no | Point acceleration from guide animation |
twist_rate |
float | no | Twist angular velocity in radians per second |
The incoming guide v and accel should have “vector” type info (the Trail SOP sets this by default). The node tags its own output v and accel as “vector” automatically, so the downstream transformbyattrib rotates them from rest into anim space.
v is required: if it is absent the velocity pass is skipped entirely. accel and twist_rate are optional value-adds, disabled automatically when missing — without accel the pass uses a velocity-only reconstruction and writes no acceleration; without twist_rate the twist-rate contribution is dropped.
Output v and accel come only from the guides. The groom’s own v and accel are removed where it enters the node, and v or accel listed as guide attributes are never transferred onto the curves, so without v on the guides (or with Transfer Guide Velocity off) the output has no v or accel, and without accel on the guides it has no accel.
Method #
In a single pass, each point is transported rigidly about its guide pivot. The angular velocity and angular acceleration are measured from how the guide tangent rotates between reconstructed neighboring frames, so the velocity swing follows the same geometry as the position deform.
Because it transports rigidly about the guide, it does not capture the small tangential sliding introduced by the resample redistribution or the target-space constraint; for hair those residuals lie mostly along the strand, the least visible direction for motion blur.
Skin Rotation #
When Transfer Guide Velocity is on, the node adds the motion of the skin itself to the velocity. It works in an unusual way, so this section explains what it does and when to trust it.
The deform runs in rest space. Each guide is moved into rest space by its own skin transform, each curve is deformed there, and the curve is then carried onto the target mesh by the skin transform at its root. The velocity pass only sees the guides’ v, rotated into rest space. Carrying v back onto the target mesh rotates it, but can’t add the transform’s own motion. So in the swing displacement modes the curves’ v is missing the skin’s rotation: every point is off by w × (P − C), where w is how fast the skin is turning at the hair root and C is the point on the guide that the curve follows. Hairs far from their guide on fast-turning skin are affected most. The Translate displacement mode was measured not to have this gap, so its curve velocity is left as it is.
The skin’s rate of turning isn’t available as an input. The procedural only sees one moment in time, skin meshes rarely carry v, and a rate of turning can’t be read from positions or normals at a single instant. So the node estimates it from the guides. Guide v is already required for velocity, and the guide roots ride on the skin. For each hair, the eight guide roots nearest its root are fitted to a rigid motion: a weighted least-squares fit in which nearer roots count for more. The fitted rotation is added to the curve’s v, and instancer points use it as the skin’s spin, so they also turn with the skin around the hair root.
It relies on:
- The guide roots being attached to the target mesh, so their
vis the skin’s motion. The node checks each root’s position: a root carried by the skin keeps the offset from its binding point that it had at rest, measured in the skin’s local frame. A root whose offset has changed by more than 0.1% of the size of the face it is bound to has slid over or lifted off the skin, and is left out of the fit. A hair then uses the nearest roots that are still attached, and with none left, nothing is added. The check can’t catch a root that sits where the skin carries it but whosevdoesn’t match the skin’s motion. - At least three guide roots around each hair, not all in a line. With fewer, the part of the rotation they can’t show is left out.
- A target mesh. Without one the skin doesn’t move, and nothing is added.
What to expect, measured on the example scenes against the motion between frames:
- On a rigidly moving body, the hair roots’ velocity becomes exact. The curves’ median velocity error drops from 2.9% to 0.8%, and the error in instancer points’ spin drops from 58% to 5%.
- On a strongly deforming body, the fit gives the average rotation of the patch of skin it covers. The curves’ median error drops from 4.4% to 2.7%. What remains at the root comes from the skin stretching, which a rotation can’t express.
- Sparse guides still help. With ten guides on the example pig, the curves’ median error drops from 8.7% to 1.0%.
accel is not changed, because the matching acceleration terms were measured to make no difference.
There is no switch for it. Guide v that doesn’t match the guides’ motion makes the fitted rotation wrong, but it makes the curves’ velocity wrong anyway, since that comes from the same guide v.
Computing Twist Rate #
No built-in Houdini node computes twist rate. Use a wrangle with a Time Shift on the second input:
- Input 0: current frame anim guides (with
twist) - Input 1: previous frame anim guides (Time Shift, frame - 1)
float tw_cur = f@twist;
float tw_prev = float(point(1, "twist", @ptnum));
f@twist_rate = (tw_cur - tw_prev) * @TimeInc;Troubleshooting #
Debug Mode #
Curve deformation can often be difficult to diagnose.
Setting Debug allows users to select specific curve ids.
Selected curves will show their captured guides in a dimmer color, both in their rest (blue) and deformed (red) positions.
Using the selection button allows selection by curve id.
The main issues to consider when troubleshooting are:
- Deformed curves are penetrating collision surfaces: Use hair_collision to bump the hair back into position.
- Curves are being deformed by inappropriate guides: Consider making the capture criteria more stringent, and increase the number of iterations. Alternatively, select more guides. Oftentimes, more guides are necessary around collision surfaces, such as a shirt collar.
- Guides are clearly identifiable in the clumping: Increase the maximum number of used guides.
- Deformation is too mushy: Decrease the maximum number of used guides, to get more discrete deformation.