Hi all,
I'm trying to figure out some maths at the moment, and was hoping someone might know what happens inside the theoretical camera lens...
What I'm trying to get a function for is, for a specified focal length/aperture, focused to a specified distance away, what sized area on the image plane will a point at a different specified distance be.
I'm planning on making a Defocus node where you set the defocus based on camera, lens and location information rather than just a pixel size.
I need to do a bit more checking on this, but this is what I understand so far:
The f/stop is defined as a ratio between the physical aperture and the focal length of the lens. So the actual aperture opening is the equivalent of:
aperture diameter = focal length x f-stop aperture distance (from image plane) = focal length
My question is this:
In this simplified model of the lens, where is the theoretical refraction point? There has to be some plane where the light rays are bent to ensure that they converge on the image plane. Is this fixed down, or can it vary between lenses? If it can vary between lenses, does this mean that different makes of lenses at the same focal length and aperture can have different sized bokeh?
I'm hoping that it will turn out that a lens can be simulated by bending the rays at the actual aperture plane, but it may well be a little more complex than that.
Thanks for any advice on this!
Edit: Solution
Thanks to Matt T for help on this one. I've put my Shake node below, for anyone who's interested.
This node allows you to specify the size and resolution of the sensor/film back. I didn't have the specs of the 35mm film back size to hand - I made it default to 24mmx18mm, which is close enough for now. You can also specify from a drop-down list what your units for focus and object distance are (all other units - sensor size, focal length - are assumed to be in mm)
CameraDefocus.h:
image CameraDefocus(image in = 0, float focalLength = 50, float fStop = 2.8, string distanceUnits = "feet", float focusDistance = 25.0, float objectDistance = 10.0, int sensorPixelsX = GetDefaultWidth(), int sensorPixelsY = GetDefaultHeight(), float sensorWidth = 24, float sensorHeight = 18.0)
{
Defocus1 = Defocus(in, defocusDiameter / pixelWidth, defocusDiameter / pixelHeight,
"rgba", 100, "circle", 0.95, 1,
float pixelWidth = sensorWidth / sensorPixelsX,
float pixelHeight = sensorHeight / sensorPixelsY,
float distanceMultiplier = distanceUnits=="meters"?1000:distanceUnits=="feet"?304.8:distanceUnits=="inches"?25.4:1,
float focusDistanceMM = focusDistance * distanceMultiplier,
float objectDistanceMM = objectDistance * distanceMultiplier,
float m = ((focusDistanceMM * focalLength) / (focusDistanceMM - focalLength)) / focusDistanceMM,
float defocusDiameter = ((focalLength * m) / fStop) * (fabs(objectDistanceMM - focusDistanceMM) / objectDistanceMM)
);
return Defocus1;
}
CameraDefocusUI.h:
nuiPushMenu("Tools");
nuiPushToolBox("Filter");
nuiToolBoxItem("@CameraDefocus",CameraDefocus());
nuiPopToolBox();
nuiPopMenu();
nuiDefSlider("CameraDefocus.focalLength",0,500,1);
nuiDefSlider("CameraDefocus.fStop",0,50,0.1);
nuxDefMultiChoice("CameraDefocus.distanceUnits", "meters|millimeters|feet|inches");
nuiDefSlider("CameraDefocus.focusDistance",0,1000,-1);
nuiDefSlider("CameraDefocus.objectDistance",0,1000,-1);
nuxDefSlider("CameraDefocus.sensorPixelsX",0,GetDefaultWidth(),1);
nuxDefSlider("CameraDefocus.sensorPixelsY",0,GetDefaultHeight(),1);
nuxDefSlider("CameraDefocus.sensorWidth", 0, 50, 0.1);
nuxDefSlider("CameraDefocus.sensorHeight", 0, 50, 0.1);
