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: http://zach.in.tu-clausthal.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/ 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\$
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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.