# Understanding glm::lookAt()

C++OpenglGlm Math## C++ Problem Overview

I am following a tutorial to learn OpenGL in which they used `glm::lookAt()`

function to build a view but I cannot understand the working of `glm::lookAt()`

and apparently, there is no detailed documentation of GLM. Can anyone help me understand the parameters and working of `glm::lookAt()`

please?

GLM documentation says:

```
detail::tmat4x4<T> glm::gtc::matrix_transform::lookAt
(
detail::tvec3< T > const & eye,
detail::tvec3< T > const & center,
detail::tvec3< T > const & up
)
```

My current understanding is that camera is located at `eye`

and is faced towards `center`

. (And I don't know what the `up`

is)

## C++ Solutions

## Solution 1 - C++

The `up`

vector is basically a vector defining your world's "upwards" direction. In almost all normal cases, this will be the vector `(0, 1, 0)`

i.e. towards positive Y. `eye`

is the position of the camera's viewpoint, and `center`

is where you are looking at (a position). If you want to use a direction vector `D`

instead of a center position, you can simply use `eye + D`

as the center position, where `D`

can be a unit vector for example.

As for the inner workings, or more details, this is a common basic function for building a view matrix. Try reading the docs for gluLookAt() which is functionally equivalent.

## Solution 2 - C++

Here, the `Up`

vector defines the "upwards" direction in your 3D world (for this camera). For example, the value of `vec3(0, 0, 1)`

means the Z-axis points upwards.

`Eye`

is the point where you virtual 3D camera is located.

And `Center`

is the point which the camera looks at (center of the scene).

The best way to understand something is to make it yourself. Here is how a camera transformation can be constructed using 3 vectors: `Eye`

, `Center`

, and `Up`

.

```
LMatrix4 LookAt( const LVector3& Eye, const LVector3& Center, const LVector3& Up )
{
LMatrix4 Matrix;
LVector3 X, Y, Z;
```

Create a new coordinate system:

```
Z = Eye - Center;
Z.Normalize();
Y = Up;
X = Y.Cross( Z );
```

Recompute `Y = Z cross X`

:

```
Y = Z.Cross( X );
```

The length of the cross product is equal to the area of the parallelogram, which is < 1.0 for non-perpendicular unit-length vectors; so normalize `X`

, `Y`

here:

```
X.Normalize();
Y.Normalize();
```

Put everything into the resulting 4x4 matrix:

```
Matrix[0][0] = X.x;
Matrix[1][0] = X.y;
Matrix[2][0] = X.z;
Matrix[3][0] = -X.Dot( Eye );
Matrix[0][1] = Y.x;
Matrix[1][1] = Y.y;
Matrix[2][1] = Y.z;
Matrix[3][1] = -Y.Dot( Eye );
Matrix[0][2] = Z.x;
Matrix[1][2] = Z.y;
Matrix[2][2] = Z.z;
Matrix[3][2] = -Z.Dot( Eye );
Matrix[0][3] = 0;
Matrix[1][3] = 0;
Matrix[2][3] = 0;
Matrix[3][3] = 1.0f;
return Matrix;
}
```

## Solution 3 - C++

After set the `camera`

(or `eye`

) and `target`

(`center`

), made `camera`

face to `target`

, we can still rotate the `camera`

to get different pictures, so here comes the `up`

vector which makes the `camera`

fixed and cannot be rotate.

## Solution 4 - C++

```
detail::tmat4x4<T> glm::gtc::matrix_transform::lookAt
(
detail::tvec3< T > const & //eye position in worldspace
detail::tvec3< T > const & //the point where we look at
detail::tvec3< T > const & //the vector of upwords(your head is up)
)
```

It's not difficult, maybe you need to review the three coordinates:
**Object(or Model) coordinates**, **World coordinates** and **Camera(or View) coordinates**.