Advanced Graphics and Animation Character Marco Gillies and Dan Jones Goldsmiths
Aims and objectives By the end of the lecture you will be able to describe How 3D characters are animated Skeletal animation forward and inverse kinematics Moprh targets
Character Animation Characters are normally animated by keyframes Set key values for position and rotation Its still very complex to animated complex movements
Character Animation Have simplified controllers that help you move a character Called rigs allow you to keyframe values of the rigs rather than all the vertices of the character
Skeletal Animation The fundamental aspect of human body motion is the motion of the skeleton The motion of rigid bones linked by rotational joints (first approximation) I will discuss other elements of body motion such as muscle and fat briefly later
Skeletal Animation a skeleton is a hierarchy of transforms Circles are rotational joints lines are rigid links (bones) The red circle is the root (position and rotation offset from the origin) The character is animated by rotating joints and moving and rotating the root
Forward Kinematics The position of a link is calculated by concatenating rotations and offsets
Forward Kinematics First you choose a position on a link (the end point) This position is rotated by the rotation of the joint above the link Translate by the length (offset) of the parent link and then rotate by its joint. Go up it its parent and iterate until you get to the root Rotate and translate by the root position
Forward Kinematics The position of a link is calculated by concatenating rotations and offsets P 2 = R 0 (R 1 (O 2 ) + O 1 ) + O 0
Forward Kinematics This is done easily with a hierarchy of transform matrices can be done quickly and easily in realtime
Problems with FK Forward kinematics is a simple and powerful system However, it can be fiddly to animate with If you want to make sure that a hand is in contact with an object it can be difficult
Inverse Kinematics Given a desired position for a part of the body (end effector) work out the required joint angles to get it there Given Pt what are R0 and R1
Inverse Kinematics We could try to work out an exact (analytic) formula Specific to a given number of links Underconstrained for more than 2 links
Inverse Kinematics An number of ways of doing it Matrix methods (hard) Cyclic Coordinate Descent (CCD) A geometric method (secretly matrices underneath)
Inverse Kinematics Start with the final link
Inverse Kinematics Rotate it towards the target
Inverse Kinematics Then go to the next link up
Inverse Kinematics Rotate it so that the end effector points towards the target
Inverse Kinematics And the next
Inverse Kinematics And the next
Inverse Kinematics And iterate until you reach the target
Inverse Kinematics And iterate until you reach the target
Inverse Kinematics And iterate until you reach the target
Inverse Kinematics And iterate until you reach the target
Inverse Kinematics And iterate until you reach the target
Inverse Kinematics IK is a very powerful tool However, it s computationally intensive IK is generally used in animation tools and for applying specific constraints FK is used for the majority of real time animation systems
Making it look good A skeleton is a great way of animating a character but it doesn t necessarily look very realistic when rendered Need to add a graphical skin around the character
Segmented Characters The simplest way is to make each joint a transform Hang a separate piece of geometry off each joint OK but body is broken up
Smooth Skinning We want to represent a character as a single smooth mesh (a skin ) This should deform smoothly based on the motion of the skeleton
Smooth Skinning Associate each vertex in a mesh with one or more joints The vertices are transformed individually by their associated joints Each vertex has a weight for each joint The resulting position is a weighted sum of the individual joint transforms T (v i ) = j joints w ijr j (v i )
Smooth Skinning
Smooth Skinning On a GPU Smooth Skinning is very well suited to implementing as a vertex shader You deform vertices one by one based on the joint transforms You need to get the bone weights for each vertex to the GPU Use Attributes
Smooth Skinning On a GPU / / use a uniform v a r i a b l e f o r the bone t r a n s f o r m a t i o n s uniform mat4 Transforms [ 5 8 ] ; / / use an a t t r i b u t e f o r the bone weights f o r each vertex / / t h i s is a vec4 so you can only have 4 bone weights a t t r i b u t e vec4 Weights ; / / you need another a t t r i b u t e to t e l l you which bones / / the weights correspond to a t t r i b u t e vec4 M a t r i x I n d i c e s ;
Smooth Skinning On a GPU / / b u i l d up a transform m a t r ix by adding up the transform / / matrices f o r each bone m u l t i p l i e d by the weights mat4 transform = Weights. x Transforms [ i n t ( round ( M a t r i x I n d i c e s. x ) ) ] ; transform += Weights. y Transforms [ i n t ( round ( M a t r i x I n d i c e s. y ) ) ] ; transform += Weights. z Transforms [ i n t ( round ( M a t r i x I n d i c e s. x ) ) ] ; transform += Weights.w Transforms [ i n t ( round ( MatrixIndices.w ) ) ] ; / / multiply the vertex position by t h i s transform g l _ P o s i t i o n = transform gl_vertex ; / / do the same f o r your normals normal = vec3 ( transform vec4 ( gl_normal, 0. 0 ) ) ;
Facial Animation Don t have a common underlying structure like a skeleton Faces are generally animated as meshes of vertices Animate by moving individual vertices
Morph Targets
Morph Targets Have a number of facial expressions, each represented by a separate mesh Each of these meshes must have the same number of vertices as the original mesh but with different positions Build new facial expressions out of these base expressions (called Morph Targets)
Morph Targets Smoothly blend between targets Give each target a weight between 0 and 1 Do a weighted sum of the vertices in all the targets to get the output mesh v i = t morphtargets w tv ti w t = 1
Morph Targets (trick) In the previous formula the weights have to sum to 1 If subtract a neutral mesh from all the targets you can lift the restriction Can allow extreme versions of a target v i = v 0i + t morphtargets w t(v ti v 0i )
Morph Targets On a GPU Morph targets can also be implemented on a GPU You need a vertex attribute for each morph target in fact 2 if you include normals
Morph Targets On a GPU / / a uniform v a r i a b l e f o r the morph t a r g e t weights / / maximum of 4 morph targets, but you can swap / / them around as d i f f e r e n t ones become a c t i v e uniform vec4 MorphWeights ; / / an a t t r i b u t e f o r the p o s i t i o n and normal of each / / morph t a r g e t a t t r i b u t e vec3 MorphPosition1 ; a t t r i b u t e vec3 MorphNormal1 ; a t t r i b u t e vec3 MorphPosition2 ; a t t r i b u t e vec3 MorphNormal2 ; a t t r i b u t e vec3 MorphPosition3 ; a t t r i b u t e vec3 MorphNormal3 ; a t t r i b u t e vec3 MorphPosition4 ; a t t r i b u t e vec3 MorphNormal4 ;
Morph Targets On a GPU / / Add the morph targets multiplied by the weights, to the position and normal / / I have preprocessed the morph targets to subtract o f f the base position / / ( t h i s i s done i n CPU code at the s t a r t of the program ) position. xyz += MorphWeights. x MorphPosition1. xyz ; position. xyz += MorphWeights. y MorphPosition2. xyz ; position. xyz += MorphWeights. z MorphPosition3. xyz ; position. xyz += MorphWeights.w MorphPosition4. xyz ; normal += MorphWeights. x MorphNormal1 ; normal += MorphWeights. y MorphNormal2 ; normal += MorphWeights. z MorphNormal3 ; normal += MorphWeights.w MorphNormal4 ;