Cannot correctly compute 3dView FOV since Blender 2.8

Hi,

I’m trying to update an addon for 2.8. At some point, this addon compute the 3Dview FOV from focal lens. The original code works great, it uses the same constants and equations than used in Blender’s source code. The FOV equation uses a sensor width of 32mm (hardcoded value), then the angle value is corrected because the 3dview have an hardcoded zoom factor of 2.

With the FOV value it’s easy to compute the real horizontal distance covered by the 3dView. The script bellow illustrate the FOV calculation for a sensor width of 32mm, a focal lens of 50mm and a camera distance fixed to 10 meters.

import math

distance = 10
aperture = 32
focal = 50
zoom = 2

fov = 2 * math.atan(aperture / (focal*2) ) #standard fov equation
fov = math.atan(math.tan(fov/2) * zoom) * 2 #zoom correction (see source code)
realw = math.tan(fov/2) * distance * 2 #simple trigo

print(math.degrees(fov), realw) #(65.2, 12.8)

For verifying these values, I reproduce the setup in the 3d view with another script and then I measure the horizontal distance with the ruler : in Blender 2.7 it gives me the correct distance (12.8m), but in 2.8 I get about 14.4m.

import bpy

for area in bpy.context.screen.areas:
    for space in area.spaces:
        if space.type == 'VIEW_3D':
            s = space

s.lens = 50
r = s.region_3d
r.view_location = (0, 0, 0)
r.view_rotation = (1, 0, 0, 0)
r.view_distance = 10

checking the source code give me no clue about the origin of this difference. The relevant parts of the source code are

File DNA_camera_types.h

#define DEFAULT_SENSOR_WIDTH 32.0f
#define DEFAULT_SENSOR_HEIGHT 18.0f

File BKE_camera.h

#define CAMERA_PARAM_ZOOM_INIT_PERSP 2.0f

File view3d_utils.c

lens = v3d->lens;
sensor_size = DEFAULT_SENSOR_WIDTH;
zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
angle = focallength_to_fov(lens, sensor_size);
/* zoom influences lens, correct this by scaling the angle as a distance (by the zoom-level) */
angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;

File math_rotation.c

* lens/angle conversion (radians) */
float focallength_to_fov(float focal_length, float sensor)
{
  return 2.0f * atanf((sensor / 2.0f) / focal_length);
}

Any help will be appreciate !

1 Like

I know this is a year-old thread, but was it the aperture? Its 36mm in my 2.8x scenes, not 32, and is user-settable so shouldn’t be hard-coded in your script.

Thanks for this answer, you’re right the 3dview sensor width is now 36mm ! Seems like I didn’t browse the right branch when checking the source code. Finally I found the commit :
https://developer.blender.org/rBbcf6cc1f6b5f16ec37651ff6b0964fd91a60a59b

Problem solved !

Indeed the aperture of a camera object can be set but not the aperture of the 3d view (outside camera), this value is hardcoded in Blender source code :
https://developer.blender.org/diffusion/B/browse/master/source/blender/makesdna/DNA_camera_types.h$174