Looking at the Wikipedia page for Circle of Confusion, and at such posts as this one, I completely understand how to calculate the values for near, far, focal planes and hyperfocal distance. I am also aware of the Zeiss formula for my desired format.

What I'm trying to find out is how to take real camera parameters (focal distance, aperture, focal length) and get a blur radius or similar usable value to configure a blur with them.

Currently, I'm simply using this function:

float getBlurSize(float depth, float focusPoint, float focusScale) {
    float coc = clamp((1.0 / focusPoint - 1.0 / depth)*focusScale, -1.0, 1.0);
    return abs(coc) * MAX_BLUR_SIZE;
}

All real-world inputs are available to the shader - Aperture f-Number, focal distance, format dimensions (35mm in this case), maximum acceptable CoC from the Zeiss formula, focal length etc., as well as depth and colour. Currently, I am applying the calculations and blur in post.

up vote 3 down vote accepted

First we can calculate the physical diameter of CoC in the image plane, given the lens parameters. This equation is from Wikipedia – Circle of confusion: $$ c = {|S_2 - S_1| \over S_2} {f^2 \over N(S_1 - f)} $$ where the variables are:

  • $c$: the physical CoC diameter in the image plane
  • $S_1$: focal distance (the distance at which a subject would be in perfect focus)
  • $S_2$: actual distance to the subject (the point whose CoC we are calculating)
  • $f$: the focal length of the lens
  • $N$: the f-number at which the lens aperture is set.

Then, divide this CoC diameter by the film or sensor frame size to get the blur diameter in texture coordinates. You can additionally multiply it by your rendering resolution to get the blur diameter in pixels if desired.

As an example calculation, suppose we render a 1920×1080 image, as if through a 85mm lens at f/1.4, on a 35mm camera (frame size 36×24 mm), and focused at 3m while our subject is 5m away. Then we can calculate: $$ {|5\text{m} - 3\text{m}| \over 5\text{m}} {(85\text{mm})^2 \over 1.4(3\text{m} - 85\text{mm})} {1920\text{px} \over 36\text{mm}} $$ (Don't forget to convert units, since we are mixing meters and millimeters here!) I get a blur diameter of ~38 px, so the radius would therefore be ~19 px.

  • I almost get the same result, but even with Wolfram Alpha I get 37.77 pixels, and 0.7082 mm with your example. Also, when using focal length in millimetres, a huge scaling occurs as the focal plane in metres reaches it. When graphed as such, desmos.com/calculator/mlblfdvknw, it's noticeable. Is there a way to convert the units properly? – Local Crab Enthusiast Aug 7 at 9:32
  • Sorry, I should've been more explicit. One way to do it is to convert all the millimeters to meters by dividing by 1000. Be sure you do that before squaring or any other operation. You're right about the 37.77, I must have typo'd it when I did the calculation initially. – Nathan Reed Aug 7 at 18:50
  • And here's an updated version of your graph with the conversions: desmos.com/calculator/j2gcokbykz – Nathan Reed Aug 7 at 18:59
  • Many thanks! I was going from M to MM but I hadn't adjusted the scales properly – Local Crab Enthusiast Aug 8 at 21:00
  • So...will you accept the answer again, since it seems to work now? :) – Nathan Reed Aug 10 at 3:03

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.