Implementing an FPS camera and I need some help on horizontal orientation.

I have the default view direction of (0, 0, -1), right vector of (1, 0, 0) and up vector of (0, 1, 0).

The approach that I have taken is as follows:
[ul]
[li]To turn left or right, the right vector is added or subtracted to the view direction and the right vector is ‘realigned’ by taking the cross product of the view direction and up vector.
[/li][li]To look up or down, the up vector is used instead of the right vector.
[/li][/ul]

The problem with this approach is that when the camera looks up or down, the left and right keys do no work they way I want them to. The orientation is like a tilted disc where turning left/right distorts the horizontal orientation.

What have I not considered?

Most simple FPS cameras have a fixed up vector. When you turn up with your camera, the up and view direction vectors are tilted back somewhat. When you then turn right, you turn about the new up axis, not the old one, so you get a tilted disc. This could be solved by not realigning the up vector when you look up or down, but then you will no longer turn up or down with constant angular velocity.

The approach I use for simpler cameras is to keep two Euler angles ranging from (in degrees) (0 - 90) and (0 - 360), specifying independent orientations up/down and left/right respectively. Then I use them along with the camera eye position to calculate the right and view direction vectors on the fly when I need them. Turning up/down and left/right then becomes a matter of scalar addition/subtraction on these Euler angles rather than vector products. Of course, it suffers from Gimbal lock and other things that could be solved by quaternions, but in practice for an FPS style application those aren’t problems.

A tutorial describing something similar can be found here. There are plenty others, as well.

Also, make sure you’re renormalizing everything at appropriate times.