Rig performance tips

A rig should always be as fast as possible to improve productivity of animators. It is also more fun to interact with a fast rig in general and maybe even allows for viewing the animation in realtime inside of the viewport. So there is no need to create a playblast all the time.

The biggest factor is the geometry resolution (lowres/highres/..) and the kind of setup the rigger chooses  Hopefully always balancing quality and speed. This is very project and people dependent. So I'm not going into that here. This post should just be a small list of things that always work and are not that well known (?):
  • Remove vertices from the deformer, if they are not affected, with the "Edit Deformers > Edit Membership Tool". I almost always use this for lattice, wrap, wire, sculpt, .. There are probably cases for all deformers. This can also be achieved by only selecting the affected vertices when creating the deformer.
  • Use few skinClusters by merging geometries. This should be used carefully of course, because it can be annoying to skin overlapping geometry (maybe skin multiple geometries and copy skin weights on the final merged mesh when publishing the rig) and other steps in the pipeline have to be considered as well.
  • Remove unused influences from skinCluster. Use "Skin > Edit Smooth Skin > Prune Small Weights" before. Each influence costs a little bit of performance, so if you have multiple geometries that are skinned to all skinning-joints this can make quite a difference.
  • Connections instead of constraints. A lot of point/orient/parent/scale-constraints can be replaced by simple translate/rotate/scale connections, if the hierarchy is setup in the right way (Maybe by creating an extra null-group to have the same local transformation values). BlendColor nodes can be used for blending. I think scaleConstraints are always the worse option, and can be avoided completely.
  • Don't use clusters to deform curves. Instead use a skinCluster (use component editor to tweak skinning weights) or [Credit to Francisco Naranjo:] connect locatorShape1.worldPosition[0] into the curveShape1.contolPoints[x] attribute
  • Delete unused Orig shapes. This does not effect the rig speed when interacting, but is about filesize, which increases file-opening / reference-loading time. Whenever you create a deformer, maya also creates an Orig shape (intermediate object). If you duplicate a geometry that had an orig shape, it will get copied as well, but ignored for future deformers. So it basically just increases the filesize with no benefits. You have to remember to delete it, or delete the history before you duplicate. (An easy shortcut-combination to select the orig shape: Arrow down (child), arrow left (latest child)


Joint chain rigging techniques

Comparing different joint-chain-like rigging techniques. The idea is always to attach the skinning joints to a simple nurbs-curve or surface, which can easily be rigged. They all have squash/stretch/twist behavior. This kind of setup is useful for spine, bendy limbs, face (lips, eyebrows, muscle), snake, hair, tail...

They can be categorized as parametric and non-parametric. Meaning that joints will keep relative distance between each other (non-parametric) when changing the driving surface or not (parametric).
I recently compared them. Mainly for performance reasons, but keeping functionality in mind. The screenshots are from simplified setup versions.

  • Non-parametric
  • + Fastest non-parametric setup
  • - Limited twist control: Only start and end. No center twist control
  • - Undesirable behavior when modifying curve-cvs (overshooting joints)
  • - Gets exponentially slower when increasing joint count
  • + Easy to add dynamics/simulation on curve (because it is only one)

Joints attached to nurbs surface
  • Parametric
  • + Full local control
  • Average speed

Curve / Upcurve
Two curves. One has the skinning joints attached to it. The skinning joints either aim at the next skinning joint (spline-IK like behavior) or are rotated at the average of aiming to next/previous (ribbon like behavior). On the second curve are the up-objects for the aimconstraints. Both curves are deformed in the same way, so that rotation along the joint-curve (twist) will only deform the Upcurve, so there will be a smooth twist driven by the up-objects.
  • + Can be non-parametric (motionpath) or parametric (pointOnCurveInfo)
  • + Fastest setup when using pointOnCurveInfo (only when using one aimconstrain upwards)
  • - Slowest setup when using motion path
  • + Full local control between start and end, depending on setup
  • Note: motion path rotation should be used carefully (almost never?). Following curve results in more extreme rotation (bigger difference between neighbors) than average of aiming up+down. So deformation will look bad in most cases.
  • Note: Motion path should be created manually (createNode motionPath). Because the MEL command (motionPath) creates unnecessary doubleLinear nodes that create cycle warnings and the command is not undoable.

Muscle Spline
Muscle > Bonus Rigging > Create Muscle Spline...
Muscle Spine
  • Parametric
  • (+) Has a lot of functionality by default
  • - Joints get oriented to curve (same problem as motion path rotation... The average of aiming on upper and lower joint is probably always better)
  • + Nice tangent/curve control attributes from start/mid/end ctrls
  • + Seems to be a bit faster than Spline-IK (but it is not non-parametric like the Spline-IK. So they are not fully comparable)
  • + Jiggle options (for hair, props, tail, antenna, .. ?)
  • Local twist, but limited control over it (flip at 180), because it is calculated in blackbox node.
  • Note: For easy to animate curves set small "Tangent Length" value (0.01) on start/end ctrl and increase on the center ctrl to have automated bend when moving center ctrl. Also edit "uValue" attribute on first (from 0.0 to 0.01) and last joint (1.0 to 0.99), so they get oriented to the curve.

  • Wiredeformer is parametric
  • Curve added as influence to skinCluster (component mode on) is non-parametric

Curve / Upcurve setups are the most flexible and offer the most control, which probably results in the best deformation for most cases. But can be slower depending on the setup.
To get a better idea what "fastest" / "slowest" for these setups mean. Here are the fps numbers when adding eight chains (two for each limb, six joints each) of either type to a base rig that runs at 34 fps

34.0 base rig
28.6 (-5.4) pointoncurve
27.7 (-6.3) splineik
27.2 (-6.8) ribbon
26.7 (-7.3) motionpath
26.3 (-7.7) pointoncurve avrg