Lately, I've been learning a lot about rigging faces with shapes. Here are some shots of my latest project:
My next picture is an example of a common problem when rigging with face shapes. It's what happens when you turn on the blink shape to a value of half.
Shape blending moves the affected vertices in a straight line, and so they crash through the round eyeball mesh, instead of flowing around it.
This tutorial will show you how to do a shape blending technique called "quadratic interpolation" which allows the affected vertices to move along a curve. Best of all, this technique also maintains a firm control over the eyelid's shape.
I'll be explaining how to use this technique in Blender 2.65, but it could work in Softimage, Maya, or any other 3D software with blend shapes. I'll be assuming you already have a general understanding of how to use Blender.
This technique involves quite a bit of math, so I'm going to break this tutorial into two parts: part one will provide basic step-by-step, math-free instructions; part two will explain the math for those who are interested.
PART ONE – The Math-Free Instructions
Below is a video containing a straight-up demonstration how this technique works.
In it, I rig up a blink for my character "Alto" from my animation Trio Animato.
If you can't handle the video's wacky klesmer music, you can read the step-by-step instructions below.
Open up Blender, and load one of your characters. Make sure that there are enough loops surrounding the eyes, for them to be modified into a blink shape.
So, that's it! We're done! Try it! Slide the "Blink" parameter between values of 0 and 1, and your character's eye should now blink along a smooth, curved path.
PART TWO – An Awesome Pile-Of-Math
This technique uses quadratic splines, so we first need to understand what they are, and how they work.
What is a quadratic spline? Well, imagine that you draw three points in space, P1 = (x1, y1), P2 = (x2, y2), and P3 = (x3, y3). You want to connect these three points using a parabola. You can do this with a quadratic spline.
That's cool, but how do they work? Well...
We will define a curve P(t). We want this curve to trace a parabola as t increases.
We also want the curve to pass through the three points we drew. Say we wanted P(t) such that:
P1 = P(0)
P2 = P(1/2)
P3 = P(1)
In other words, as t varies from 0 to 1/2 to 1, P(t) will trace a parabola, hitting the points P1, P2, and P3 along the way. These three points are knows as the "control points". What does P(t) look like mathematically? Well, something like this:
P(t) = a2t2 + a1t + a0
The curve P(t) is a second order polynomial in t, with three constants, a2, a1, and a0. If can we find the values of these constants, we will have everything we need to know for P(t) to work. We can solve for the constants by plugging in our previously chosen t values.
P1 = P(0)
= a2(0)2 + a1(0) + a0
P2 = P(1/2)
= a2(1/2)2 + a1(1/2) + a0
= a2(1/4) + a1(1/2) + a0
P3 = P(1)
= a2(1)2 + a1(1) + a0
= a2 + a1 + a0
We now have three equations and three unknowns. If you remember your high school algebra, it shouldn't be hard to solve for a2, a1, and a0. If you try to solve it yourself, you should get:
a0 = P1
a1 = -P3 + 4P2 - 3P1
a2 = 2P3 - 4P2 + 2P1
Great! If we take these values and stick them into our definition of P(t), our problem is solved.
P(t) = (2P3 - 4P2 + 2P1 )t2 + (-P3 + 4P2 - 3P1)t + P1
This equation describes exactly what we wanted: a parabolic curve which passes through points P1, P2, and P3 as t varies between 0 and 1. Try it! Set t to a value between 0 and 1 and see what you get.
Using the above equation, we can parametrize the movement of a single point P(t) along a parabola. Shape blending in 3D software can be manipulated in the exactly the same way. The only difference is that instead of blending a single point along a parabola, we're blending hundreds of points each along their own individual paths. Say you had three shapes, S1, S2, and S3, and you wanted them to blend together such that each vertex follows a parabola? Well, we just do the same as we did above.
S(t) = a2t2 + a1t + a0
and we'll constrain S(t) such that it uses three "control shapes",
S1 = S(0)
S2 = S(1/2)
S3 = S(1)
After solving for a2, a1 and a0, we should have the analogous result:
S(t) = (2S3 - 4S2 + 2S1 )t2 + (-S3 + 4S2 - 3S1)t + S1
Now let's re-arrange this equation into a more useful form.
S(t) = S3(2t2 - t) + S2(-4t2 + 4t) + S1( 2t2 - 3t + 1)
Let's take a moment to realize the sheer awesomeness this result contains! Say you have a character with three shapes. If you take shape #1 and scale it with the value ( 2t2 - 3t + 1), scale shape #2 with the value (-4t2 + 4t), and scale shape #3 by value (2t2 - t), you will get S(t)! Changing the parameter t between 0 and 1 will cause the character to morph smoothly from shape #1, then #2, then #3! Simply create a custom parameter to store the value of t, and use it as an input for the above scaling factors.
You can now understand where I got my number settings for my shape drivers. I wanted to interpolate from the basis shape (S1), through the "half-blink" shape (S2), and end at the "blink" shape (S3). I therefore multiplied the "blink" shape with a second order polynomial of the custom parameter, using coefficients 0, -1 and 2, to produce (2t2 - t + 0). My "halfBlink" shape was likewise scaled with (-4t2 + 4t). As for S1, my basis shape, I didn't need to do anything because the basis shape is the undeformed shape, which is mathematically equivalent to the "zero" shape. S(t) therefore doesn't depend on the values that multiply S1.
So, that's it! You've used quadratic spline interpolation to get a curved path for your shapes!
I hope this has been useful!