Tuesday, April 28, 2015

First steps for a game camera

The first version of a camera tracking a target on screen could be a fixed offset from the center of the target with the camera looking straight along the offset.

This is really all there is to get started and it is time to think about the next steps. This is a few questions to ask about the game before deciding on a direction for the camera that will influence level layout, art detail, how far sounds need to be heard and much more.

There are a lot of considerations when framing multiple targets at once but to reduce the scope this post will focus on game cameras with a single target. This post does not contain anything new, it is intended as a checklist to get started with a game camera.

Different camera distances

Any artistic qualities for framing subject would require a far longer post so instead I will resort to suggest defining some metrics at this point;

Thursday, April 23, 2015

Intersection of three planes

Three plane intersections can make framing shapes on a screen trivial, along with many other applications. While useful for prototyping, I don’t tend to use three plane intersection in final products as there are a lot of things working together.

There are several cases where three planes do not meet in a single point, but there is a simple test for that. For most intersection applications with camera space I have not encountered this but it is worth keeping in mind.

Intersection of three planes

Unsurprisingly the solution is similar to finding a point along the line of a two plane intersection:

P = (d1(n2n3) + d2(n3n1) + d3(n1n2)) / (n1 ᐧ (n2n3))

Tuesday, April 21, 2015

Intersection of two non-parallel planes

Plane intersections can solve a number of camera framing optimization problems and is an easy way to for example find the rays along the corners of the view frustum given the screen edge planes.

Any line that lies on a plane is perpendicular to its normal, so the only line that is shared between both is perpendicular to both normals, or the cross product of the normals:

D = n1n2

If the planes are parallel the cross product will be zero since there will be no intersection. This is a rare case when dealing with camera space but worth keeping in mind.

Two parallel planes will not intersect and two non-parallel planes will intersect in a line.

If any point of the line is already known, for example the intersection of any two camera frustum planes will intersect with the camera position, this is all that is needed.

If no point along the intersection is known there are a few more steps.

Sunday, April 19, 2015

Constructing the camera frustum planes

The camera frustum is defined by the orientation and field of view of the camera and looks like a pyramid with the peak located at the camera and everything inside is visible on the screen.

Each edge of the the screen can be represented by a plane and in addition the near and far distances cap the frustum. Creating planes of the surface of the frustum is not the only way to represent it but it is convenient for many tests and placements.

A typical camera frustum with plane normals pointing outwards.

Before jumping in to formulas the value of field of view needs to be described.
The most common way to describe field of view in games is an angle between the top and bottom or between the left and right side of the screen, and most math uses the half field of view.

Saturday, April 18, 2015

Plane definition

At this point I will add a few posts about basic geometry. This is needed to back up future posts without weighing them down inlining the math. Here is a basic review of planes.

Planes are commonly used for camera logic and are easy to work with as long as the basics are clear.

Line segment intersecting with a plane.

Camera Debug Drawing

It seems natural that one of the more useful ways to debug the camera is the ability to see what the camera is looking at and where it came from. I usually render a variety of paths and frustums and more to help diagnose a large set of common problems.

This is a re-imagining of camera debug drawing in a recent game which contains a number of different visualizations:

Camera drawn as the frustum up to the near plane, player, player path, framing cylinder, camera path and extended field of view as red lines.
One additional requirement is the ability to view the camera status from a different perspective and ideally while the rest of the game is in a frozen state. I prefer to be able to go into this state using nothing but the game controller so I can easily investigate issues on other machines when I get called over to look at something.

Some engines handle seeing the game camera from a different perspective by letting you move around in the scene in one window while playing the game in another. This is fine but it means you can’t really dig in to what happened when the game is tested on a target different from the development computer.

Here is list of visualizations I tend to implement in games.

Wednesday, April 15, 2015

Finding 2D points

I am going to post some basic geometry solutions that I will reference in future posts. These are solutions I've used in several games for a variety of cameras.

Some problems with game cameras can be solved by projecting points into a horizontal plane, and here are planar line intersection and constructing a circle from three points.

Intersection of two lines in a plane

Given two lines, L0 and L1
L0 = P0 + s D0
L1 = P1 +  t D1

Find a point along both lines s and t where L0 and L1 intersects.

P0 + s D0 = P1 + t D1

An intersection between two lines in the plane is a point.

Saturday, April 11, 2015

Smoothing Functions

Probably the most common feedback during development is softening camera movement. This commonly applies to tracking camera target height or relative angular offsets among many other things.

I've implemented this so many times that I've settled on a specific function that gives me pretty good control of the smoothing and doesn't cause any bumps when settling with reasonable parameters.

Here's how it looks:

The red line is the target value. Each black dash represents one frame step for the value.

To show the components of the function that work together I'm breaking up the solution. Let's start with simply applying an acceleration limit to the difference from the start value to the target value:

We have a value that is updating, a rate of change for that value that is the speed and a target value. Each update we pass in the delta time (update interval in seconds). In these graphs the initial speed is zero to illustrate the functions, the value can already be moving and the target value can change each update.

Wednesday, April 8, 2015

Game Camera Types

Before diving in to details I'd like to define some camera types. The names I use for these cameras are likely different from what other teams use since there isn't a lot of academic literature for this subject.

Each camera type has specific utilities, such as walking, following a vehicle or fitting in small spaces. When the utility of a camera fits the space and gameplay the camera will be out of the way. Each type can be implemented in a number of ways. There are a number of parameters that camera systems manage but these definitions relate specifically to orientation and target distance. Each camera type may have collision logic or variable field of view. In this post the camera has a position and orientation and the camera target is something the camera is tracking that has a position and a facing direction.

I will find some way to draw clear lines and arcs to illustrate these camera types in a future post. For now I hope the written definitions are clear.

Leash Camera

Let's do this again.

I have done it again. I've created a game camera for yet another game and forgotten what I learned from all previous projects. I have 9 sheets of paper in front of me with pencil graphs and equations written on both sides and plenty of eraser crumbs all over.

It is time I documented my solutions in a place that won't be lost in bad handwriting in a drawer of a desk where I no longer work. Let's see if I can dig up some of those notes and remember some of those ideas of games shipped and make public posts about them.

Right now my stack of sheets contain a solution to find an optimal position for a camera to see a number of things on a screen taking into account some covered parts of the view. This is something I already solved in both Playstation All-Stars and Sonic Boom and I keep having to start over because I don't have a reference to my old notes or code.

Game cameras are often asked to do too much, including showing the desired perspective of the game; maximizing the size of the player; maximizing how much you see around the player; showing the direction forward; showing all the enemies around you; showing something in the distance that is relevant to what you should do and more and more, to the point where the game camera is simply a spatial and rotation optimization problem and not an opportunity for creativity.

With experience and constant persuasion from those I work with I've found that many limitations can be avoided by digging a little deeper. Since I've done this many times I feel I can share some of the solutions.

Much of my work has involved Bezier splines applied in different ways to cameras, some games have 2D cameras, most projects have user controlled cameras and lots of features require robust smoothing functions, and many implementations of camera collision. I worked on game cameras for most of my games, including Pocahontas for Genesis, Pac-Man World 2, Shrek 2, Kung Fu Panda, Playstation All-Stars Battle Royale, Transformers: Revenge of the Fallen and more. I might not have the notes or source available but I do have a good memory.

Future posts will include actual notes about game camera programming.