8 Feb 2019

Challenge

Our main goal was to make the object have real-world size on screens of different dimensions. Meaning, a user could take a ruler and measure it right on the screen. For instance, we set a size of 2 cm for a particular object. Obviously, if we measure it with the ruler, it should have the same size of 2 cm on the screen. Additionally, we needed it to work on all possible platforms – mainly, for Standalone and Mobile (iOS and Android).

Solution

At the very beginning, we have brainstormed what techniques it was possible to use before implementing the solution. We splitted the problem into smaller ones to solve each of it one by one.

The first complication was to find a physical pixel size. That would allow us to find how many pixels the required object must be rendered with. We have tried a few ways of calculating the pixel size without entering any parameters of the user’s monitor. As a start, we took the DPI (dots per inch) of a screen using Unity3D API. But the issue we had faced after was that it didn’t work on Android and could return wrong values. Thus, we needed to find another solution to the problem.

The solution we came up with was to ask a user to enter his screen’s diagonal and then calculate the width and height in inches/centimeters. Knowing the diagonal we could calculate the sides of the screen:

Once we know the pixel size, it becomes a piece of cake to show an object on the screen in real-world size. And it doesn’t matter whether we want to show a 3D object or 2D object. take the camera frustum into account to calculate how much screen space is taken by 1 unity meter

Basically, we need to take the camera frustum into account to calculate how much screen space is taken by 1 unity meter. To do that we should know at which distance an object is placed on the screen. For example, here we see the white plane which appears for the intersection of the camera frustum. The blue square represents which part of the plane is shown on the screen.

To calculate what size in Unity3D units the blue square is we must use the following formula:

h =2*d*tan(fov*0.5*dtr) ,

where h – height of the blue circle, d – distance from camera to the camera to an object, fov – field of view of the camera, dtr – degrees to radians constant as tan() – the function requires a value in radians.

So, we calculate the height of the blue circle and then use the camera aspect ratio (screen aspect ratio) to compute the width. The resulting values are measured in Unity3D meters (units). Then we simply use the pixel size and the units to reckon how much space in the 3D world an object should take.

On the screenshot below you can see a blue square outlining the white plane. It’s the representation of the blue outline on the small Camera Preview window which is pointed out with the red arrow: