Jump to content
  • Advertisement
Sign in to follow this  
Dranith

y-fov in perspective matrix creation functions

This topic is 4212 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!