If you have ever written an FPS camera, you have probably seen something like this:
vec3 forward = get_forward_vector(yaw, pitch);
vec3 target = position + forward;
mat4 view = look_at(position, target, world_up);
It works, but it's really redundant and there's a way simpler way of doing an FPS camera properly.
Constructing a target just to pass it to look_at is unnecessary. The camera is already defined by its position and orientation, so constructing the basis vectors directly is just simpler.
look_at is actually for cases where you actually have a target. Maybe you're orbitting a planet, or tracking an object, whatever, THIS is what actually makes sense:
view = look_at(camera_position, player_position, world_up);
Now you might ask, oh, Cutie, what's the proper way of doing an FPS camera?
First you want the forward direction
vec3 forward;
forward.x = cos(pitch) * cos(yaw);
forward.y = sin(pitch);
forward.z = cos(pitch) * sin(yaw);
forward = normalize(forward);
Then, you want the camera basis:
vec3 right = normalize(cross(forward, world_up));
vec3 up = normalize(cross(right, forward));
And now you have the directions to move and orient the camera:
position += forward * movement_forward;
position += right * movement_sideways;
Then you can construct a view matrix from these axes, or construct a camera transform and invert it.
That's it. I hope it was useful.
Top comments (0)