Joe
Joe

Reputation: 1

gluLookAt specification

I have some problems understanding the specification for gluLookAt. For example the z-axis is defined as:

F = ( centerX - eyeX, centerY - eyeY, centerZ - eyeZ )

with center being the point the camera looks at and eye being the position the camera is at.

f = F / |F|

and the View-Matrix M is defined as:

( x[0]   x[1]   x[2]  0 )
( y[0]   y[1]   y[2]  0 )
(-f[0]  -f[1]  -f[2]  0 )
( 0        0      0   1 )

with x and y being the x,y-axis and f being the z-axis

If my camera is positioned at (0, 0, 5) and the camera looks at the center. Then f would look along the negative z-axis because of the first equation (center - eye) the f-vector would be: (0,0,0) - (0,0,5) = (0,0,-5)

So far everything makes sense to me, but then the f-vector is multiplied by -1 in the M-Matrix above. That way the f-vector looks along the positive z-axis and away from the center.

I found that the perspective matrix gluPerspective will also multiply the z-axis of the camrea with -1 which turns the z-axis again and makes it look toward the world's negative z-axis.

So what is the point of multiplying it with -1?

Upvotes: 0

Views: 1007

Answers (2)

jackw11111
jackw11111

Reputation: 1547

I know this isn't a direct answer to the question but it might help someone who is looking for an equivalent function without using GLU, for example, if they are porting old OpenGL2 code to modern OpenGL.

Here is an equivalent function to gluLookAt(...):

void gluLookAt(float eyeX, float eyeY, float eyeZ,
               float centreX, float centreY, float centreZ,
               float upX, float upY, float upZ) {
    GLfloat mat[16];
    float forwardX = centreX - eyeX;
    float forwardY = centreY - eyeY;
    float forwardZ = centreZ - eyeZ;

    glm::vec3 forward = glm::normalize(glm::vec3(forwardX, forwardY, forwardZ));

    glm::vec3 right = glm::cross(glm::vec3(forwardX, forwardY, forwardZ),
                                 glm::vec3(upX, upY, upZ));
    right = glm::normalize(right);

    mat[0] = right.x;
    mat[1] = right.y;
    mat[2] = right.z;
    mat[3] = 0.0f;
    mat[4] = upX;
    mat[5] = upY;
    mat[6] = upZ;
    mat[7] = 0.0f;
    mat[8] =  -forward.x;
    mat[9] =  -forward.y;
    mat[10] =  -forward.z;
    mat[11] = 0.0f;
    mat[12] =  0.0f;
    mat[13] =  0.0f;
    mat[14] =  0.0f;
    mat[15] = 1.0f;

    glMultMatrixf(mat);
    glTranslatef (-eyeX, -eyeY, -eyeZ);
}

Upvotes: 0

Ripi2
Ripi2

Reputation: 7198

Because gluLookAt is a View Matrix for a right-handed system. In this space, Z-coordinate increments as it goes out of screen, or behind the camera. So all objects that the camera can see have negative Z in view space.

EDIT

You should review your maths. The matrix you exposed lacks the translation to camera position.

Following this notation let's do:

Obtain f normalized, up normalized, s normalized, and u=sn x f. Notice that s must be normalized because f and up may be not be perpendicular and then their cross-product is not a vector of length=1. This is not mentioned in the link above.

Form the matrix and pre-multiply by the translation to camera position, L= M · T

The resulting lookAt matrix is:

 s.x   s.y   s.z  -dot(s, eye)
 u.x   u.y   u.z  -dot(u, eye)
-f.x  -f.y  -f.z  dot(f, eye)
  0     0     0      1

With your data: camera=(0,0,5), target=(0,0,0), and up=(0,1,0), the matrix is:

1  0  0  0
0 -1  0  0
0  0  1 -5
0  0  0  1

Let's apply this transformation a the point A=(0,0,4). We get A'=(0,0,-1).
Again for B=(0,0,20), B'=(0,0,15).
A' has a negative Z, so the camera sees it. B' has a positive value, the camera can not see it.

Upvotes: 1

Related Questions