How to calculate field of view to preserve aspect ratios

215 Views Asked by At

I have a game where there is a fixed camera pointing at a 2D plain

enter image description here

It has been designed to fit perfectly for a 1920 x 1080 resolution.

If the users chosen display ratio changes I want the 2D plain to maintain its aspect ratio so that there will be black bars in areas where the field of view needs to capture more than just the plain.

My approach was I used the base aspect ratio as the benchmark and I tried using an aspect ratio differential as a multiplier:

double _rootAspectRatio = 1.777885; // (1920 x 1080)
double _rootFieldOfView = 55;

double aspectRatio = (double)Screen.width / (double)Screen.height;

double fieldOfViewPerAspectRatio = _rootFieldOfView / _rootAspectRatio;

double aspectRatioDifference = _rootAspectRatio - aspectRatio;

_mainCamera.fieldOfView += (float)(aspectRatioDifference * fieldOfViewPerAspectRatio);

This worked for a good chunk of resolutions but then it failed in some others e.g. 2436 x 1125 (in this case the camera is way to close).

Can you advise me a better way to calculate what the field of view should be when changing resolutions knowing that I want it to preserve the aspect ratio of 1920 x 1080?

Thank you.

1

There are 1 best solutions below

0
On BEST ANSWER

I found a solution:

void adjustCameraToFixScreen()
    {
        // set the desired aspect ratio (the values in this example are
        // hard-coded for 16:9, but you could make them into public
        // variables instead so you can set them at design time)
        float targetaspect = 16.0f / 9.0f;

        // determine the game window's current aspect ratio
        float windowaspect = (float)Screen.width / (float)Screen.height;

        // current viewport height should be scaled by this amount
        float scaleheight = windowaspect / targetaspect;

        // if scaled height is less than current height, add letterbox
        if (scaleheight < 1.0f)
        {
            Rect rect = _mainCamera.rect;

            rect.width = 1.0f;
            rect.height = scaleheight;
            rect.x = 0;
            rect.y = (1.0f - scaleheight) / 2.0f;

            _mainCamera.rect = rect;
        }
        else // add pillarbox
        {
            float scalewidth = 1.0f / scaleheight;

            Rect rect = _mainCamera.rect;

            rect.width = scalewidth;
            rect.height = 1.0f;
            rect.x = (1.0f - scalewidth) / 2.0f;
            rect.y = 0;

            _mainCamera.rect = rect;
        }
    }