W00t! 2,000 views on the blog today! Probably most are spammers, but who cares? Still a victory!

Anyway, What I’m going to do is use this blog to not only rant about useless stuff I find interesting, but to also store code snippets and algorithms for later use in applications and such. And I guess I’ll share them too.

So, today, since it’s been a few years since College, I’m going to bone up on some of my math. I’m going to do a step-by-step of the LookAt Algorithm.

**Variables**

First, we have our object that’s doing the looking. Since the most common usage of the LookAt algorithm is for cameras, lets call it `camera`

.

`camera`

is simple; it only contains a 4×4 Matrix which contains the camera’s orientation and position in the world. We’ll call this variable `orientation`

;

So we have `camera`

and `camera.orientation.`

**LookAt Function**

The LookAt function prototype is fairly straight-forward.

void LookAt(Matrix4& orient, const vec3& target, const vec3& Up);

Nothing scary; the `Matrix4& orient`

is the matrix we’re modifying, and the `vec3& target`

is the position of what we want to look at. The `vec3& Up`

is our worlds’ `Up`

vector, which is normally `{0, 1, 0}`

. So, if we know this, why pass it in? Because not every situation will have the same `Up`

vector! Maybe this isn’t a camera doing the looking, but the head on a model. Or maybe this is Super Mario Galaxy!

Before we start, Here’s an easy breakdown of the matrix, so I don’t confuse anyone with terminology. You should have a general concept of Linear Algebra and Trigonometry if you’re trying to pull this off.

{Xx Xy Xz Xw} <- X Axis {Yx Yy Yz Yw} <- Y Axis {Zx Zy Zz Zw} <- Z Axis {Wx Wy Wz Ww} <- W Axis

Now it’s time to break down the algorithm.

**Step 1: **First, we create a vec3 called `ZAxis`

. This is a vector pointing to our target’s position from our camera’s position, which is stored in the W Axis of the `orient`

matrix. Afterwards, we normalize the vector.

vec3 ZAxis = target - orient.WAxis(); ZAxis.normalize();

**Step 2:** Now we create the vector `XAxis`

and initialize it to the cross product of the `Up`

vector crossed with the `ZAxis`

we just made. Then we normalize that, too.

vec3 XAxis = CrossProduct(Up, ZAxis); XAxis.normalize();

**Step 3:** Next, we create the vector `YAxis`

, and initialize that to the cross product of `ZAxis`

crossed with `XAxis`

. Then, you guessed it: normalize the sucker.

vec3 YAxis = CrossProduct(ZAxis, XAxis); YAxis.normalize();

**Step 4:** Finally, we set all of `orient`

‘s axises with the corresponding ones we just created, and there! We now have a Stalking Matrix — err, I mean, uhh, a LookAt Matrix.

orient.XAxis(XAxis); orient.YAxis(YAxis); orient.ZAxis(ZAxis);

All Together Now!

vec3 ZAxis = target - orient.WAxis(); ZAxis.normalize(); vec3 XAxis = CrossProduct(Up, ZAxis); XAxis.normalize(); vec3 YAxis = CrossProduct(ZAxis, XAxis); YAxis.normalize(); orient.XAxis(XAxis); orient.YAxis(YAxis); orient.ZAxis(ZAxis);

There. Simple, right? I’ll post up more code snippets over time, usually whenever I feel like it.

And on that note, Tootles!

(Yeah, I couldn’t think of a witty way to end the post. Big Whoop. Wanna fight about it?)

Just implemented this in my own android space game to point ships in the direction of travel. Worked a charm. Thanks!

Really Nice…

Hi,

Suppose that the lookAt vector is 0,0,1 (World Z Axis) and the camera up vector is 0,1,0 (World Y Axis ), in order to calculate the camera coodrinates we do the following:

1- Camera Z axis: is the lookAt vector

2- Camera X axis: is the cross product of the lookAt and the Camera up vector

3- Camera Y axis: is the Cross product of Camera X and Camera Z

Now assume that the camera up vector is tilted a little in the YZ plane so it is 0,1,1, now the cross product of the lookAt and the up vector will give a vector in the same direction as the case when the camera up vector was 0,1,0 so the camera Y axis will have the same direction as the camera up vector 0,1,0 case. Then the rotation matrix that transfers from the wrold coordinates to camera coordinates will have the same values. whic will give a similar view as if the camera is not tilted.

If this is true then there is something wrong, because when the camera is tilted the view should change. What is wrong in my understanding?

Awesome and useful blog. Thank you! Works like a charm.

There’s one special case, though. If the camera to target direction aligns with the up vector parameter, should you use the global x-axis or y-axis and cross it with the new z-direction to find the new y-axis or x-axis respectively as a workaround on this dilemma?