Rigging Tip: Driving your Deformations (primarily for Games)

Sol Brennan
14 min readJun 11, 2021

So in the article Rigging Tips: Methods for Extra Character Deformation (in Game Dev), I spoke about when to use blendshapes versus helper joints? Now that we have an understanding of that, let’s talk about how we can drive these attributes.

Please note I will only detail Maya-centric solutions as this is most common within the professional industry and I don’t really have the experience and authority to speak about other programs. A lot of these concepts can be applied in to other programs and hopefully will be of some help even if you are not using Maya.

When we talk about ‘driving your deformations’- what do I mean? In this, I’m talking about getting one or more values, to drive one or more other values. To create a relationship between two sets of numbers — whether they be translation, rotations, simple floats or complex matrices. All we need to focus on when creating these relationships are — what is the data I’m controlling, and what am I hoping to drive? Where you build this into your setup — on the rig, the bones directly, another rig that plugs in or additional logic that is housed outside of it, within a plugin or perhaps even real-time in engine — should be tailored to what you care about. Is it performance? Reusability? Flexibility? Ease of use? Simple to access? This is all down to your preference and needs for your project, your content and your workflow and tools.

I will discuss some of the most commonly seen methods easily available and often used, specifically within my area of expertise — video games.

SDKS

Helper joints have often traditionally been driven by system like Maya’s SDKs. SDK stands for ‘Set Driven Keys’ — as it is named within Maya itself. So what are SDKs? They’re a way to have an arbitrary value control (or drive) another value/s with an animation curve. These can be found relatively hidden within the Animation > Key > Set Driven Key > Set… (click the box to get the UI).

A looping gif showing the Maya user interface. There is a blue cube moving to the right with the word ‘Driver’ written on it. Next to it, on the right, is a green cube with the word ‘Driven’ written on it. As the blue cube moves right, the green cube moves up. At the bottom of the screen, you can see Maya’s Curve Editor open and a smoothed curve onscreen. The playback bar can be seen progressing linearly across the screen from left to right.
The animation curve on the bottom is driving the green cube. As the Driver object moves in +Z, the Driven moves up in +Y.

The important distinction to make here is that the animation curve is driving properties real-time in the viewport and doesn’t require any change of time, but rather a change of a value being evaluated in Maya. SDKs are just ONE implementation of a technique like this in Maya. You can technically drive any value by another — this could be controlled by a node graph node (like remap, a multiplier, or various other means). The power of the animation curve is that the motion can be keyed and customised — which can be quite powerful if you want to control the way your attributes are driven. Not only that, but it is method of driving that is understood by animators — so if you expose it you can have animators edit the curve to their satisfaction (if they’re savvy enough to understand SDKs and their disconnect to time).

Typically, when it comes to SDKs — setup usually consists of selecting what you are driving, setting the initial key on it (with the UI!) and whatever it’s driving (can be multiple objects/channels) and then for every bit of movement, stopping and doing the same process. This has flaws however. If you are dealing in translations only — SDKS are pretty easy and useful to use. Rotation driving or being driven will result in Euler pops or gimbal lock (a video like this will explain it much better than I can!). Not ideal. In this case, you’ll want to add additional logic, using aim constraints or some other vector calculations than drive the rotations instead to reduce that. Scale get even trickier — because the base value for scale is 1, not 0. Therefore, additional SKDs on scale can be negative curves and can be very difficult to read and parse after setting them (if you want to edit them perhaps). When driving simple things, SDKs can work well — the more complicated a setup gets — the more difficult it becomes to manage SDKs and at this point you might need a tool to manage to curves (as Maya’s default editor is not very in-depth or useful past the initial setting of keys). Notoriously, it can clog up the Curve Editor if not sufficiently removed from animator controls, and makes Curve Editor a nightmare to read if you are editing them within the interface.

On top of that, SDKs can be a slow, outdated and rather cumbersome way of driving attributes. When Maya constructs these, it creates a whole bunch of nodes with each key, compounded by blending nodes when there is more than one SDK driving a control.

