Gaze, breathing and character behaviour
An attention state machine, eyes that lead the head, and layered breathing, blinks and reactions for expressive browser characters.
Part 9 of 9From images to expressive 3D charactersSeries contents
- Building an expressive Giant Aperture mascot
- Turning reference pictures into a useful mesh
- Giving a mesh meaningful part labels
- Making painted eyes look and move like eyes
- Finding an ear and making it bend
- Turning a mouth line into an opening
- Fitting movement to the body in front of us
- Composing expressions and character behaviour
- Gaze, breathing and character behaviour
A leaf is interesting. Until something else happens.
A character can have a convincing smile and still feel absent. The difference often lies between the big expressions: noticing a falling leaf, following it for a moment, looking back at someone who tapped, then settling without freezing.
Our character stage separates three decisions. The world offers things worth noticing. An attention controller chooses what to follow and when to let go. The character turns that intention into eye, head or body movement. Breathing, blinks and small weight shifts keep running underneath.
This builds on the expression map. A held expression describes a pose; attention and idle motion give that pose a continuing relationship with its surroundings.
Give attention a beginning and an end
Picking the most interesting object on every frame made gaze too ready to change direction. Two leaves could trade places in the ranking and pull the eyes back and forth. Smoothing the movement alone would soften the twitch without fixing the indecision.
The controller keeps an explicit state and elapsed time: idle, noticing, tracking, losing and returning. A target needs enough importance to be noticed. Once chosen, it gets a minimum dwell time. A brief disappearance has a grace period; sustained absence or spent interest leads to a lingering look, a return and an idle cooldown.
A rival normally has to beat the current target by a margin and keep that advantage for a short interval. That stickiness is hysteresis: small changes do not reverse the decision. An urgent stimulus can interrupt immediately, so a tap does not have to wait behind a drifting leaf.
- Notice
Leave idle when a target clears the threshold. Move the eyes first, with a short beat before the head follows.
- Track
Hold the commitment and follow the target. A competing target must earn a switch; an urgent interruption can cut in.
- Linger
The losing state keeps the last point briefly after interest expires or the target disappears.
- Return
Ease the eyes and head forward, then release into idle motion. A cooldown spaces out ordinary curiosity.
Let the eyes lead the turn
Choosing a target and moving toward it are separate problems. The controller makes a quick eye movement for a new look, follows a slow target continuously, and uses occasional catch-up movements when the target gets too far ahead. A minimum gap between those corrections avoids a rapid staircase of new eye movements.
The head follows after a delay, with its own damped response. The eyes keep aiming at a point in the world as the head catches up. This avoids making the head and eyes rotate as one rigid unit. The character adapter supplies the coordinate frame and eye limits; the controller can give more of a large turn to the head.
The jelly has no neck. Its adapter translates the controller’s head contribution into a small lean of the dome and passes an aim to the iris API. Its own ambient gaze layer is separate, so that hand-off still needs a rendered check with ambient life enabled. Sharing an attention decision does not mean imposing the same anatomy on every character.
Decide which movement owns which part
A character may be looking at a leaf when it shakes off snow or reacts to a poke. Giving every behaviour the whole body would either cancel useful motion or make the controllers fight.
The stage resolves priority separately for eyes, head aim, head movement, face, body and tail. A shake can take the head and body while gaze keeps the eyes. A poke can take the face while attention continues following a target. Each behaviour supplies its own blend envelope; the priority resolver decides whose contribution is allowed through.
This is an established animation pattern: layers and body-part masks let different actions coexist. Our particular part names, priorities and rule for reserving a part without adding movement are project choices. They make ownership inspectable when a reaction looks wrong.
Build a resting performance from small rhythms
The fitted-rig life layer treats breathing, sway, glances, blinks and follow-through as separate contributions. A breath has a quicker inhale, a slower exhale and a pause. Its period varies slightly from cycle to cycle, and the chest follows the belly a little later. Depth and chest share control where the motion reads.
The same breath publishes its phase and exhale strength. Frost breath and visor fog can follow that signal instead of running an unrelated timer. Slow weight shifts and occasional glances add other rhythms. A seed makes the sequence repeatable while letting characters start with different timing.
Blinks close quickly and open more slowly, with occasional doubles. They also need acting judgement: an attentive hold or a release blink can say something that an arbitrary interval cannot. Shawn Kelly’s advice to blink for a reason is the practitioner reference here; procedural variation still needs to be judged in the combined performance.
Body type matters. The rigid-route life layer omits organic breathing and sway and supplies servo-like glances and a light pulse instead. A soft rig uses its supported channels and measured movement ranges. Missing controls are recorded and skipped.
Put personality in settings that can be changed
The attention settings live in a shared default record with character overrides. Notice threshold, dwell, cooldown and the importance of different stimulus kinds change what holds the character’s interest. Head delay, turn share and smoothing change how that interest is performed.
The jelly’s record makes it easy to engage and slower to move its soft body. In the inspected configuration, it can hold ordinary interest for 1.8 to 6.5 seconds, waits 0.2 seconds before the dome follows, and limits that contribution to 14 degrees. Those are authored settings for this character, rather than biological constants.
The useful handles are small. One threshold changes how readily a character notices. One dwell value changes how patient it feels. One head share changes how much of a look reaches the body. Breath depth and energy change the resting performance without authoring a separate clip for every combination.
A smooth curve still needs smooth sampling
One breathing defect came from reading a cached animation one whole frame at a time. The fitted-rig layer was baked at 60 frames per second. A faster display could show each value twice; other playback rates could alternate between holding and skipping samples. The underlying breath curve was smooth, but the displayed movement stepped.
The stage sampler now interpolates between neighbouring cached values at the requested time. It also treats breath phase as a wrapping cycle, so the transition from the end of a breath to the beginning follows the short path. Sampling exactly on a cached frame preserves that frame.
That fix belongs to the fitted-rig stage path inspected here. The procedural jelly has its own adapter and cached life sampling, so it needs its own playback check. Reusing the life generator does not by itself prove that every renderer samples it smoothly.
Check the decisions as well as the motion
A gaze problem is easier to diagnose when we can inspect the chosen target, current state, commitment count, eye movements and winning behaviour for each body part. Those records distinguish a target that changes too often from a follower that moves badly toward a stable target.
The controller tests exercise dwell and hysteresis, the route back to idle, eyes leading the head, pursuit of a slow target and spacing between catch-up movements. The behaviour tests check that a shake wins the head while gaze retains the eyes and a poke can retain the face.
For repeatable directed clips, ambient attention is disabled by default unless explicitly enabled. That preserves an authored look instead of allowing a passing environmental stimulus to change a capture.
This chapter follows the inspected shared stage code and its local controller tests. The later rainy-scene capture supplies visual context. A fresh comparison of all characters, rendered gaze accuracy and physical-phone performance still needs scene-level evidence; passing the controller tests alone does not establish those results.