A New Take on Shape Keys
Sep 7th, 2007 by admin
The Peach Project is thinking about Shape Keys, and as I’ve been giving it some thought and doing some preliminary coding on this myself, I thought I’d share:
The Problem
When doing my own work with facial animation and shape keys, I came across a serious shortcoming which also presented a solution.
The problem, from an animator’s standpoint, is this: when a real face changes shape from, for example, a smile to a frown, all the parts of the face do not move in concert. Just like different parts of the body precede or follow the main motion of an action like throwing, so too do the portions of the face work together, but at different rates, to form expressions. So, a smile is not a static shape. It is the combination of differently timed changes that lead up to and fall away from a pose in a moment in time.
To ignore this is to have faces that move and change expression in an all-at-once, unnatural way.
Clearly, you could create a facial expression as a whole shape key, and then, using vertex groups, break it into component parts and animate them separately each and every time you wanted to change expressions. Just as clearly, this is not an ideal solution.
One proposed remedy to this problem is the use of an NLA-like system for stacking, sliding and controlling shape keys. While this would be an improvement, I think that a more intuitive interface is possible.
Expressions
What we need is some way to create and manage entire sets of shape key Ipos. A full Ipo could be created, for example, for a smile with the different shape keys interacting over time to give a believable build-up to the final expression. This Ipo can then be unlinked from the object, and a new one attached and created for a frown, a look of surprise, or for smaller more localized activities like an eye twitch or lips pursing.
After these shape-based Ipos are created, they can be linked back to the object in a new interface panel (or window type), based on “Expressions.” An object’s Expression is a link to a list of Expression Channels. Each Expression Channel contains a link to a full shape Ipo as defined above, information on the sample range from within that Ipo (start and end frames), and a control slider (or dial) and linked implementation Ipo to store the slider’s values over time.
This allows you to easily keyframe entire developing expressions, going so far as to adjust their timing by tweaking the implementation curve for that Expression Channel’s control slider, just like the Influence keying on Constraints.
The main benefit to this system is that once it is set up, you are animating with simple controllers and common keyframes and Ipo curves, with immediate feedback in the 3D view, but instead of blending from simple shape to simple shape, these keyframes are controlling more complex and (hopefully) more nuanced and realistic character performances.
An Expression/Expression Channel implementation is more suitable to an animator’s shape keying workflow than an NLA approach, especially for facial animation. With a slider (or dial) based system, animators can easily tweak timing and expression on-screen, while they view and work with poses in the 3D view. A strip based system presents an unnecessary level of abstraction, requiring the animator to either work with numeric panels or perform transforms (scale/translate) on a strip to fine-tune facial animation.
For the purposes of time syncing with other NLA-based animation, the Ipo’s generated for Expression Channels would be capable of becoming Actions (Object Actions), and therefore placeable and scalable in the main NLA window.
Conclusion
I’ll be soliciting feedback on this proposal from some animators as well as coders. From a coding standpoint, this is not a difficult project, especially if the programmer is already familiar with the code for the shape key system. I have DNA structs already built for the project, and am reading my way through the shape keying code right now.
Follow Up:
After some discussion with other developers and users, I think that something like this can be implemented with a more general modification to Blender. Although you really have to jump through hoops to make it happen, you can save different sets of shape transformations as Actions. Actions can be arranged and stacked in the NLA Editor. What we would need to effect something like this would be the addition of an Ipo block to NLA Strips that would allow you to key for both Time and Influence. A more general approach like this to the internals would not only benefit shape keying, but give animators and riggers a whole new level of control and automation.
Of course, the NLA interface is less than ideal for a straight-ahead animation workflow as is so often used when working with shapes. However, a simple control setup could be created with Python, or Ipo drivers could be used. That would let people play around with interface elements, and, if people used the system and one setup emerged as clearly superior to the rest, it could be codified in the sources.
Currently the shapekey combination (aka vertices being moved by several shapekeys at once) only adds deformation giving weird results. Let’s say you organize your keyframing in expressions or whatever, what you need is a way to blend transparently all these shapekeys. I rather not use shapekeys for facial deformation more than adding a little extra thing or for lipsync. Instead I use lattices, which give smooth deformation and somehow gives you the feeling of actually working with skin and muscles in the face.
Your idea to me sounds like overcomplicating things, I would like the idea of creating facial expressions and mixing them up in NLA if weren’t for the fact that NLA is pretty useless most of the time for real quality character animation. When animating I go from one facial “pose” to the other in one unique action, this is fast and clean. Otherwise I can only think of spending long time setting up expressions and in the end thinking they look too repetitive.
Best regards !
malefico
love the video-effect on the duck.
.b
In some of my (as of yet unpublished or coded) experimental concepts for the evolution of the NLA system, I’ve got the following in mind:
* Each NLA-strip (shapekey or otherwise) basically gets two IPO curves which control how this strip interacts with the other strips
– Time: For each frame, the time IPO is checked to see which frame from the source-action should be used
– Influence: For each frame, the influence IPO is checked to see how much the data from the source-action should be applied
* All of the existing blendin/out, start/end range, etc. stuff basically become parameters which are used to create parametric versions of these curves (using IPO-Modifiers)
I agree with malefico about how this system you mention sounds a bit on the complicated side.
Heh. If you notice the “Follow Up” at the bottom of the post, that was exactly what I was suggesting! Both a Time and Influence Ipo for NLA Strips. I had started coding it myself, but got busy with something else. If you’re doing the same thing, awesome! And the fact that we both came up with the same solution gives me good confidence.
The rest of the discussion in the earlier post is really implementation and interface work, suggesting a way that this can be put to use, but as I mentioned in the follow up, with Ipos attached to NLA strips, Python can take over for interface experimentation.