A screenshot of Maya’s node editor showing a single node inputting into a middle node, then out to another single node.
Look at this simple little guy! Transform to Transform is nice and clean!
A screenshot similar to above but this time there is a unitConversion node between the first node and second node’s connection.
A rotation driving a rotation adds a unitConversion node! Anytime a rotation is used, Maya create a unitConversion node to handle the transformation of a float into a eular angle.
In this one, there is two node connections similar to the screenshots above, but then are both feeding into a new ‘blendWeights’ node, which blends the results into an output.
Having two separate objects drive a single one adds a blendWeighted node — PER CHANNEL! You can imagine how complex it starts to get as more drivers are added. Also, remember to rig and create SDKs in centimeters — otherwise you will compound the unitConversion nodes!

Expressions

Speaking of slow and outdated… another method of driving things in Maya can be expressions. I’ll be honest here — people either love or hate them. Expressions are chunks of Maya MEL code that are running live. I’m in the latter camp — but I know their usage can be divisive. I don’t use them because they are difficult to parse, debug and edit in code. Many rigging setups are created, edited, rebuilt and evaluated via Maya scripts — and expressions can complicate this. However, they have their usages. Patrick Woo covers expressions in a series of videos here, doing them a lot more justice than I ever could.

These are more common for simple, linear types of behaviour — like a twist joint setup. What is cool is that you can use math functions that aren’t available as native nodes in the Node Editor, such a cos, sin, etc…

A screenshot of Maya’s expression editor. You can see an expression written in MEL at the bottom. It reads Ball.translateX=cos(time)
As seen here, linked from the Maya Documentation

Moving on to more (relatively speaking) modern ways of creating these relationships…

Cone Readers

Ah! The humble Cone Reader. The Cone Reader first came into popular usage with the amazing set of tools offered by Michael Comet — a suite of tools for Maya still used to this day.

A gif from a educational video on The Last of Us rigging. There is a character’s wrist onscreen. The wrist is moved slightly, and you can see 3 joints inside move to correct the deformations at the write. The wrist joint is then clicked and 3 large and very flattened cones appear — showing the cone reader’s visual representation.
Cone Readers as seen in one of my oft-references videos Rigging on The Last of Us

Cone Readers are a fairly simple concept — they give you the angle of a cone, with a given angle where a value will start to fade from 0 (the outer limits of the cone) to 1 (the centre of the cone). These are useful as you can tune at what angle of rotation starts to drive an external value (the 0–1 float). The problem with Cone Readers is that they are uniform in scale (no squished or irregular shapes cones!) and can only drive a single behaviour — meaning that tuning the fade in and fade out of the angle can be a balancing act and fine-tuning the behaviour is not always achievable.

Traditionally, their usage has been limited to blendshapes but in video games, joints are often more economical, or easier to reuse — thus the 0–1 driving system can be a bit odd to navigate when you are driving transforms.

Here’s an older, but extremely helpful video from Marco Giordano on how you can build your own cone reader — without the need for a plugin, and also a good explanation on how it works.

At scale, the famous Comet Cone Reader can be a big of a resource hog which is not surprising seeing as the most recent releases of it as basically life-support and the poor code has been around forever. Companies will often develop their own cone-readers or perhaps use some of the newer, quicker plugins built by other studios smart folks out there like Vector Angle mode in Brave Rabbit’s weightDriver.

Radial Basis Function(RBF)

Ahhh… the big daddy itself of driving deformations and an industry standard. Much heavier and more complex than SDKs, Cone Readers or other such methods… Radial Basis Function is named (within rigging circles) after the original Disney Paper written on it.

Hans Godard’s RBF solver example explains this more beautifully than I ever could.

