Skeletal animation

From Tech Artists Wiki

Jump to: navigation, search

Contents

Introduction

Skeletal, or bone, animation, is the most common type of animation in 3D games. It works the same way ingame as it does in a DCC app, with restrictions. Starting from the root of the hierarchy, it transforms each bone down the hierarchy. Traditional skeletal animation behaves strictly in this FK manner, though new techniques, such as IK and physics-driven bones, are increasingly common.

What is a bone?

See main article: Bone

It is important to understand that, although many 3d programs have dedicated bone objects that often have special settings, a bone to a game engine is simply a transform in an hierarchy. Lights, cameras, even particle systems could be used as bone objects, if the exporter is set up to handle it- all the game wants is the parent (either as an ID or a name), and the transform. The transform is stored a 3x4 matrix.

In the DCC App

The only requirement for skeletal animation is a true hierarchy- all bones to be exported must be parented to their actual parent, not constrained, and not parented to a point helper that is then parented to the parent. Each link in the chain is exported as a bone, so there should be nothing superfluous. For this reason, game rigs are usually built on top of the actual skeletal rig, and constrained to them. That way, the rigger has all the flexibility and tools required, while it has no bearing on the actual skeleton that will be exported. And alternative is to dynamically create an export rig and re-skin the objects to it.

Exporting and Compression

Exporting techniques will vary with each animation toolset, but a key component is animation compression. Some pipelines may have a middleware solution for animation blending/state trees, in which case the animation will usually be exported uncompressed (a key per frame). If the animation is to go straight into the game, the exporter will use either motion filtering or key filtering to compress the animations. Either way, if the artists are doing the exporting, they should understand the options and what they do, but on many projects, the exporting and compression will be left to technical artists/animators.

The end result of a compressed animation is a selective number of keys (not necessarily coinciding with original keys) of the transform for each bone. On more highly compressed animations, the keys will be less, while with less compression, there will be more keys.

Motion filtering

Motion filtering is an arbitrary sampling of the animation curves of a bone, not necessarily on the keyframes. This gives the exporter more freedom in deciding compression since it can do things between frames, etc., whenever it finds appropriate points and tolerances.

Key filtering

Key filtering will remove redundant adjacent keys along an function curve, and remove adjacent keys within a certain threshold or tolerance. This results in a key reduction scheme that is similar to those found in animation programs.

Skeleton

Along with the animations, there needs to be a skeleton to play them on. This skeleton needs to have matching bone ID's and/or bone names. The actual placement of the joints is usually irrelevant to whether the animation will work or not, but to play as intended, the animation skeleton and the model skeleton should match. Often times, however, playing the same animation on multiple skeletons will work acceptably (but keep in mind, if the Center-of-Gravity root bone changes height (meaning the legs grow or shrink), the unintended character will float in the air or sink in the ground.

Everything is Relative!

Remember that with bones, everything is relative to the parent, ie in Parent Space. Positions are offsets from the parent- X is usually 'down the chain' while Y and Z point to the sides (true even in Z-up programs like 3dsmax). Rotation and scale is also relative to the parent- if a root scales by 1.5 in the XYZ, its children will scale by the same, but maintain a transform scale of 1. Transforms are passed down the chain/inherited.

The parent of the root node is the world, thus, the root is in world space.

A Note on Scaling

There are two types of scale- uniform and non-uniform scale. Keep in mind that transforms are passed down the chain- if you scale a bone, you will scale its children. Uniform scale is fine, however, since it will just change the transform in unison. Non-uniform scale, however, will leave to shearing in the children. This shearing effect is rarely desired, since it is impossible to control correctly. However, for muscle bones, etc., non uniform scale may be desirable- in this case, simply make them a childmost bone (no children), and scale and them to your heart's desire.

Many 3d programs/rigs may hide the 'true' effect of scale and shear. To see them for yourself, make a hierarchy of point helpers in your 3d tool and scale, shear, and rotate.

Transforming on the CPU

By the time the CPU gets the animation data, it is a list of bone ID's and their keys.

Key Interpolation

In 3d programs, the goal is key efficiency- using the minimum keys possible to allow ease of animation and adjustment. The animator has tools, such as numerous interpolation techniques, to achieve this. However, when using real time, it is much more expensive to calculate this interpolation than it is to store multiple keys to achieve the same motion. For this reason, most game engines use linear interpolation of key data. We can think of an interpolated range of keys as a new function curve.

For each frame, the CPU must sample the curve, and take the transform. It then transforms the bone (in parent space!). Because all transforms are in parent space, all bones down the hierarchy are also transformed. It does this all the way down the chain, to the end.

There is no true limit to how many bones can be in a skeleton, the CPU can transform as many as needed. There are, however, practical (soft) limits which your programmers must decide. Also, if the engine is going to use Hardware Skinning (as all modern engines do), only 4 influences per vertex can be stored.

Skinning

For detailed info, see Skinning.

Skinning is the relationship of vertices to bones. A vertex weighted .5 to a bone will get 50% of its transform- however, that does NOT mean it will go on an arc for half of the degrees of rotation. It will essentially end up halfway along a line drawn from the original vertex position to its 100% weighted spot. Which means, if a bone is rotated 90 degrees, a vert 50% weighted to it will end up along the hypotenuse of the right triangle formed from its original position and its rotated position. An image will better demonstrate:

Skinning is handled either on the CPU or GPU.

After skinning, the Skeletal animation pipeline is complete- all that is left is the rasterized scene to render.

On the CPU (Software Skinning)

CPU skinning was common in the early days of 3D and before Shaders. Software skinning is just performing the Skinning process on the CPU. The downside is that CPU's work in a linear fashion, which takes time- they must do one vert, then move on to the next, etc. If skinning is done on the CPU, the resulting vertex position is passed to the Shader.

On the GPU (Hardware Skinning)

The GPU is a parallel processor, which makes it great for handling skinning. Each vertex doesn't care about the other vert, so it can handle many verts at the same time (unlike the CPU which must go one at a time).

Most, if not all, modern games use Hardware Skinning. It is extremely fast and the Vertex Shaders in most games are almost never the bottleneck.

Personal tools