Coordinate systems

From DmWiki

In 3D graphics, one uses a coordinate system in order to represent points in space by a series of numbers. Usually Cartesian coordinates are used, as these are the easiest to work with (see 3D coordinate systems for other systems). However, there is not just one Cartesian coordinate system. There are many, which have their origins in different places and their axes aligned with different things. Each coordinate system has its own uses, and this article will teach you how to transform between them.

Table of contents

Coordinate Systems used in 3D Graphics

The following is a list of the most commonly found coordinate systems in a typical 3D application.

World Coordinates

The world coordinate system forms the "base" on which you can think of all other coordinates being defined. Usually, its origin is at the center of the game world, and its axes might be aligned with directions like north/south, east/west, and up/down. (For example, it is very common for the X axis to be east, the Y axis to be north, and the Z axis to be up. Another way is for X to be east, Y to be up, and Z to be south.) This is the coordinate system in which most of your level geometry - such as rooms, hallways, and landscapes - will probably be defined.

Local (Object) Coordinates

Each model in your game that is separate from the world - for instance, the model of a Non-Player Character (NPC), or a prop such as a tree, shrub, piece of garbage, etc. - will be defined in its own local coordinate system, also called object coordinates or body coordinates. This is good because it allows you to do instancing: the same NPC or prop can be used many times in a game level, and each time it can appear in a different position and orientation. Instead of having a different copy of the model data in world coordinates for each time the object appears, only one copy is needed. It is kept in local coordinates, and only the local-to-world transformation (a 4×4 matrix) is different for each copy of the object.

Bone Coordinates

Bone coordinates are related to skinning. Each bone will have its own coordinate system, and the vertices attached to it will be defined in that coordinate system. For more information, see the article on skinning.

Eye (Camera) Coordinates

This is a coordinate system that is aligned with the eye or camera. Usually, the X axis is to the right, the Y axis is up (corresponding to the X and Y axes of the screen), and the Z axis points into or out of the screen depending on whether the coordinate system is left-handed (Direct3D) or right-handed (OpenGL). In order to render the world, everything in it must be transformed to eye coordinates - this is normally done by the GPU. In fact, in most 3D APIs, such as Direct3D and OpenGL, there is no actual camera. Instead, the programmer creates a world-to-camera transformation, which gives the illusion of a camera moving through a world.

Tangent Space

For certain types of pixel shaders, it is necessary to work in tangent space. This is a coordinate system that is aligned to a single triangle, with the X and Y axes pointing along the surface and the Z axis parallel to the triangle's normal vector. There may be a single tangent space for each triangle in a model, or for smooth models, the tangent space may vary smoothly from point to point along the surface.

Transforming Between Coordinate Systems

The main question is: if you have the coordinates of a point in one coordinate system, how do you figure out what its coordinates are in another system? This is done using 4×4 matrices, and it is very easy to do. The key is not to think about these matrices as being made of translations, rotations, and so forth - this is confusing and unnecessary. Instead, only think of coordinate systems in terms of the directions in which their axes point.

Bases

A coordinate system can be defined by four vectors - one each for the X, Y, and Z axes, and one for the origin. The only restriction is that the axes cannot all lie in the same plane. (You can check this by calculating the value (x × y) · z. If this number is nonzero, then the vectors are good.) A set of four vectors {x, y, z, o} that satisfies this rule is called a basis.

The three axis vectors in a basis do not need to be unit-length, or perpendicular to each other. If they are, then they are a special kind of basis, called an orthonormal basis.

Bases and Coordinates

Once you have a basis, any point in space can be represented by adding up a multiple of each of the basis vectors. (Technically, this is called a linear combination of the basis vectors.) In math notation: suppose you have a basis, B = {x, y, z, o}. For any point p in space, you can find three numbers c1,c2,c3 such that:

\mathbf{p} = c_1 \mathbf{x} + c_2 \mathbf{y} + c_3 \mathbf{z} + \mathbf{o}.

Note that we are thinking about the vectors as just being "arrows" in space, and not being expressed in any particular coordinate system yet. But now, the three numbers c1,c2,c3 are called the coordinates of p with respect to the basis B. We will use the notation:

\big [ \mathbf{p} \big ]_B = \begin{bmatrix} c_1 \\ c_2 \\ c_3 \\ 1 \end{bmatrix}.

This just says that the vector (c1,c2,c3,1) is the coordinates of the point p in terms of the basis B.

Note also that we use a 1 in the last coordinate because p is a point. If it were a direction, instead, we would use a zero in the last coordinate, and we would have

\mathbf{p} = c_1 \mathbf{x} + c_2 \mathbf{y} + c_3 \mathbf{z}.

The Change-of-Basis Matrix

Now, we are ready to learn how to find the matrix that will take us from the coordinates in one basis to the coordinates in another basis. Let us suppose we have two bases, A and B, and the vectors of A are called x, y, z, o. Then the change-of-basis matrix from A to B is defined as:

S_{A \to B} = \bigg [ \begin{bmatrix} \mathbf{x} \end{bmatrix}_B \quad \begin{bmatrix} \mathbf{y} \end{bmatrix}_B \quad \begin{bmatrix} \mathbf{z} \end{bmatrix}_B \quad \begin{bmatrix} \mathbf{o} \end{bmatrix}_B \bigg ]

This deserves a bit of explanation. We are taking each of the vectors in the basis A (the "initial" basis) and expressing it in the coordinates of the basis B (the "final" basis), and then putting these coordinates into the columns of a matrix. The matrix created by this process can be multiplied by the A-coordinates of any vector v, and the result is the B-coordinates of the same vector:

\big [ \mathbf{v} \big ]_B = S_{A \to B} \big [ \mathbf{v} \big ]_A

The change-of-basis matrix from B to A is simply the inverse of the A-to-B matrix.

An Example

Let's do an example where we compute the matrix to transform an object from local coordinates to world coordinates. Suppose we want the center of the object to be located at the world point (1, 2, 3), and we want the object to be rotated 45 degrees around the Z axis with respect to world coordinates.

In order to transform from local to world space, we have to take the basis vectors x, y, z, o of the local coordinate system, and express them in world coordinates.

  • First, since we are rotating around the Z axis, the x axis of the local coordinate system will have world coordinates (cos 45°, sin 45°, 0, 0), which equals (.707, .707, 0, 0). Note that this vector is (1, 0, 0, 0) in local coordinates.
  • Similiarly, the y axis of the local coordinate system will have world coordinates (-sin 45°, cos 45°, 0, 0), which equals (-.707, .707, 0, 0). This vector is (0, 1, 0, 0) in local coordinates.
  • The z axis does not change during the transformation (it is the same in both local and world), so its coordinates are just (0, 0, 1, 0) in both.
  • Finally, the origin of the local coordinate system will have world coordinates (1, 2, 3, 1). This point is (0, 0, 0, 1) in local coordinates.

To summarize, we have:

\big [ \mathbf{x} \big ]_{world} = \begin{bmatrix}.707\\.707\\0\\0\end{bmatrix},\quad \big [ \mathbf{y} \big ]_{world} = \begin{bmatrix}-.707\\.707\\0\\0\end{bmatrix},\quad \big [ \mathbf{z} \big ]_{world} = \begin{bmatrix}0\\0\\1\\0\end{bmatrix},\quad \big [ \mathbf{o} \big ]_{world} = \begin{bmatrix}1\\2\\3\\1\end{bmatrix}

All we have to do now is put these vectors together in a matrix, like so:

S_{local \to world} = \begin{bmatrix} .707 & -.707 & 0 & 1 \\ .707 & .707 & 0 & 2 \\ 0 & 0 & 1 & 3 \\ 0 & 0 & 0 & 1\end{bmatrix}

That's all there is to it. This matrix will convert any vector from the local coordinates of this object to world coordinates.


DevMaster navigation