It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.

Search articles, jobs, buyers guide, and more.

By Randima Fernando
[Author's Bio]
and Mark J. Kilgard

[Author's Bio]
Gamasutra
March 24, 2003

Introduction to Cg

The Limited Execution Environment of Cg Programs

Particle Systems

Key-Frame Interpolation

Vertex Skinning

Printer Friendly Version
   

Excerpted From:

[More info...]

Change Login/Pwd
Post A Job
Post A Project
Post Resume
Post An Event
Post A Contractor
Post A Product
Write An Article
Get In Art Gallery
Submit News

 


 


[Submit Letter]

[View All...]
  



Upcoming Events:
Workshop on Network and Systems Support for Games (NetGames 2009)
Paris, France
11.23.09

EVA 09 - Exposicion de Videojuegos Argentina
Buenos Aires, Argentina
12.04.09

Flash GAMM Kyiv 2009
Kyiv, Ukraine
12.05.09

Game Connect: Asia Pacific (GCAP)
Melbourne, Australia
12.06.09

ICIDS 2009 – Interactive Storytelling
Guimaraes, Portugal
12.09.09

[Submit Event]
[View All...]

 


[Enter Forums...]

Note: Discussion forums for Gamasutra are hosted by the IGDA, which is free to join.
 

 

 


Features

Animation With Cg

Key-Frame Interpolation

3D games often use a sequence of key frames to represent an animated human or creature in various poses. For example, a creature may have animation sequences for standing, running, kneeling, ducking, attacking, and dying. Artists call each particular pose that they create for a given 3D model a key frame.

Key-Framing Background

The term key frame comes from cartoon animation. To produce a cartoon, an artist first quickly sketches a rough sequence of frames for animating a character. Rather than draw every frame required for the final animation, the artist draws only the important, or "key," frames. Later, the artist goes back and fills in the missing frames. These in-between frames are then easier to draw, because the prior and subsequent key frames serve as before-and-after references.

Computer animators use a similar technique. A 3D artist makes a key frame for each pose of an animated character. Even a standing character may require a sequence of key frames that show the character shifting weight from one foot to the other. Every key frame for a model must use the exact same number of vertices, and every key frame must share the same vertex connectivity. A vertex used in a given key frame corresponds to the same point on the model in every other key frame of the model. The entire animation sequence maintains this correspondence. However, the position of a particular vertex may change from frame to frame, due to the model's animation.

Given such a key-framed model, a game animates the model by picking two key frames and then blending together each corresponding pair of vertex positions. The blend is a weighted average in which the sum of the weights equals 100 percent. Figure 6-7 shows an alien character with several key frames. The figure includes two key frames, marked A and B, to be blended into an intermediate pose by a Cg program.

An application can use a Cg vertex program to blend the two vertices together. This blending may include further operations to illuminate the blended character appropriately for more realism. Usually, an application specifies a single position for each vertex, but for key-frame blending, each vertex has two positions, which are combined with a uniform weighting factor.

Key-frame interpolation assumes that the number and order of vertices are the same in all the key frames for a given model. This assumption ensures that the vertex program is always blending the correct pairs of vertices. The following Cg code fragment blends key-frame positions:

blendedPosition = (1 - weight) * keyFrameA + weight * keyFrameB; 157

The keyFrameA and keyFrameB variables contain the (x, y, z) positions of the vertex being processed at key frames A and B, respectively. Note that weight and (1 - weight) sum to 1. If weight is 0.53, the Cg program adds 47 percent (1.0 - 0.53) of the position of key frame A to 53 percent of the position of key frame B. Figure 6-8 shows an example of this type of animation.


Figure 6-7. Key Frames for an Alien

 


Figure 6-8. An Example of Key-Frame Blending

To maintain the appearance of continuous animation, the key-frame weight increases with each rendered frame until it reaches 1.0 (100 percent). At this point, the existing key frame B becomes the new key frame A, the weight resets to 0, and the game selects a new key frame B to continue the animation. Animation sequences, such as walking, may loop repeatedly over the set of key frames that define the character's walking motion. The game can switch from a walking animation to a running animation just by changing over to the sequence of key frames that define the running animation.

It is up to the game engine to use the key frames to generate convincing animated motion. Many existing 3D games use this style of key-frame animation. When an application uses a Cg vertex program to perform the key-frame blending operations, the CPU can spend time improving the gameplay rather than continuously blending key frames. By using a Cg vertex program, the GPU takes over the task of key-frame blending.

Interpolation Approaches

There are many types of interpolation. Two common forms for key-frame interpolation are linear interpolation and quadratic interpolation.

Linear Interpolation

With linear interpolation, the transition between positions happens at a constant rate. Equation 6-2 shows the definition of linear interpolation:


blendedPosition = positionA x (1-f) + positionB x f

Equation 6-2. Linear Interpolation

As f varies from 0 to 1 in this equation, the intermediate position varies between positionA and positionB. When f is equal to 0, the intermediate position is exactly positionA, the starting position. When f is equal to 1, the intermediate position is positionB, the ending position. Once again, you can use Cg's lerp function to accomplish the interpolation.

Using lerp, the interpolation between two positions can be written concisely as:

intermediatePosition = lerp(positionA, positionB, f);

Quadratic Interpolation

Linear interpolation is good for many situations, but sometimes you want the rate of transition to change over time. For example, you might want the transition from positionA to positionB to start out slowly and get faster as time passes. For this, you might use quadratic interpolation, as in the following code fragment:

intermediatePosition = position1 * (1 - f * f) + position2 * f * f

Other functions that you might use are step functions, spline functions, and exponential functions. Figure 6-9 shows several common types of interpolation functions.

Basic Key-Frame Interpolation

Example 6-3 shows the C6E3v_keyFrame vertex program. This program performs the object-space blending of two positions, each from a different key frame. The lerp Standard Library function linearly interpolates the two positions, and then the program transforms the blended position into clip space. The program passes through a texture coordinate set and a color.

As indicated by the input semantics for positionA and positionB, the application is responsible for configuring key frame A's position as the conventional position (POSITION) and key frame B's position as texture coordinate set 1 (TEXCOORD1).


void C6E3v_keyFrame( float3 positionA : POSITION,
float3 positionB : TEXCOORD1,
float4 color : COLOR,
float2 texCoord : TEXCOORD0,

        out float4 oPosition : POSITION,
        out float2 oTexCoord : TEXCOORD0,
        out float4 oColor : COLOR,

    uniform float
keyFrameBlend,
    uniform float4x4 modelViewProj)
{
float3 position = lerp(positionA, positionB,
        keyFrameBlend);
oPosition = mul(modelViewProj, float4(position, 1));
oTexCoord = texCoord;
oColor = color;
}

Example 6-3. The C6E3v_keyFrame Vertex Program


Figure 6-9. Various Interpolation Functions

The application is also responsible for determining the key-frame blending factor via the uniform parameter keyFrameBlend. The value of keyFrameBlend should transition from 0 to 1. Once 1 is reached, the application chooses another key frame in the animation sequence, the old key frame B position input is then configured as the key frame A position input, and the new key-frame position data feeds the key frame B position input.

Key-Frame Interpolation with Lighting

You often want to light a key-framed model. This involves not merely blending two positions (the vertex in two different key frames), but also blending the two corresponding surface normals. Then you can calculate lighting computations with the blended normal. Blending two normals may change the length of the resulting normal, so you must normalize the blended normal prior to lighting.

Example 6-4 shows the C6E4v_litKeyFrame vertex program that adds per-vertex


struct Light {
  float3 eyePosition; // In object space
  float3 lightPosition; // In object space
  float4 lightColor;
  float specularExponent;
  float ambient;
};

float4 computeLighting( float4 computeLighting(Light light,
float3 position, // In object space
float3 normal) // In object space

{
  float3 lightDirection = light.lightPosition - position;
  float3 lightDirNorm = normalize(lightDirection);
  float3 eyeDirection = light.eyePosition - position;
  float3 eyeDirNorm = normalize(eyeDirection);
  float3 halfAngle = normalize(lightDirNorm + eyeDirNorm);
  float diffuse = max(0, dot(lightDirNorm, normal));
  float specular = pow(max(0, dot(halfAngle, normal)),
        light.specularExponent);
  return light.lightColor * (light.ambient +
        diffuse + specular);
}
void C6E4v_litKeyFrame(float3 positionA : POSITION,
                       float3 normalA : NORMAL,
                       float3 positionB : TEXCOORD1,
                       float3 normalB : TEXCOORD2,
                       float2 texCoord: TEXCOORD0,

        out float4 oPosition : POSITION,
        out float2 oTexCoord : TEXCOORD0,
        out float4 color : COLOR,

    uniform float keyFrameBlend,
    uniform Light light,
    uniform float4x4 modelViewProj)
{
  float3 position = lerp(positionA, positionB,
        keyFrameBlend);
  float3 blendNormal = lerp(normalA, normalB,
        keyFrameBlend);
  float3 normal = normalize(blendNormal);
  oPosition = mul(modelViewProj, float4(position, 1));
  oTexCoord = texCoord;
  color = computeLighting(light, position, normal);
}

Example 6-4. The C6E4v_litKeyFrame Vertex Program

lighting to the C6E3v_keyFrame example. In the updated example, each key frame also supplies its own corresponding per-vertex surface normal.

The computeLighting internal function computes a conventional lighting model using object-space lighting.

 

______________________________________________________


join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2003 CMP Media LLC

privacy policy
| terms of service