3
\$\begingroup\$

I am working on a personal project and I got a 3d viewport with moving camera working nicely. Now I am working on being able to freeze the time and switch to a debug camera and move in the game freely. In order to do so I also wish to see where the original camera is and what the frustum is. I started by creating at the origin the camera shape and compute the proper frustum. enter image description here

The camera frustum is the result of a vertical angle of view of 30 degree, near plane 100, far plane 5000. (no particular reason behind those value).

Those values are the exact same of the flying camera so I would expect if i put the camera at the origin, pointing in the same direction (-z), the frustum should match the screen size.

Unluckily that doesnt happen here is the result I get: enter image description here

If in the frustum point calculation I scale the fov by 2.75~ I get the right size, no idea if that number has a specific meaning. I am quite sure the frustum is correct, I say that because if I do atan(plane-width/2 / near) I get half the fov*window ratio. Same for far plane, which is correct. That lead me to think it might be a problem just in the visualization.

I use glm to compute both look at and perspective:

mat4 Camera3dPivot::get_world_view_matrix() const
{
    //just computing and returning the camera
    mat4 look = lookAt(m_pos , m_pivot, vec3(0.0,1.0,0.0));
    return look; 
} 

mat4 Camera3dPivot::get_projection_matrix() const
{
    //computing perspective

    mat4 temp44= perspective(m_fov,((float)m_width/(float)m_height),m_near,m_far);
    //flipping the perspective to avoid upside down effect
    temp44[0][0] *=  -1.0f ;
    temp44[1][1] *=  -1.0f ;
    return temp44;
}

After that the MVP matrix is nothing more that proj * lookM.

view_to_proj_matrix = projection_matrix* model_to_view_matrix;

So far the camera worked really nicely, no glitches or artefact I am aware of, so I am quite confidant in the code both cpu and shader. (shaders are the most basic one you can imagine, i can post them if needed).

This is how I compute the frustum:

Camera3dPivot* cam = (Camera3dPivot*)m_cam;
float angle = cam->get_fov()* (M_PI / 180.0);

float near =cam->get_near_plane(); 
float hnear = 2.0f*tanf(angle / 2) *near;
float wnear = hnear * cam->get_ratio();


float far = cam->get_far_plane()*0.9;
float hfar = 2.0f*tanf(angle / 2) * far;
float wfar= hfar * cam->get_ratio();

float hnearhalf = hnear / 2.0;
float wnearhalf = wnear / 2.0;

float hfarhalf = hfar / 2.0;
float wfarhalf = wfar / 2.0;

There is only one camera in the scene. The flying one, the drawn camera is just a not transformed drawn of the flying camera.

I went through the code several time checking the data and everything is fine and makes sense, from the angles, to the aspect ratio of the viewport etc.

So I am starting to think I am actually missing something, also because it has to work, since if I replicate the same exact scenario in maya the frustum matches the viewport. Although I might try to see if maya gives me the points of the frustum and compare them with mine.

Any help on the matter is appreciated. PS: this is the tuorial i looked at for the frustum calculation: View Frustum Culling Tutorial PPS: I am also sure i am inputting the right angle, glm::perspective I feed degrees , tanf I feed radians, you can see the conversion in the frustum code.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Looks like that by luck I found the solution to the problem. I really don't like the glm documentation, was my understanding that glm doc was intentionally skinny since it matches corresponding glsl and glut. Anyway documentation is a mess.

doc v 0.92 doesnt specify what unit to use, the gluPerspective uses degree, so that's why I used degrees.

doc v0.94 says is degree but if you define a macro you can use rad. doc v0.97 looks finally much better and now only states radiants. To be honest I downloaded the repo a while ago so I don't know what version i have (i removed glm git folder from my own repo). So I checked directly the source code and found: /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.

Which I found it really confusing. Anyway: TL;DR , switched to radians in glm::perspective all good.

Cheers

M.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .