I'm currently starting with DirectX and building a small framework for myself and ran into a problem comprehending the camera vectors (position, lookDir, up).

What they represent exactly is clear, but here's the problem:

For my understanding the lookDirection Vector and the up Vector have to be orthogonal to each other. It this true? What happens if they are not?


3 Answers 3


The Up & look direction that you plug into the function as arguments do not need to be orthogonal. But then the 'behind the scenes' part of the function will make them orthogonal.

When they made XNA, they created similar functionality and since it's managed code, you can reflect it and see the 'behind the scenes' code that uses double cross product equations that make the 2 vectors orthogonal. The following snippet is slightly different in that it takes point in space that the camera is looking at instead of a looking direction but the first line converts it into a looking direction like yours does. The result is a view matrix.

public static Matrix CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector)
    Matrix matrix;
    Vector3 vector = Vector3.Normalize(cameraPosition - cameraTarget);
    Vector3 vector2 = Vector3.Normalize(Vector3.Cross(cameraUpVector, vector));
    Vector3 vector3 = Vector3.Cross(vector, vector2);
    matrix.M11 = vector2.X;
    matrix.M12 = vector3.X;
    matrix.M13 = vector.X;
    matrix.M14 = 0f;
    matrix.M21 = vector2.Y;
    matrix.M22 = vector3.Y;
    matrix.M23 = vector.Y;
    matrix.M24 = 0f;
    matrix.M31 = vector2.Z;
    matrix.M32 = vector3.Z;
    matrix.M33 = vector.Z;
    matrix.M34 = 0f;
    matrix.M41 = -Vector3.Dot(vector2, cameraPosition);
    matrix.M42 = -Vector3.Dot(vector3, cameraPosition);
    matrix.M43 = -Vector3.Dot(vector, cameraPosition);
    matrix.M44 = 1f;
    return matrix;
  • \$\begingroup\$ Vector3.Cross(cameraUpVector, vector) is 0 if both vectors are colinear. And Normalize will divide by 0. How to workaround that ? \$\endgroup\$
    – Softlion
    Commented Aug 27, 2021 at 11:38

LookAt functions construct an orientation from a pair of non-colinear vectors.

As long as they are not completely parallel, it is possible to via repeated cross product construct a set of orthogonal vectors representing the new orientation.

There are numerical stability concerns when they start becoming parallel as the cross product magnitude starts approaching zero.

If you do not do the orthogonalization steps and try to use a non-orthogonal set of basis vectors, you no longer have a rotation.


They don't need to be orthogonal. For example a traditional first person camera would have the up vector locked as (0, 1, 0) and with the change of the direction vector when looking around, it's not orthogonal most of the time. This prevents the roll effect when you turn sideways that you can see in flight simulators, where the up vector changes all the time to enable free rotation.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .