Editable camera sensor size (meaningful focal length units)
Closed, ArchivedPublic


This patch allows editing the blender camera's sensor size, which affects the apparent field of view for a given lens focal length.

Previously Blender's camera was hardcoded to a sensor aperture width of 32mm, which doesn't reflect any commonly available real-world camera, meaning the focal length (mm) for the lens didn't resemble any real-world lenses whatsoever - pretty misleading when you can't choose a 50mm lens for example and expect it to match live action footage, or just photographic intuition.

more info on http://mke3.net/weblog/blender-sensor-sizes/



I noticed in a few places only the sensor_x is used, should this be changed to MAX2(sensor_x, sensor_y) ?

Since logically I would think the camera back could be portrait.

This would also crash:
+ if((*sensor_x)==0.0f || sensor_x == NULL)
+ (*sensor_x)= 32.0;

shouldn't be MAX2(), but rather an option to choose which of the horizontal or vertical FOV to fit to (other apps have this). However currently blender already does some funky auto-sizing for resolution aspect ratios - would need to figure out what impact that has and account for it, I didn't look into that much so far.

And good point re. the crash! Some older code I didn't clean.


For the BGE I can try to look at it after bconf. While testing I couldn't make the size_y to affect anything, is that dependent on the aspect ratio?

How about a Blender Default preset?

import bpy
bpy.context.object.data.sensor_x = 32
bpy.context.object.data.sensor_y = 18

It would be great if the vertical FOV could be exposed. Right now I have this in my .chan export/(import) script:

hfov = cam.data.angle ### radians
vfov = str(math.degrees(2 * math.atan(math.tan(hfov/2) * cam.data.sensor_y/cam.data.sensor_x))))

It could then skip the imported math functions and just have:

vfov = cam.data.angle_v

Thanks for working on this!

Any progress on seeing this in trunk?

sensor_sizes_updated.diff is the same original patch updated to a more recent svn revision.
sensor_sizes_bge.patch is the patch with the needed changes to work with the BGE.

Matt 2 comments:

1) As I commented before I don't see how the sensor_y is affecting the frustum. Therefore I'm only passing the sensor_x for the BGE frustum functions.
2) Sensor x or sensor width? In some parts I called it sensor_x and in other sensorwidth. Feel free to change it accordingly to what you think it's better.

I have updated the patch to work with the latest svn revision (34534)

It is the same as before, but I didn't touch:

This is the first time I've touched code and making a patch, so if something is wrong or missing please tell and I'll do my best to correct it!

Attached sensor_sizes_updated_again.diff

Hi again, sorry for spamming, but I got so excited about hacking that I've been up all night trying to do some more!

I got Vertical FOV working, so finally this can be set by the user! Not that I think many would jump on this, and I don't think there's a need to make it visible in the UI, but it is important for importing/exporting camera data. The new properties are Camera.angle_x and Camera.angle_y.

I also tried, without luck, to enable Matt's code for having the focus distance affecting the FOV. A bit to ambitious maybe, but at least Blender compiles without failing now on my systems (32bit Linux). Therefor I left my hacks in, and hopefully a kind soul will point out to me what I missed.

Also with my first patch I found out there were some nasty indentations, because I set up vim for Python. The good thing was I found out about :set list! :)

I hope the new patch isn't to bad code wise, and again please comment if there is anything. Next I will look at the BGE-patch, and then Collada/FBX/chan.

Updated the patch to new revision (35433)

This contains the original sensor sizes patch by Matt and my changes for accessible vertical FOV. I have made changes to the camera properties so that the focal length is always visible, and the toggle (lens_unit now called angle_unit) is used for showing either HFOV or VFOV.
This is also a "clean" patch, meaning there's no "hacks" by me trying to enable Distance_Affects_FOV.

Same as above, but with BGE changes by Dalai.
I went with sensor_x instead of sensorwidth, though.

Because of some changes of names (primarily angle_x instead of angle) I fixed it in the addons I could see was affected (light_field_tools, x3d, fbx, xna).
FBX and XNA look alike, and these have options for both HFOV and VFOV, but I didn't touch this even if it is possible now. Collada remains untouched for now.

Comments welcome!

This looks an amazing addiion to Blender.
However, how do you get the script to work in Blender 2.5? It just keeps saying invalid syntax.


Updated patch to revision 36330

This is identical to the previous patch including BGE changes.
I made a build for 32bit Linux (tested on Ubuntu 10.10):

I have spend some time testing FBX exported files in Nuke, Maya and Houdini. There's still some funky problems where the files work correctly in Maya, but in Nuke/Houdini the local Y rotation is wrong, and frame-start is 0 instead of 1. This is a bit out of scope for what this patch is for, but focal length, fov and sensor size settings are now exported correctly :) Turns out vertical fov was essential for FBX too!

@Thomas Wilshaw
Hi, this is not a script but code that needs to be compiled. The addon-scripts are dependent on these code changes. If you run 32bit Linux you can try the build above (in a virtual machine if needed).

Thanks, I'll wait until it's availble on Window, or is it going to be Linux only?


Hi Tom,

The code is cross-platform, it's just that I only use Linux so can't make builds for Mac/Windows. Luckily there are kind souls making builds for other platforms, like this one (win64):

Ultimately we would like to see this as a part of the official Blender, but in the mean time I hope you can try it out with the Windows build above.


Those are patches on the source code, not scripts. You'll either need to compile blender from source with the patches applied or wait for a windows build with those patches to become available.

Attached collada_r36330.diff

Like the unmodified FBX exporter, this will not export camera properties correctly. This is just so Blender compiles with OpenCollada without errors.

Hi Ejner,

Read and tested a bit this patch. As Campbell already said, it's very confusing line: if((*sensor_x)==0.0f || sensor_x == NULL). In case of sensor= NULL, it'll crash. *sensor_x == 0 meas. there's no value for sensor width. But how this could happen due to there's code in do_versions which prevents this for old files? Maybe we should restrict set zero-sized sensor_x?

Also played a bit with vertical size of sensors. Looks like it only updates Field of View in Camera buttons, but isn't used in 2d view/rendering. Is it supposed behavior and i misunderstood meaning of this option?

And what do you mean saying "this will not export camera properties correctly."? Would it just use old-school behavior or exported data would be kinda unpredictable?

Hi Sergey,

I will admit that I am not a programmer, and that I just copy/pasted most of what Matt originally coded. The line in question is probably unnecessary, and you are correct that this is taken care of in 'readfile.c' for old files. As I see it, nobody will ever set sensor_x to 0 unless it's a mistake, and if they do it is very obvious when rendering (at least it doesn't crash..).
I am equally wondering about the line: if((*lens)==0.0f). You cannot set lens to 0 at all, so what is that line for? A way to to fix it for sensor_x/sensor_y could be to change in 'rna_camera.c' the line: RNA_def_property_range(prop, 0.001, FLT_MAX) to RNA_def_property_range(prop, 1.0f, FLT_MAX). Then it would always default to minimum 1mm (no sensor in the world is that small anyway).

The vertical sensor size affects the vertical FOV, obviously, but the reason you can't see the effect in rendering is because Blender only uses the render resolution, which will always fit horizontally. Ideally we should be able to define how the the resolution fits inside the sensor (resolution gate), but this is beyond my coding abilities... So to answer your question, yes this is expected behavior. If you look through the camera and choose the "Sensor" display option, you can see what it does.

Regarding exporters, they have never exported camera properties correctly, meaning you can't assume that what you see in Blender is what you'll see in other apps (the FOV is wrong). I fixed this in the FBX exporter*, but because Collada is new to me and I can't test it properly yet, I only fixed some names so Blender could compile without errors when enabling OpenCollada. This doesn't change how it worked before since the exported FOV have always been wrong. I of course would like to fix this, just as I did with FBX.

* I just need to figure out how to create a "Focal length" animation channel in the exporter, since this is the last important camera feature.

Thank you for looking at this patch, Sergey! Do you want me to create a new patch with the sensor_x = 0 issue fixed?

Updated to revision 36505

I removed the if((*sensor_x)==0.0f || sensor_x == NULL) lines, and changed it so sensor_x/sensor_y cannot be less than 1.0.

Thank you! Pardon for not answering so long -- got long TODO list..
Will re-read patch soon and wil ltry find out way to get sensor_y working in more expectable way.

Hi Sergey!

It's alright, I can imagine you have a lot on your plate.

What do you mean by "get sensor_y working in more expectable way"? How do you think it should work? For me sensor_y is only important to get the vertical FOV value, which is used by exporters.

I'm really happy that you look at this basic but important function! Please tell me if there is anything you want me to do.

Looks like sensor_y changes for UI only, renderer isn't affected with it. Or it shouldn't?

Right, sensor_y doesn't affect rendering, because rendering is controlled by render resolution, not sensor size. Other 3D apps gives the choice of how the render resolution fits inside the sensor aspect, or bypass the render resolution all together, but in Blender this is always a horizontal fit (like HD resolution inside a 1.5 device aspect ratio is 1920 pixels wide, but not 1280 pixels high). This is OK and expected behaviour (in Blender), and most choose horizontal fit anyway.

It really gives more sense by illustrating it, so I will try to cook together an image explaining this.

Even if the effect of sensor_y is not that clear, it is still very important. In this new basic camera sensor_y fulfils its purpose by providing the correct vertical FOV. Later we can think about stuff like resolution gate. In my opinion.

Attached image briefly explaining resolution gate.

Hope the image makes sense as it's not in depth... As I said in my last comment, I think resolution gate should be tackled by another patch. Ultimately it is something that needs to be done, and I think it probably will be more invasive than this sensor patch.

Updated to revision 36625

Works now with camera Composition Guides recently committed to trunk.

Updated to revision 37468

Only changes in addons: io_anim_camera.py and import_x3d.py

I have made some example .blends to explain more visually:

And here's an Ubuntu 11.04 64bit build:

I wrote this on bf-committers, but should probabyl mention it here:

Hi guys, sorry to have not been keeping track of this stuff, I've been busy. I'll try to make time to look at the updated patch on the weekend (hopefully). As far as I can see right now from a cursory glance, all that's needed is to make blender's internal camera respect the vertical/horizontal FOV settings - from memory right now it's done automatically based on the longest render dimension.

Hi all,

I've just commited this patch to my tomato branch. Would handle all requests, bug fixes and so on there.
Unfortunately, i can't commit changed to addons yet -- they aren't branched yet. As soon as we'll be ready to merge tomato in trunk it'll be easy to do.

Thanks everyone for your work on this patch!

Sergey Sharybin (sergey) closed this task as "Archived".Jul 14 2011, 5:26 PM