I had originally intended to release this all a bit later once I had a few more key pieces in place, but, inspired by Raf Anzovin's enlightening blog, Daniel M Lara's Easy Rigging stuff, the exciting developments in the VR-based animation space, and also the 2.8 code quest, I decided to put this out earlier.
In this article, I'm going to try to "throw the ball further" (as Emirates Team NZ would say) and take a more comprehensive view of where we need to going in the medium to long term, as well as what steps we can take now.
(NOTE: I originally started writing this article in NZ, but in between preparing a new laptop for travel, and travelling to/settling in Amsterdam for Code Quest, I've only had time to really work on finishing this in the past day or so).
1) Ground Rules - What are some of the big issues we face?
First up, what exactly is "wrong" with the current state of animation tools? In no particular order, here are a few:
- "Production Quality" rigs are hideously complex. "BlenRig" (by JP-Bouza and used in all the recent Open Movie projects) is a prime example of this (sorry JP, no offense intended). Some of this is perhaps a symptom that there's stuff that the core system isn't doing (otherwise, you wouldn't have needed to chain up a whole bunch of bones to do it), while others actually call into question our assumptions about what a rig should be, and how we should actually be managing cases where rigs effectively have different modes. (In this regard, the more I learn about what people in stop motion are doing, the more I realise that we may be over-complicating some things). Some of the big conflicts we have here are:
- The tradeoff between having a rig that is "easy to keep on model + quick blocking" vs "need for applying fine tuning" - On one hand, animators want to able to have fine control over the final shape of everything (to get the perfect pose/silhouettes/shapes), while on the other hand, you don't want to have to work with too many controls straight out of the box (or else, you'd go slowly mad).
- The need for different configurations of the rig, to suit animation in different setups. For example, this includes stuff like IK/FK switching, pivots/parents, and even the directionality of chains. As Raf pointed out recently, all of this imposes a layer of additional cognitive overhead in trying to figure out how to get the pose you want, vs just going in and manipulating the character into shape.
- Technical issues solving all the constraints and counter-correcting rotations/etc. to get the desired poses complicate matters, when the user may only be thinking about adjusting a set of points. On sufficiently complicated rigs, it can be nightmarish trying to fight the constraints to give you the desired pose.
- Viewport clutter + Complexity of Learning New Rigs - Learning to work with the rigs for a particular show may often end up being like learning a whole other program on top of the basic animation software. In contrast, 2D artists can effectively learn to draw once, and then, they can draw whatever they want, using just the basic tools they have.
- Character prop interactions in Blender are somewhat complicated by the Object/Armature split, which causes challenges when animating props that need to be in contact with different characters at different times. Often, TD's currently have to resort to dumping the rig for every single prop a character may ever encounter during the project into the main character rig object, further complicating/weighing things down.
- For the ultimate test of hand/finger interaction with a length of string, I've dreamed up a little short film. See here for details.
- Perhaps we could have tools to reflow timing / edit multiple frames simultaneously / etc. However, to implement these tools, we would need to be able to
- Applying "other motion sources" (e.g. physics sims) to an existing animation, to add some extra detail/depth. See physics sims notes below.
- Cleaning up and "enhancing" motion capture animation.
- Perhaps we could have an even more experimental approach, where we instead focus on allowing animators to define the motions they are trying to achieve - i.e. the paths traced out, speed/acceleration and direction of movement, and the overall "scope + energy" of the movements. For instance, this could work well if we made this a two-step process, where
- Animators first define the poses they want to hit (as they do now), using whatever precision plotting/placement tools work best
- Then, we combine a mocap-like approach (e.g. similar to the "performance based timing" tools that were demonstrated at BConf a few years back) to let animators craft the transitions in an easier and faster manner.
- Defining "action transition graphs" or things like that where you can define a node graph describing how different actions can be linked to others. With suitable tool support, you can then test how different clusters of animations flow together and interact with each other as they would in a game engine/simulation, allowing you to check how well everything fits together.
- Letting such ATG graphs be used to power crowd/particle simulation behaviour, and for other things too where you want to again work in a more declarative way (e.g. demolition/fracture/etc. physics sims, where you can build in behaviours that should be triggered under different conditions)
- Improving standard bone-skinning (especially around things like elbows). Things like the Bone Glow and Implicit Skinning approaches easily come to mind here, as this is a problem commonly tackled by academic researchers.
- Finding new ways to rig fat/blobby/flexible "mass deforming" volumes - The Mesh Deform Modifier approach is already an important part of many fancy rigs, but things can still be a lot simpler. For instance, the mesh deform modifier still ends up needing a whole bunch of helper bones (i.e. one per on-the-go heater/access you used). What if we could deform rigs without needing those mesh deform cages?
- "Muscle" Systems - TBH, I *still* don't really know what exactly people mean when they say they want a "muscle system". What exactly does that entail? I mean, are you after a simulation of skin/flesh volumes moving over some solid/hard/fixed shell (e.g. face shapes sliding over the skull), or is it all about physics sims adding little bits of jiggle whenever things change?
- Non-Hookean deforms, etc. - <insert latest buzzword/super-solution here> :P
- Note: For Blender, it was always intended that the NLA system would act as a bit of an Animation Layering system. What's currently missing to support this is some internal code to keep track of all the channels that are currently being animated, what values they have, and a way to set/control what the default values for these channels will be (i.e. when they are not being animated). Since this is such a frequently asked question/request, I thought I'd address this up-front here.
2) The Role of the Rig
As mentioned above, I'm increasingly leaning towards pursuing/pushing the Blender rig style towards some of the ideas being presented by Raf. Specifically, the key takeaways from this are:
- Undirected or Bidirectional Bones, without a fixed hierarchy baked the rig. Instead, everything becomes more focussed on just transforming points (i.e. joint positions), which is generally simpler to work with in general.
- Allowing riggers to define multiple "manipulation convenience modes" - dynamic hierarchies/groupings/selections to accomplish a lot of the things like IK-FK switching / switchable pivot points / etc. that seem to be a major pain point. From a rigger perspective, they might still be defining heaps of crazy setups and so forth for giving animators different control schemes. The difference though, is that less of this is baked into the evaluation of the rig (i.e. not all of these components need to get evaluated on each animation step/update), with the calculations for different rig components only really happening when you go to edit. (The only challenge is how we optimise all this enough that interactivity while editing won't suffer too much)
- Reducing the importance / hold that "interpolation" has on the way we approach things - While we probably cannot do without it entirely (i.e. even things like the breakdowner are still very much dependent on the endpoints being able to interpolate nicely, in order to choose nice in-betweens), there's a lot to be said about how our need to be able to always interpolate between one state to another causes a lot of headaches.
- "Mix-Ins" for Rigs - That is, in a shot file, you can mix and match different prebuilt "rig components" into your rig to customise the functionality you have available in a particular shot file. (To be clear, these "rig components" can either be rig elements that are bundled with the default Blender distribution - much like Rigify - or perhaps they could be assets provided by the wider Blender community, or they may also be shot/show-specific rigs that were designed by a production's rigging team to deal with certain character/shot specific requirements).
- IIRC, I mentioned something like this a few years ago in one of these posts (or maybe in a reply to someone's comment). The idea came about in response to the challenges with sharing props between characters, when I started pondering the viability of allowing artists to dynamically "fuse" several different rigs within a shot file as needed (e.g. Frank and the rope rig from Cosmos Laundromat couldn't been done this way instead).
- Thinking more about this now, this can also be useful for allowing riggers to provide different configurations for different shot types in a more modular way - in effect, replacing the current mindset of "the rig always contains all the modes for all different situations", to allowing a more freeform "we can easily switch out the arm/spine/face rig with something that works better for this specific shot"
- Quick "On-Model" Posing/Blocking vs Fine-Grained Control over Final Shape - Closely related to the previous point is the tension between having the rig to allow animators to quickly block out poses (and having the results stay "on-model"), versus the need that animators often have of being able to have fine grained control over the shape of the deformed meshes (necessary for achieving particular silhouettes and shapes to satisfy particular aesthetic requirements).
- On current rigs, this is often achieved by having multiple tiers of controls - larger/rougher controls that provide the broad/coarse control needed to quickly block out a shot, and then a network of smaller controls (often starting to approach grid-like coverage of the geometry in places) providing animators with the ability to tweak the shapes with a high degree of control (while not having direct control over specific vertices still).
- On the Aardman films, these tradeoffs were managed by largely building the puppets from relatively rigid latex parts for the less flexible-but-quickly-poseable parts (e.g. arms, legs, torso's) and using more malleable plastacine on all the places where animators need fine control (e.g. eyebrows, around mouths, and in one shot, the entire torso) with the understanding that although animators would take longer to work on those shots, they could also have a much higher level of control/flexibility to do as they needed to.
- Extrapolating from these ideas, we could make it easier for animators to achieve fine control over rigs by perhaps allowing direct manipulation of rig geometry in certain areas. We could make such rigs intuitive by defaulting to using a sculpt focussed, (visible)-controller-less setup. That is, to pose the characters, animators use a sculpt-based approach to pose the character geometry, then, by using facemaps and/or more geometry/mesh specific sculpting tools, the more malleable regions can be hand sculpted with a greater degree of control.
3) Evaluation and Editing
In the past, I've always been somewhat against the use of evaluation caches. My main concerns about these center around the memory requirements (i.e lots) and overall code complexity (i.e. you have to keep these things in sync and/or manage invalidation events, etc.). Both of these are known to be fairly technically tricky problems to get right (and to a certain degree, cannot ever really be "perfect"). That said, my current position is evolving. As Pixar (with Presto) and Dreamworks (with Premo) have demonstrated, it is probably necessary and even beneficial to now be caching geometry, allowing for faster playback without the hassles of trying to evaluate all the geometry in real time, and worrying about low performance/framerates due to all the constant duplicate recalculation of things going on.
What sort of benefits would caching stuff on each frame have? Well, judging by how much easier it often is to edit Grease Pencil data (well, before a lot of the layer parenting and object transform stuff was added), and also the growing popularity of geometry caches (e.g. Alembic) in big production houses), it's reasonable to assume that caching the animation rigs/geometry would allow us to do a lot of currently-hard things much easier. For instance, the following things suddenly become easily feasible/doable:
* Multi Frame Editing of armatures (just like with Grease Pencil) - Maybe there'd still be some complications, but it'd be a lot easier than now
* Onion Skinning for animated meshes - This would become feasible, as we wouldn't get bogged down with evaluating n+1 frames for each frame drawn, greatly simplifying/speeding up the whole process! Of course, there are physical limits to how much performance we could get (since we're still rendering n+1 copies of the geometry), but all of a sudden, it all becomes possible to do!
This note leads us nicely into our next big area...
4) Editing Motion Across Time
By and large, all animation tools these days are currently focussed around creating and editing a single frame's state at a time. This is largely a consequence of the hardware limitations in place when much of the major software packages used in the industry were first created. However, there have been massive advancements over the past few decades in terms of raw computing power and also availability, meaning that it's time to re-evaluate whether we can be making our tools do more for animators!
First, let's remember that animation is all about motion - or change over time. However, our tools don't do a great job at helping us do this. Instead, they're more orientated towards creating a series of still images! This is because we've currently got effectively two ways of working with our data:
1) Isolated snapshots of the state of the scene at particular points in time, but with the ability to view/edit this in full 3D, and
2) Abstract views of the timing/change data, but only in 2D, and in a separate view, represented separately from the stuff it's affecting
What we really need is a way to have tools that can work across time (i.e. on a wide range of frames). The current single-frame behaviour then becomes like a special/sub-case of this more general approach. For instance, one thing we could do is that instead of having a "current frame" indicator in the timeline that looks like a line, we could instead have a "multiframe range" indicator - a box with start/end range controls + a "current frame" control/line within that range (see mockup below) - that could be used for both multiframe editing and/or visualising the Onion Skinning range:
There are several options I'm particularly keen to explore:
- Motion Sculpt (3D) - Using sculpt tools to apply time contraction/expansion/smoothing effects to motion path points
- Time Expansion/Contraction - The basic idea here is that the brush would simply adjust F-Curve handles and/or keyframe spacing so that more/less frames are allocated to parts of the curve around the keyframes where the brushes were used
- Path Smoothing - Instead of going in by hand to try to reduce kinks, perhaps it'd be worth seeing if we can find a more general/semi-automated solution?
- Performance-Based Timing - Given a set of keyframes, we record the speed of the animator's mouse movements as the trace out the path, using this info to adjust the spacing/timing of keyframes. (This is similar to a presentation at BConf a few years ago). In essence, this approach lets us combine the best of both the motion capture world (i.e. dynamic performance/energy capture), vs retaining the precision of traditional keyframe animation control.
- Motion Stencils / Effect Masking - Using sculpt tools to "paint" animation from one source onto a character. In particular, several key examples of this include:
- Painting Ragdoll Physics Sims onto body parts - The idea is that you can "paint" ragdoll physics sim effects onto bones to get nice secondary motion effects, and/or realistic "relaxing/settling/contact" with less effort than running a full sim, or hand animating the effect yourself. This way, we can allow animators to make more use of physics sims to help create an initial rough version of some fiddly physics-based effects (e.g. hair blowing in wind, or accurate hand-object contact) and still be able to "art direct" the effect. (From the Spring weekly's, this sounds like something that could be quite useful for animating Spring's hair strands for example)
- Painting Motion Captured data on to another rig - The process of cleaning up motion capture data is often a matter of taking what works from the original performance data, ignoring noise/floaty stuff, and then adding our own hand-animated stuff on top. A stencil/masking approach may be a useful interface for allowing animators to be able to filter down the key parts of the performance much easier. We could also develop this further to include stuff like the Push/Relax pose tools into this, to help exaggerate/dampen aspects of the performance we're masking.
- Selectively mask/paint effect of Breakdowner/Pose Library Tools onto bones by different amounts - Currently the Breakdowner/Pose Library tools get applied to all bones by the same amount. However, what if we could use a paint/brush approach to control the influence of these tools regarding how much they affect different bones? For example, being able to selectively paint a "smile" or "frown" expression on to parts of the character's face, instead of having the full pose applied each time (or having to select different bone subsets first).
- In-Viewport Falloff/Drag Animation - See the Grease Pencil demo for details
- Adjusting the pose of a body part/prop that doesn't move that much/far over a wide range of frames - By selecting a range of frames and then selecting the controls of interest across those frames, we could modify that pose across all frames, instead of having to use something like the Pose Propagate tool to do so. (As nice as Pose Propagate is, it is still a bit of a mystery to users in some situations - particularly regarding what keyframes it will or will not affect, since it has to guess what is a held pose vs what is an actual "real" pose it shouldn't try to clobber).
There is also the matter of Onion Skinning. To implement MultiFrame Editing, we'd need something similar, so we'd need to eventually develop some solution to this problem. So far, we haven't implemented Onion Skinning as it would largely be prohibitively expensive to do so (i.e. we'd be evaluating some n+1 frames of data each time we want to draw a single frame!). With the work on the Depsgraph (faster evaluation, with the option of doing it in the background) + a move towards embracing geometry caches (e.g. Alembic caching of animated meshes as a general rule, instead of an obscure hack for certain tricky situations), I think it might be possible to easily solve this! That's because instead of having to recalculate things all the time at draw time, we'd now be able to cache off the geometry (i.e. watch any Presto demos, and watch how it recaches the entire timeline, current frame outwards, upon any change being made), meaning that the drawing of the onionskins can potential be a lot faster (i.e. simply a matter of streaming the relevant geometry and rendering it with an appropriate shader). Possibly the main technical issue we have here relates instead to how we're rendering the geometry (i.e. what shaders we use) - specifically, we want a shader that lets animators see the silhouettes of the character shapes, instead of being bogged down with weird glitches in all the places where the mesh intersects itself. One of Raf's blogposts touched on this - the solution he came up with (i.e. showing just an outline silhouette) is an interesting approach; I'm not sure yet about the relative merits of that approach though.
*) Small improvements to commonly used workflows/tools we can begin doing now
There are a raft of smaller technical issues (Blender-specific) that need to be resolved before we get into all these other things. For example:
- Animation Filtering API - Over the past few weeks, I've been doing a bit of planning/investigation work on putting in place Python API support for accessing all the animation channel api's that are available internally for working with animation data. Among other benefits are:
- Finally you'll be able to use the same nice stuff we use internally (instead of having to roll your own) to create some new specialist editing tools,
- It'll be easier to create addons to support keyframe editing in the Timeline - I'm still not keen on supporting this as a built-in feature given the slippery-slope of feature creep that will happen here, hence why I'd like to first have the community reach a level of consensus about the level/depth of functionality needed here, in the form of an addon, before we look into formalising these.
- Defining start/end points for actions/clips - So, instead of the cycle length for each F-Curve being calculated based on its own keyframes, we define a hard limit for the start/end range of an action, and all the curves in there use that as their reference points for cycling. The main question that this raises though is: why don't we just make animators use the NLA in such cases instead?
- Making it easier to tweak things at the start/end of the cycle (for example, displaying 1-2 keyframes or even the entire range of keyframes for the cycles immediately before/after the "real" ones, perhaps in different colors/faded to make it more obvious what's going on)
- When inserting keyframes beyond the end of the cycle range, we could do one of the following:
- Remap the new keyframe back into the source keyframe range - giving us an easy way to tweak the cycle while previewing it on a long-looping timeline
- Make all the intermediate cycles (between the original range and the current frame) into real keyframes, then insert the keyframe into the latest cycle. The point here is that it would make it easier to animate "transitions" out of a cyclic motion, and/or overlay variations over repeating motion.
- At the very least (and as a first step), it would probably be a good idea to set up a "rig overview" editor to provide an overview of all the drivers, constraints, and modifiers, to help keep track of where relationships exist
- As a next step, we can then decide on more of the semantics - i.e. what sort of nodes to allow, how they connect to each other, etc. One of the big challenges here though is figuring out how to solve the scoping problems (i.e. how many bones/objects do we show nodes for, while keeping everything manageable)
- (Note: The new despgraph should have no problem supporting this sort of thing - the question rather is what effect it may have on our ability to write certain classes of editing tools).
- Popup panel showing the key bits and pieces (e.g. expression, relationship - linear/non-linear + factor, variables), with a button to open the full Drivers Editor. (OR, a "budget" version of this is a just a menu option to open the drivers editor with the driver in question focussed). Sure, this breaks the "non-blocking, non-overlapping" concepts, but we also have the search popups now - ultimately, it may be necessary/best sometimes to have such elements.
- RNA Path Builder Widget - One problem many people have is with figuring out what driver paths they should be using. For a very long time, I've always intended to replace that textbox with either a "breadcrumbs" widget (like you see on any modern file browser), or by retrofitting the property search to support recursively traversing/building up the path. Recently I experimented with the latter approach, but ended up running into some technical difficulties (i.e. we'd effectively have to implement a new set of infrastructure in the UI toolkit, as the existing search gets in our way too much).
With the 2.8 "Code Quest" under way now, you may be wondering what parts of this may end up getting some attention during the Code Quest. As at the time of writing, it's unclear if I'll get time to work on much/any of these things (?), since there are quite a lot of other larger unresolved issues we'll likely have to focus on in the interim.
That said, if/when I get time to work on any of this stuff, it'd likely be the smaller issues identified in the section at the end, addressing many issues that animators have often raised with me. (Of course, given the chance, I'd also totally love to spend the time working on polishing Pose Sculpting once and for all, and spending time with animators refining/developing some further refinements... but, I'm sure we'll end up have other priorities that need addressing first).