What exactly is the UP vector in OpenGL's LookAt function?

41.6k views Asked by At

this is related to The LookAt target location doesn't matter if it is z = 0 or z = 1000 or -1000?

I tried

    gluLookAt(512, 384, 2000,
              512, 384, 0,
              0.0f, 1.0f, 0.0f);

and things work fine, and now I change the 3rd row (the UP vector), last number to 0.8:

    gluLookAt(512, 384, 2000,
              512, 384, 0,
              0.0f, 1.0f, 0.8f);

and it is exactly the same... next I tried and modified the 3rd line, the first number to 0.8:

    gluLookAt(512, 384, 2000,
              512, 384, 0,
              0.8f, 1.0f, 0.8f);

Now the view is like it rotated 45 degree to the left. How does this UP vector work?

4

There are 4 answers

0
Zack Brown On BEST ANSWER

The up vector is used to create a cross product between the eye and centre vector supplied to gluLookAt.

From the GLKit headers on iOS, you can see the implementation as:

static __inline__ GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
{
    GLKVector3 ev = { eyeX, eyeY, eyeZ };
    GLKVector3 cv = { centerX, centerY, centerZ };
    GLKVector3 uv = { upX, upY, upZ };
    GLKVector3 n = GLKVector3Normalize(GLKVector3Add(ev, GLKVector3Negate(cv)));
    GLKVector3 u = GLKVector3Normalize(GLKVector3CrossProduct(uv, n));
    GLKVector3 v = GLKVector3CrossProduct(n, u);

    GLKMatrix4 m = { u.v[0], v.v[0], n.v[0], 0.0f,
        u.v[1], v.v[1], n.v[1], 0.0f,
        u.v[2], v.v[2], n.v[2], 0.0f,
        GLKVector3DotProduct(GLKVector3Negate(u), ev),
        GLKVector3DotProduct(GLKVector3Negate(v), ev),
        GLKVector3DotProduct(GLKVector3Negate(n), ev),
        1.0f };

    return m;
}

The accepted answer in this question How do I use gluLookAt properly? provides a good description of what the up vector actually impacts.

(The intuition behind the "up" vector in gluLookAt is simple: Look at anything. Now tilt your head 90 degrees. Where you are hasn't changed, the direction you're looking at hasn't changed, but the image in your retina clearly has. What's the difference? Where the top of your head is pointing to. That's the up vector.)
2
CodeHxr On

The up vector determines which direction is "up". Think of it like a video camera... if you hold the camera "properly", then an imaginary line going upward from the center of the camera to the top of the camera could be represented by a vector (0,1,0). If you tilt the camera 45 degrees to the right, the imaginary line going from the center of the camera to the "top" of the camera would now be represented by a new vector (1,1,0). If you then tilt the camera "back" just a bit, your "up" vector now becomes (1,1,1) [or (1,1,-1)... I always get the polarity of the z-axis reversed].

So, in short, the UP vector describes the roll of the camera by saying which point is "up" in the camera's orientation.

Hope that helps. :)

(edit to correct summary as per comment)

4
Nicol Bolas On

It works exactly the way it looks like it works.

Imagine you're at some point in space. And them imagine that you're looking at some point 2000 units directly in the -Z direction from you.

There are an infinite number of possible cameras with these characteristics, but they are different based solely on having a different "up" direction. So the different "up" directions correspond to having a different orientation around the direction of view.

The up vector is the vector direction that is aligned with the "up" direction you want the camera to have. That is, if you were to draw the up vector from your camera point, you would see a straight vertical line pointing up.

Now, look back at your imagined view, and look at that vertical line. Could you tell if that vertical line were moving towards or away from you? No; it's just a vertical line. So it doesn't matter if the up vector partially points in the direction of the view. What matters is that the up direction is not exactly pointing in the view direction.

When you give the up direction a non-zero Z coordinate, it now partially points in the view direction (ie: the Z axis). That part is ultimately irrelevant to the up direction you get, so it is ignored. When you give the up direction a non-zero X coordinate, that is not in the view direction, so it is significant.

The point of this is so that if you change the view look-at or camera origin point, you don't have to change the up direction too. As long as you're not looking directly along the up axis, you're fine.

0
IronMensan On

The first two parameters of gluLookAt are the camera position and the camera target. With just those two the camera isn't fully constrained. Imagine standing somewhere holding a camera. You can hold the camera horizontally to take a landscape picture, or you could hold the camera vertically to take a portrait picture. In both cases, the position of the camera and the position of the subject of the picture are the same. You could rotate the camera to any angle and those two values don't change. The third parameter, the up vector, selects the orientation of the camera.