A looping gif of a large black ball in Maya with multiple coloured balls on its surface. There is a pin control on it and a flat coloured sphere to its right. As the pin rotations in the center of the balls and moves closer to the many multiple coloured balls on the surface, the output ball (the one of the right) changes colour to approximate the closest combination of colours to the pin control.
RBF in action — finding the best colour to blend between sampling all the colours around it.
A looping gif of a shoulder rig showing off 4 crafted shoulder blendshapes and the RBF driven solution blending between these blendshapes to create a deforming shoulder mesh that considers the mass and volume of the shoulder as it moves.
RBF driving blendshapes, a single joint driving multiple float values.

I’m not going to lie — the maths behind this eludes me here. But the concept is simple. You can use a single solver to use arbitrary values to drive an unlimited number of other arbitrary values — which means this is perfect for a matrix driving other matrices(joint transforms) or single values (blendshapes). This is a very flexible and powerful option for those who are looking to finesse shapes. The downside is nothing is for free if you prefer more additive solution. Combination shapes must be distinctly sculpted or driven by different solvers to combine their transforms. For example, say you have a mouth wide shape in a facial rig, and a mouth open shape. These cannot be driven by the same interpolator to get mouth wide and open at the same time, meaning more solvers will be required for those solutions. If driven by the same solver, this will result in a compromised shape-where only half of each shape is being engaged. For solutions like that — SDKs can be a simpler choice.

RBFs solvers are either written by individuals, offered online like Brave Rabbit’s weightDriver (choose RBF mode) or even available natively in Mata — with a little extra work required.

Maya’s native Pose Deformer tool still has the problem that it expects blendshapes — but you can use the nodes that come with it to extract the behaviour and drive your own setups.

a screenshot from Maya’s Node Editor showing a simple setup of a node connecting to Maya’s poseInterpolator node. It’s outputing to a blendshape
Here is the poseInterpolator node driving a Blendshape — as setup in the UI that comes with it.
In this screenshot, very similar to above, the output of the poseInterpolator is also going to a remapValue node, which feeds into the position of another node in Maya’s Node Editor.
Think you’re driving a blendShape? Wrong, poseInterpolator! You’ve been HIJACKED!

Math Nodes

Maya has many natively supplied nodes within it — often given names that don’t correspond to their practical usage but derived of some feature they were built to supplement. Because Maya lacks a lot of really simple functions but it built on a node-based system — we can use these nodes to drive desired behaviours. This is extremely useful and pretty crucial for rigging itself, but can be used also in driving deformations. For what are deformations other than relationships between a control and something being controlled — often by a character rig itself?

Here I will cover and give a summary and some usages of some of the more useful Maya nodes. You may not be aware of some of these or be confused by their purpose because of the name — but if there is anything you should learn by working in tech-art, it is to use every tool available to you to do the job you need, regardless of it’s intended purpose (just please talk to a programmer if you are planning on doing this in a game-development environment. Sometimes they will have a better solution, or what you think is a good way to use a tool might cause problems for others, whether in performance or implementation).

Without further ado:

AddDoubleLinear (also, plusMinusAverage)

A screenshot of Maya’s Node Editor. It shows the addDoubleLinear and plusMinusAverage nodes not connected to anything.
addDoubleLinear and it’s bigger sibling plusMinusAverage

Function:
addDoubleLinear takes two inputs an sums them. Simple, fast and clean for when you need addition.
plusMinusAverage is a little more complex, allowing for not only the addition of floats(1D), but also 2D(UVs) and 3D(vectors) to be calculated. It also allows for more than 2 inputs — but will only add similar types. Be careful with the UI — to add 1D inputs, you will need to add them either via connections in the Node Editor/Connection Editor or via script. Thanks Maya! The Channel Box also doesn’t contain any information at all…
Usage:
Simple enough! Do you need to add two or more numbers together? If you need to subtract, it’s easier to use the plusMinusAverage node, rather than converting all subtracted values to negatives.

multDoubleLinear(also, unitConversion, multiplyDivide)

A screenshot of Maya’s Node Editor. It shows the multDoubleLinear, unitConversion and multiplyDivide nodes not connected to anything.

Function:
multDoubleLinear takes two inputs and multiples them. Maths! The Channel Box doesn’t have show the values however, so make sure to check the Attribute Editor.
unitConversion is very similar except the input is the first value and the conversion factor is the second value.
multiplyDivide allows you to do a multiply, divide or power operation with vectors (3 channels!). If you wish to divide, it’s safer to use a multDoubleLinear or multiply operation with your dividing number as a negative if you can as this way you never divide by zero. (Computers LOVE dividing by zero).

Usage:
Mutliply! Divide! Multiply to the Power of! This is just simple maths stuff, but it’s nice to know it’s all still here.

Reverse

A screenshot of Maya’s Node Editor. It shows the reverse node not connected to anything.

Function:
reverse has 3 channels for inputs — meaning you can use it for vectors or 3 float operations. Converts 0 to 1 and 1 to 0. Operation is (-1x +1) = y, where x is your input and y is your output.
Usage:
Very useful for IK/FK switches, or any operation where you want the opposite behaviour from a 0–1 range.

Remap Value (also remapColor, remapHSV)

A screenshot of Maya’s Node Editor. It shows the remapeValue, remapColor and remapHSV nodes not connected to anything.
remapValue is surprisingly useful! remapColor/Hsv are the same with additional functionality.

Function:
remapValue also allows you to remap a range of values to another range. Unlike setRange, it gives you a handy-dandy little curve, allowing you to have multiple points, or tangents in your range, controlling the rate of your interpolation. You give it a min, and a max for both the input and the output, and the controls the relationship. Color gives you the ability to remap to a vector (3 values) instead of a singular float. 2 for 1! Only use it for a single type of operation though, as the input will affect both output and outColor.
remapColor and remapHSV (which I’ve honestly never used) are variant of the same thing. Ignore the naming — in maya nodes, color is often a good substitute for vector. Also watch out! For some reason, the Channel Box only contained a limited number of the channels in the node.
Usage:
Have a linear value — say the output of a poseInterpolator needing to be converted into a transform-type value? Say 0 is translateX: 0 on your output, but 1 is translateX:20, and you want the interpolation to be smooth, not linear — this is a good way of doing that.

Set Range

A screenshot of Maya’s Node Editor. It shows the setRange node not connected to anything.
setRange node within Maya’s node editor.

Function:
setRange allows you to remap a range of values to another range, with up to 3 inputs/outputs — allowing you to work with vectors (which transforms, rotations and scales all are!).

A screenshot of Maya’s Attribute Editor for the setRange node. You can see a table of values — 3 rows each. One for value, one for min, one for max and one for old min.
All the channels for the setRange in the Attribute Editor — these can also be viewed in the Channel Box.

Usage:
Do you have a 0–1 range but want to convert it into something strange, like 80–150? This is where setRange comes in. Giving you 3 dimension allows you to calculate vectors or just be cheeky and do 3 operations in one (just try and make sure you’re not fighting Maya’s parallel mode by reusing the node several times in a chain). Also useful for reversing a range.

Clamp

A screenshot of Maya’s Node Editor. It shows the clamp node not connected to anything.
The clamp node as seen in Maya’s node editor.

Function:
clamp is great for setting limits on a number or range of numbers. You set a min, a max and an input. Supports vectors.
Usage:
Although I don’t recommend this (gimbal), say you have a shoulder pad, and you want it to translate up slightly in a linear fashion with a multiply node when the shoulder joint rotates in a single axis but when the arm falls you don’t want it to move at all? This would be a great example of clamp.

Matrix Nodes

Well, we have arrived at matrices. Help us all. But for real — matrices are excellent because they contain the full transform of a node — knowing how to use them is super powerful and will help you overcome all sorts of problems like gimbal and scale issues. Let’s go over some of the simpler ones.

A screenshot of Maya’s Node Editor. It shows the composeMatrix and decomposeMatrix nodes not connected to anything.
composeMatrix and decomposeMatrix as seen in Maya

