Search code examples
c++openglrenderingglm-mathperspectivecamera

Is glm::perspective's fov parameter defined as half the angle of the field of view?


I'm at the optimization phase of a renderer I've been writing in OpenGL, and my next step is to cull everything I can't see. When reading this and other resources, I see the visual depiction of the frustum like:

Frustum

Image from: https://www.scratchapixel.com/images/upload/perspective-matrix/camsetup1.png

And therefore thought that we pass something like glm::radians(90.0f). However I started running into culling problems with my algorithm because I thought that I'd be going 45 degrees along the left and right for the planes... but then I started getting false-positive culling. As soon as I changed it to using the fov angle passed to glm::perspective then culling starts working fine.

However there's two things I'm unsure about:

  1. Is what I said correct? As in the fov value should be half of the green angle in the image posted above?
  2. If (1) is true then why does a fov of 90 not show me everything to my left and right?

These are important for me to understand because I want to make my culling algorithms cull as much as possible without false positives. As you may be able to guess, I was getting false positive culls because I thought "I need to divide the first argument I use for glm::perspective() again by two to get half of the angle" which caused a tighter frustum that would cull a lot more than it should have.

The way I'm culling currently is to calculate the left and right edges of the frustum and culling any 2D lines that can't be seen by the left or the right edges (as if they were line segments) through dot products. This is why a narrower angle was giving me grief. As an aside, if there is a better way of doing this let me know, though I figure two dot products is probably the cheapest I'm going to get with respect to efficiency of calculations for a line I have to check.


Solution

  • The fov parameter of glm::perspective is the angle from the bottom to the top (y axis) of the view frustum.
    If the view port is rectangular and the width of the viewport is greater then the height (and fov < 180°), then the angle from the left to the right is greater than the angle from the top to the bottom:

    aspect = width / height
    fov_x  = atan(tan(fov_y/2) * aspect) * 2