Search Unity

Adjust FOV based on aspect ratio - how?

Discussion in 'General Discussion' started by larku, Jun 7, 2017.

  1. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Hey all,

    If I have a camera setup with my reference configuration at 1080x1920 (9x16 portrait aspect ratio) with an FOV of say 30. How can I calculate the FOV (at runtime) for different aspect ratios?

    I want the FOV calculated to give the same visual size appearance (size of objects).

    I see that there's no linear relationship between the two so I assume some trigonometry or similar is needed.

    Any hints?
     
  2. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,573
    You need to decide which fov is more important for you - horizontal or vertical one, and then take it from there.

    Standard "Width/Height" Aspect ratin can be calculated as
    Code (csharp):
    1.  
    2. aspectRatio = tan(hFov * 0.5f)/tan(vFov*0.5f);
    3.  
    Where hFov is horizontal fov and vFov is vertical one.

    so vFov from hFov would be:
    Code (csharp):
    1.  
    2. vFov = 2.0f*atan(tan(hFov*0.5f)/aspectRatio);
    3.  
    and hFov from vFov will be:
    Code (csharp):
    1.  
    2. hFov = 2.0f*atan(aspectRatio*tan(vFov*0.5f));
    3.  
    You could also try:
    Code (csharp):
    1.  
    2. aspectRation = hFov /vFov;
    3.  
    BUt IIRC this is for fisheye camera and for the normal computer videogame one.
     
    Martin_H and larku like this.
  3. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Thanks neginfinity!

    I'm not sure where the vFov will come from here - I'm just referencing the camera.fieldOfView which I assume is the hFov.

    So the information I have is:

    at 9:16 (1080x1920) I have a desired fov of 30 set on the camera in unity.

    If I switch to landscape (for example) I want the objects on the screen to remain "the same physical size" as such I want to choose an fov that will do this.

    I also want it to work that if I have a 4:5 aspect ratio it will also work.

    Does that sound doable?
     
  4. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,573
    As per unity documentation, camera's field of view is vFov and hFov is calculated based on viewport aspec ratio.
    https://docs.unity3d.com/ScriptReference/Camera-fieldOfView.html

    Meaning a wider screen will give wider horizontal field of view.

    Isn't it done automatically? Their size (relative to screen height) should remain the same by default, but horizontal field of view will be either clipped or extended at the sides.
     
    Thorlar likes this.
  5. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Aha, well that's where I've left out the detail I suppose :)

    What I'm really calculating here is the minimumFov - I use this to allow the user to zoom in up to a certain FOV. As such the camera isn't really set to this value, but instead I'm clamping the fov between a min and max during zooming. It's the min FOV I really need. For example, if I had a min fov of about 12 at 9:16, I need it to be about 7 at 16:9..

    Does that make sense?
     
  6. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,573
    If Aspect Ratio > 1 (PC, width > height), plug in fov as camera fov as is.
    If Aspect Ratio < 1 (Mobile in vertical mode - height > width), use desired fov as hfov, and calcualte vFov (which is set onto camera.fov), using one of the previous formulas.
     
  7. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422

    Thanks - worked perfectly!
     
  8. danBourquin

    danBourquin

    Joined:
    Nov 16, 2016
    Posts:
    34
    I was wondering how Unity team handle the transformation frome Horizontal to Vertical FOV so I just take a look inside the source code of the CameraEditor.cs and funny thing there's a built-in method to transform from one to the other.
    Code (CSharp):
    1. public static float VerticalToHorizontalFieldOfView(float verticalFieldOfView, float aspectRatio);
    2. public static float HorizontalToVerticalFieldOfView(float horizontalFieldOfView, float aspectRatio);
    Link to documentation : Link1 and Link2
     
    ChanzDog likes this.