Post Lists

2018년 6월 23일 토요일

The construction of Camera matrix (Lookat Matrix)

I'd like to simplify the camera matrix within my understanding.

First of all, We should know that the window using graphics library such as OpenGL just shows the display on the (0,0,0) origin and in the direction of -Z axis (based on OpenGL, right-handed coordinate system).

It means that there is no actual move of camera. We just make the world space coordinate of objects change. It makes an effect of us moving the camera.

With this notion above, suppose that there is an object located on (-2, 0, -3) in the world space, and the camera is located on (0,0,0), looking at -Z axis.

If you want to move camera backward(+Z axis),
you have to make the object forward(-Z axis).

For example, if you want to move the camera on (0, 0, 2), the object should move to (-2, 0, -5) as I already told about the fake moving of camera. take care that the actual world space coordinate of the object is still on (-2, 0, -3), because the view matrix transform makes the change of location on the display, not on the actual coordinate space. It means the object still has the world space coordinate on (-2, 0, -3) in your code memory.

So, It's obvious how the translation matrix of camera should be constructed.


eye means the position of the camera in world space coordinate

the last step is the rotation, the very hard and agonizing one. Let's suppose another case. the camera is in (0,0,0), looking at an object located on (-2, 0, -3).

In this case, we don't need to translate the object,
because the camera is already on the origin.
However, it looks at the object, not at the -Z-axis.

So, we need to resolve this problem.
Think about the first restriction of 3D fake. We have to rotate the object anyway, not the camera.

If you imagine the scene that there is the object on the left side of the window, and you want to rotate your camera to the left side to look at the object, You have to rotate the object to the right side around Y-axis. It will be good to see this video for the further understanding. https://youtu.be/-tonZsbHty8?t=12m33s

In this stage, we have to know the axis rotation.
If you have standard vector of 3D space, (1, 0, 0), it points to X-axis.
Suppose you want to rotate this vector with unknown rotation matrix


So, the first column of the rotation matrix is pointing to X-axis. likewise, the second column of the rotation matrix is pointing to Y-axis, the third column to Z-axis.
Keep in mind this one to construct the rotation matrix.

And then, we have to know this one: the relationship between camera position and the target object can give us the information of camera local axes . We can get the picture of the camera pointing to somewhere with the information. Finally, after rotating the vectors of camera local axes into standard basis vectors, we can get right Lookat Matrix.
To be specific, If your camera look at the left side, you just have to rotate the object to the right side around World up Y-axis.

https://learnopengl.com/Getting-started/Camera
you can see what I mean on the Camera/View space section. To be simple, when you get the local axes of the camera, you have to align the axes with the standard basis vectors of 3D space, (1, 0, 0), (0, 1, 0), (0, 0, 1). If you align the axes along the basis vectors, you can get the right view of the object.

So, We suppose that the three vectors u, v, n are the information from the relationship.
and the vectors should be changed into the standard basis vectors by unknown rotation matrix.

it means that




u, v, n means the vectors from the relationship between camera and target object.
u connects to X-axis, v to Y-axis, n to Z-axis.

By the property of the matrix multiplication :





By the property of the orthogonal vectors



until here, we know what elements should be put on the rotation matrix. And now we have to know how to calculate the vectors from the relation ship.

the z-axis vector should be from target object to camera



and you should normalize this one, because we just need the orientation.

the x-axis vector should be calculate with the z-axis and world up-vector (0,1,0)


now, you can get the last one y-axis vector


Finally the Camera matrix is :



I tried this code and this code works well on OpenGL
glm::vec3 zaxis = glm::normalize(cameraPos - (cameraPos + cameraFront));
glm::vec3 xaxis = glm::normalize(glm::cross(cameraUp, zaxis));
glm::vec3 yaxis = glm::cross(zaxis, xaxis);

glm::mat4 matrix(1);
matrix[0][0] = xaxis.x;
matrix[1][0] = xaxis.y;
matrix[2][0] = xaxis.z;
matrix[0][1] = yaxis.x;
matrix[1][1] = yaxis.y;
matrix[2][1] = yaxis.z;
matrix[0][2] = zaxis.x;
matrix[1][2] = zaxis.y;
matrix[2][2] = zaxis.z;
matrix[3][0] = -glm::dot(cameraPos, xaxis);
matrix[3][1] = -glm::dot(cameraPos, yaxis);
matrix[3][2] = -glm::dot(cameraPos, zaxis);

view = matrix;

댓글 없음:

댓글 쓰기