I am trying to implement a UVN free camera for browsing the 3D space of my OpenGL simulation and I noticed the perspective is introducing some sort of distortion. I observed it is more noticeable close to the border of the window and consequently far away from its center.
When inspecting the space employing an orthographic projection I notice no problems but when I switch to the perspective projection something odd happens. I have attached an image of the problem I am experiencing.
Each tile in the image is squared, with edges of length $e$, however, when rotating or simply translating the camera I can spot points of view from which tiles appear to be rectangular.
When I remove the plane and draw the three vectors $(1, 0, 0)e'$, $(0, 1, 0)e'$, and $(0, 0, 1)e'$ $(e'=3*e)$, I can spot perspectives from which the three do not appear to be orthogonal.
I implemented quaternion-based rotation and the problem can be perceived when rotating.
I also tried rotating the camera via the lookAt()
method and a pair of angles but the problem is still there.
I spent a few days checking my calculations and I couldn't spot anything wrong. My matrices are computed on the CPU and are row major, when set as uniforms they are transposed.
This is my code for setting up the perspective matrix.
GLfloat
VFOV = GLfloat(tan(radians(verticalFieldOfView / GLfloat(2.0)))),
aspectRatio = GLfloat(width) / GLfloat(height);
Matrix4<GLfloat>::identity();
Matrix4<GLfloat>::elements[0][0] = +1.0f / (VFOV * aspectRatio);
Matrix4<GLfloat>::elements[1][1] = +1.0f / VFOV;
Matrix4<GLfloat>::elements[2][2] = (-Zfar - Znear) / (Znear - Zfar);
Matrix4<GLfloat>::elements[2][3] = +(2.0f * Zfar * Znear) / (Znear - Zfar);
Matrix4<GLfloat>::elements[3][2] = +1.0f;
Matrix4<GLfloat>::elements[3][3] = +GLfloat(0.0);
The image above has been captured with a FOV=30°.
Translation of the camera is achieved (inefficiently but simply) via the product with the translation matrix (identity with the fourth column having the column vector set to $-position$ of the camera).
I am not sure whether such distortion can be mitigated by the model, hence I don't know whether I am looking for a bug or I am fighting against a limitation of the camera model.
At this point, I have three questions:
- Is the distortion I am perceiving due to the perspective?
- If it is, is it to be expected (can not be prevented via such a simple model)?
- Which model could account for it and correct it?
All help is appreciated.