Function:
composeMatrix gives you the ability to create a matrix composed of a node’s translate, rotate, scale and sheer. This is useful because Maya doesn’t always let you access the matrix of nodes.
Similarily, decomposeMatrix does the opposite. Takes a matrix and turns it back into translate, rotate, scale and sheer. This is especially useful as maya likes to use matrices to exchange information, but doesn’t often let you see the matrices themselves (for example, in a matrix, you can extract single vectors or the position of a transform).

A screenshot of Maya’s Node Editor. It shows the addMatrix and multMatrix nodes not connected to anything.
addMatrix and multMatrix as seen in Maya’s Node Editor.

addMatrix lets you add x number of matrices and gives you the sum as an output.
multMatrix multiplies x number of matrices and gives you the multipied output. Does what it says on the tin.

A screenshot of Maya’s Node Editor. It shows the inverseMatrix, fourByFourMatrix and transposeMatrix nodes not connected to anything.
inverseMatrix, fourByFourMatrix and transposeMatrix as seen in Maya’s Node Editor.

inverseMatrix is useful for calculations involving hierarchies. For example, say you want another node to drive it as if it were in a hierarchy — ever seen parentInverseMatrix being used in constraints? This is where this node will come in useful.
fourByFourMatrix lets you full construct a matrix from single values, then outputs the new matrix.
transposeMatrix…is a little out of my depth for my matrix math right now so I’ll let Google answer for me. ‘The transpose of a matrix is simply a flipped version of the original matrix’. (from mathinsight.org).

A screenshot of Maya’s Node Editor. It shows the pickMatrix and pointMatrixMult nodes not connected to anything.
pickMatrix and pointMatrixMult as seen in Maya’s Node Editor.

I’m now venturing into unfamiliar territory but figured out I might as well mention the other matrix nodes. At this point, I’m just going to paste what Maya’s documentation says — because I honestly would be making it up as I go otherwise.

Will Telford explains Maya’s pickMatrix node here, but the documentation says: Pick element of a matrix (scale, translate, rotate and shear) and build a matrix only with the selected one.
pointMatrixMult is used to ‘multiply a point by a matrix’

A screenshot of Maya’s Node Editor. It shows the blendMatrix and aimMatrix nodes not connected to anything.
blendMatrix and aimMatrix as seen in Maya’s Node Editor.

blendMatrix takes a base matrix (InputMatrix) and blends it successively with each target. Here’s a video demonstrating how it can be used to create a pole vector.
While I’ve personally not used this, I imagine an aimMatrix is a great replacement for the old Maya trick of using an aimConstraint to make deformations controlling or controlled by rotations a little less problematic. Often used in twist calculations, and explained quite well here by Jørn-Harald Paulsen.

Doing a little Googling brought me to some more articles if you wish to learn more about this stuff — already covered by some other folks who understand it better than I can explain here.

Brendan Kelly — Maya’s native matrix nodes

Vasil Shotarov — Maya matrix nodes — Part 1: Node based matrix constraint

Note: a lot of the newer functions in Maya introduced in 2020 are explained very well by Will Telford here and are worth checking out as it includes the Matrix changes.

Finally, if you like playing with fire — or don’t want to deal with full matrices just because you hate gimbal — there are some Euler to quaternion nodes, and a whole bunch of quaternion math nodes available for your pleasure (or pain)

A screenshot of Maya’s Node Editor. It shows the quatToEuler, eulerToQuat and axisAngleToQuat nodes not connected to anything.
axisAngletoQuat, eulerToQuat and quatToEuler in Maya’s Node Editor.

Finally, I know this doesn’t cover it all — there are a million ways to drive connections and create relationships between transforms and values in Maya — but hopefully this is a small taste and intro to what’s available out there! Good luck and happy rigging!

Ultimately if you enjoyed this and got this far, perhaps consider throwing my some spare change to feed my addiction to cats, Pokémon or cat-like Pokémon?

Tip-jar: https://ko-fi.com/solhappening

--

--

Sol Brennan

A rigging artist working within the games industry.