Sign in to follow this  
Dranith

y-fov in perspective matrix creation functions

Recommended Posts

Some friends and I were talking about how both glu and d3dx matrix creation functions take the fov in the y direction, instead of the possibly more intuitive x direction. We then started wondering why this is. I hit up Google a bit and couldn't really find an explanation of why y-fov is used. Is it just something that is because of some convention set long ago?

Share this post


Link to post
Share on other sites
Quote:
Original post by Dranith
Some friends and I were talking about how both glu and d3dx matrix creation functions take the fov in the y direction, instead of the possibly more intuitive x direction. We then started wondering why this is. I hit up Google a bit and couldn't really find an explanation of why y-fov is used. Is it just something that is because of some convention set long ago?
I don't know why these functions work with the vertical rather than horizontal field of view (although I imagine there's a good reason). You can easily convert between horizontal and vertical fields of view if needed though. Here's a pair of functions that performs these conversions:
/** Convert horizontal field of view to vertical field of view. */
template < typename T >
T xfov_to_yfov(T xfov, T aspect) {
return T(2.0 * std::atan(std::tan(xfov * T(.5)) / double(aspect)));
}

/** Convert vertical field of view to horizontal field of view. */
template < typename T >
T yfov_to_xfov(T yfov, T aspect) {
return T(2.0 * std::atan(std::tan(yfov * T(.5)) * double(aspect)));
}

Share this post


Link to post
Share on other sites
Quote:

template < typename T >
T xfov_to_yfov(T xfov, T aspect) {
return T(2.0 * std::atan(std::tan(xfov * T(.5)) / double(aspect)));
}

template < typename T >
T yfov_to_xfov(T yfov, T aspect) {
return T(2.0 * std::atan(std::tan(yfov * T(.5)) * double(aspect)));
}


ummm... doesn't this boil down to:


template < typename T >
T xfov_to_yfov(T xfov, T aspect) {
return (xfov / aspect);
}

template < typename T >
T yfov_to_xfov(T yfov, T aspect) {
return (yfov * aspect);
}


am i missing something?

Share this post


Link to post
Share on other sites
Yeah, I'm more interested in where or how the convention started.

On a side note though, how is that different from a simple yfov = xfov/aspect? For values < pi, 2*atan(tan(rad/2)) == rad

Share this post


Link to post
Share on other sites
Quote:
Original post by godecho
ummm... doesn't this boil down to:
template < typename T >
T xfov_to_yfov(T xfov, T aspect) {
return (xfov / aspect);
}

template < typename T >
T yfov_to_xfov(T yfov, T aspect) {
return (yfov * aspect);
}
No, the relationship between the horizontal and vertical fields of view is not linear with respect to the aspect ratio.

Share this post


Link to post
Share on other sites
Try it out.

Starting with a desired 90 degree xfov:

yfov = 2*atan(tan(pi/4))/(4/3) = 1.178 = (pi/2)/(4/3) = xfov/aspect

4/3 being for a standard resolution. The above holds true for any degree fov <180.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dranith
Try it out.

Starting with a desired 90 degree xfov:

yfov = 2*atan(tan(pi/4))/(4/3) = 1.178 = (pi/2)/(4/3) = xfov/aspect

4/3 being for a standard resolution. The above holds true for any degree fov <180.
I think you're misreading the parentheses in my posted example (understandable - it's not very clear).

If you're still unconvinced, I'll try to post a derivation later this evening.

Share this post


Link to post
Share on other sites
Here's a quick, informal derivation of the yfov-from-xfov equation (the derivation of the opposite conversion is similar):
w = ( width of view volume at near plane) / 2
h = (height of view volume at near plane) / 2
n = distance to near plane
aspect = w/h
tan(xfov/2) = w/n
tan(yfov/2) = h/n

yfov = 2*atan(h/n)
yfov = 2*atan((w/n)/(w/h))
yfov = 2*atan(tan(xfov/2)/aspect)

Share this post


Link to post
Share on other sites
Haha, yes I did read the parenthesis wrong. I worked it out by hand and indeed got what you posted above. Sorry about that.

Edit : Ah, I see you posted a derivation as well. Now if you could just tell me why the convention is to use y-fov! =)

Share this post


Link to post
Share on other sites
Quote:
Original post by Dranith
Now if you could just tell me why the convention is to use y-fov! =)
Hehe, I wish I knew :) I'm sure someone here on GDNet knows the answer to this question though...

Share this post


Link to post
Share on other sites
A different friend of mine mentioned that when they have talked about cameras in 3d graphics in classes he has taken, they usually build up the model for the projection matrix starting with the idea of a pinhole camera. Seeing as how the diagrams illustrating this concept are usually drawn from the side, he suggested that may be the source of the convention. Sounds plausible to me.

Share this post


Link to post
Share on other sites
My opinion (which, incidentally, was what caused me to rewrite my engine's camera FOV stuff recently) is to better support widescreen type aspect ratios. If you use horizontal FOV rather than vertical FOV and you change your aspect ratio from, say, 4:3 to 16:9 then you end up seeing LESS vertically rather than seeing MORE horizontally. At least, that's the way it worked for me - and I now seamlessly and easily support widescreen in my engine. Hope this helps.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dranith
Haha, yes I did read the parenthesis wrong. I worked it out by hand and indeed got what you posted above. Sorry about that.

Edit : Ah, I see you posted a derivation as well. Now if you could just tell me why the convention is to use y-fov! =)


hah. did the same thing, my mistake jyk.

Share this post


Link to post
Share on other sites
Yeah Rompa has what I believe to the best answer: arguably widescreen should expose more horizontally, rather than less vertically assuming the viewer distance to monitor does not change. Of course this is a somewhat subjective decision as well, but widescreen ratios seem to "make more sense" visually, and thus they should probably be the first class citizens, with 4:3 ratios seeing less on the sides. Movies have adopted this convention, and NVIDIA's "XHD" as well.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this