Selection
At any one time there are a huge amount of cameras to choose from in game. A singular level can have a whopping 50 defined in it, a lot of which are designed to run simultaneously. But how do you decide which ones to pick, which ones have higher priority? The engine uses one of three systems, those being: zones placed in environments, actions triggered by the combat system or scripting.
Environment
The environment in God of War is marked up with zones, which to the camera system sort of looks like what's pictured above. Each of these zones reference one or more cameras and when the hero enters a zone, the associated camera's are selected and sent to the renderer.
Combat - Combat can also submit cameras. Whenever Kratos performs a grab on a grunt/minion he goes into a move sequence, which can each have their own animated cameras associated with them. More on this later.
Scripting - Finally there are scripted sequences. After the player triggers an event, be it pull a lever or whatnot, the scripting system will serve up to the camera system which specific cameras to use. These cameras would have normally already been picked out by the animators and are meant to highlight something important in the game.
Filtering
Once all cameras are submitted, the camera system is left with a laundry list of cameras to pick from. How does it narrow it down to the selections it wants? Using a filtering system.
Embedded in each camera is a list of other cameras it can or cannot transition to, so that's one pass. Then the player state is looked at, like if he is falling, only cameras that are marked to be valid when the player is falling will be used. Once they have that shortened list, they look at the priority level and clear out the ones with one less than that of the highest one in that list, or submitted. This finally returns a list of cameras that should be active in that scene. Next this list is passed on to be dealt with by the blending system.
Blending
The blending system handles how one camera will transition to another, how one camera will move or be restricted and blend in to create smooth and not-jarring movement. It keeps a track of how to do this using a blend tree at its core.
Blend Tree
As input the blend tree takes in camera priority, how it's set to blend and whether it was submitted that frame. Cameras can be faded in and out as needed and are inserted into the tree at the right point. Each of the nodes in the tree has a weight and mode that determine how it calculates what it will do that frame.
Blend weights have multiple ways of being generated. They can be created from timers which are used to drive a hermite spline, to add ease. They can also be driven by Kratos's position within a zone, like mentioned previously, which are calculated by the collision system. Finally they can be calculated bu the camera itself, and the team does have an experimental camera that controls its weight based upon its direction moving on a rail, more on this later.
Modes
There are two modes of blending that determine how the nodes will be blended in the tree. Crossfade blends the second node over the first node, and average mode blends across all input nodes using their individual weights to produce an average. Once these modes and weights are determined in the blend tree, they are reduced to a list of binary blending operations between pairs of cameras. Afterwards, each camera gets converted to a set of parameters that can later be interpolated to produce nice, smooth motion, which are: orientation, target position in world space and target position in camera space.
How the camera is positioned is described in the above image. The camera is set relative to the target which allows it to tween around it rather than being able to go through it. The actual position of the target in camera space is not defined by the targets position, rather it is stored as the offset of the target vector from the look vector (by horizontal and vertical angles). The distance from the camera to the actual target completes the spherical coordinate form.
A interesting thing to note is that the camera is stored in Euler form rather than Quaternion form. Eulers keyframe nicer for cameras rather than quaternions which introduce ugly roll. This however introduces the problem of gimbal lock, which they try and solve by asking designers to avoid those sorts of shots (vertical shots), but that is not really a realistic request. Designers will still submit those vertical shots, like Kratos walking down a flight of spiral stairs, and it is up to the programmers to solve it. They did it with a simple solution, which just involved tilting the camera just slightly from vertical. Simple and effective.
You never know what designers will throw at you however, like the vertical flying segment of God of War 3, . To solve this problem, they just added a extra transform which allowed them to change the actual direction of the gimbal lock, which should only be done under exceptional cases, and this was one of them.
The Yaw Problem
For each of the parameters, yaw, pitch and azimuth there are two ways that cameras can blend, long and short. For yaw it's a problem because the system is dynamic and whichever side is shortest can change uncontrollably, which can cause a unsightly pop as the camera tries to flip from one side of the player to another. This is easy to spot, but sometimes would pop up in a long chain of blends.
To solve this they decided to express yaw as a 2D unit vector which they blend with each blend in turn and converting it all back into an angle when generating the camera transform. This reduces the problem and gives them a warning which they can use to tell the camera designer if they are using fragile blends. All that's left now is angle of view.
Dynamics
Before we get to calculating the angle of view, lets look at how the cameras are generated in the first place. There are three basic cameras that match the previously discussed submission methods.
The animated camera is used for cinematic sequences, and is triggered by the scripting system. The dynamic camera deals with environmental situations and is controlled by the environment zoning system. Finally the combat camera activates when a close up shot of a fight sequence is needed and it is submitted by the combat system.
Animated
The animated camera simply takes a camera that's animated by a animator, typically for cinematic sequences and gets mapped directly to its blending parameters. You can even control the blending using a static aim point from Maya, as the target point. Of course more functionality was added in later games (GoW3) like the ability to drive animation based on a NURBS curve they called the drive rail. The drive rail would be mapped to the length of the current animation and the system automatically calculated the animation time based on the point on the rail nearest to the hero in each frame.
Dynamic
The dynamic camera model is similar to the model used for blending (pictured above, with all the vectors). All the same parameters come in as Euler angles again, but there are a couple of extra bits added.
You can see in the upper left the Dolly, and from the Dolly to the target plane, coincident with the look vector, the boom. The boom is used to calculate and constrain orientation and distance, and the offset is converted into distance to the target plane, to stop constraining the offset from changing the size of the target on screen.
Constraints are applied in the following order. First framing is set by constraining the horizontal and vertical components. Then the position of the dolly is updated to constrain the boom. Then the distance of the camera to the target plane is constrained, and finally the orientation of the camera itself. This all culminates in the framing constraint being expressed in terms of a safe zone on the screen that if the hero moves out of, the camera will put him back in.
After all of these calculations are completed in sequence, so now you are left with conflicts. Sometimes applying one constraint will inevitably push the system out of a another constraint. Minimizing the effect may work, but sometimes they oscillate, and in worse scenarios may cause the whole system to explode. This can be fixed easily though by opening up some constraints, which the speaker recommends be orientation, modified between 0 to 5 degrees.
Combat
Because combat events can happen anywhere in the environment, more direct control of the camera is seized (as these cannot be authored in the world), so they are animated relative to the characters involved.
In this scene are effectively three character, Kratos, the grunt and the camera rig. All three are synched such that a joint in each lines up at the position and orientation pictured above, called a synch joint. The combat rig itself is comprised of the synch joint at its root and attached to it are a camera and target, each on their own joints.
Because interiors can be liable to clipping with the camera a clever thing is done. The combat camera is blended over the environment camera, because it is know that the specific environment camera was designed not to intersect with geometry. The position of the environment camera is used, then the rig camera is oriented to face the target and the fov is set at a size that would be the same as if the rig camera was used directly.
If the target creatures are not facing the camera when an animation is initiated, they are rotated around the up axis to match the camera animation. This is tweened over time to look as smooth as possible, sometimes extra steps by Kratos are added to hide footslide on larger, more jarring angles.
Targeting
Targeting will cover how entity's are selected to be looked at.
Pictured above is Kratos. He stands at 2.25m tall, with his logical position being on the ground between his feet. About 1.5m up you can see the camera target, which has no explicit damping. All damping comes from player logic and will be described later.
Because Kratos is a jumpy sort of guy, this would cause the camera to be moved up and down a lot, and quite frankly that would be a little dizzying. There's a optional system called jump correction which sets out to fix that, and it can be enabled on a per camera basis.
The concept works simply. If Kratos lands on a higher surface than he started on, the camera will tween up to meet him. If he falls below starting height, his vertical position is immediately tracked. Notice no in-between; so when he actually jumps there is no vertical movement whatsoever.
Above is how targeting info is visualized in the camera system (in debug). If you notice, the creature target is a sphere rather than a point and it has a weight associated with it. The target can be also attached to a joint however and thus will need to be dampened.
This is achieved by wrapping the joint in two spheres. The innermost sphere allows free movement of the joint, the space in-between the two spheres is progressively dampened and if the joint reaches the outer sphere the whole target is moved to keep the joint inside. This makes sure that the target never becomes detached from the creature.
With multiple creatures in a fight, each with a target them, they are averaged to produce a boom target fed into the dynamic camera.To prevent slow moving creatures from going off screen, a weight is added to each target. The weight is actually comprised of three weights:
- Base Weight - This specifies how important the target is
- Distance Weight - This fades out between a min and max distance from the hero
- Activation Weight - Used to smoothly add in or remove targets, when the creature is spawned or killed
The boom is obtained from the sum of all target positions, multiplied by their weights, and divided by the sum of all weights. This system works fairly well for a lot of creatures, but doesn't pull in close enough when down to one, singular grunt. This is a flaw in the averaging process and it is solved with a second pass of prioritised framing.
Prioritised Framing
Prioritised framing fixes the previous problem with a second pass that promises the highest priority target will remain in frame, followed by trying best to frame lower priority targets. It does this by tracking the target camera to include multiple tracking spheres. Starting at the bottom working its way up.
It first centers round Kratos, then looks for the lowest priority level, moving the frame only enough to encompass as much as possible. This is repeated at the next priority level until done, and whats left is the new frame. However there is still a problem, birth and death and going behind the camera.
When a character is spawned outside the frame, there is a sudden pop to include them in it. The solution is to add weights, a logical position between the actual, physical position of the target and the hero. This logical position is then used to tween targets in and out, and this logical position always remains in the safe zone. Whenever a new creature is spawned, the weighted position moves out from Kratos in smooth tween to its logical position, guiding the camera along with it.
Going behind the camera is a little more tricky. If the target were to pass behind the player, the camera would suddenly pop to the other side of the player, and pop back next frame in oscillating mess. The solution is pretty similar to the birth and death solution.
The logical weight never goes behind the camera, instead it is clamped to the plane parallel to the camera plane. In the image above you can see the target, represented by the solid circle, and it's logical wieght, represented by the dotted circle. Notice how the target is now behind the camera, but the logical weight does not pass by the horizontal line (plane), and that is what the camera is tracking. As long is follows that, the target will eventually reunite with its weight and the transition will look smooth, no jerky flips.
All these corrections come together to make a camera system that works smoothly in all cases, keeping priority on the player and including all relevant enemies in a way that looks smooth and natural.
All images and source material was taken from Phil Wilkins, 2011 GDC presentation, "Iterating on a Dynamic Camera System".
No comments:
Post a Comment