Sign in to follow this  
nico92

depth of field coc questions

Recommended Posts

Hi all !

 

I'm currently trying some various graphics techniques and I have some questions regarding the depth of field and more specially about computing the COC...

 

I use this computation for the COC : A * (F*(P-D)) / (D*(P-F)) where A = aperture diameter, F = Focal length, P = Focus Plane and D = object distance. (Note that I saw some paper using D-P instead of P-D in the first part, not sure which one is the good one ...)

 

A, F and P come from the camera settings and D is the taken from the depth buffer but I'm having problems with the computed size ... If my engine unit is 1 = 1m I need to convert the other parameters to the same unit correct ? (that means aperture size from mm to m, same for F and P) 

 

Also using the 1st equation should give me the same result as using the CoCScale & Bias when using the raw z right ?

 

Thanks !

Share this post


Link to post
Share on other sites
Okay let's try this again...
 
You definitely want to be careful with your units, and make sure that they're consistent. I prefer to have the UI present certain parameters in millimeters, and then convert to meters before sending them to the shader so that the shader can work in meters. If you have everything in meters, you can compute the CoC from your depth buffer like this:
 
// Compute the depth in meters
float z = Projection._43 / (zw - Projection._33);
 
// Compute CoC in meters
float coc = -ApertureSize * (FocalLength * (FocusDistance - z)) / (z * (FocusDistance - FocalLength));
 
// Convert to pixels
coc = (coc / FilmSize) * DisplayWidth;
 
The first step takes non-linear z/w from the depth buffer and converts it to linear view-space z, which is the depth you want to work with. The second step computes the CoC size in meters from this depth value. Note that I negate the equation in order to produce a signed value such that negative values are from the near field, and positive values are from the far field. This can be useful for shader-based DOF approximations, however if you don't care about this you can remove the negative and apply abs() to get the CoC size. The final step converts from meters to pixels, since this is typically what you use for gather or scatter-based DOF approximations. In this part 'FilmSize' is the width of the image plane (for example, 35mm) and 'DisplayWidth' is the horizontal resolution used for rendering.

Share this post


Link to post
Share on other sites

Thanks for the reply it cleared up my head !

 

I tried to use the simplified version of the coc computation but I don't get the same results, I don't get why for now :/ 

 

 

 

The circle of confusion can alternatively be calculated from the z-buffer values, with the camera parameters lumped into scale and bias terms:

CoC = abs(z * CoCScale + CoCBias)

The scale and bias terms are calculated from the camera parameters:

CoCScale = (aperture * focallength * planeinfocus * (zfar - znear)) /
((planeinfocus - focallength) * znear * zfar)
CoCBias = (aperture * focallength * (znear - planeinfocus)) /
((planeinfocus * focallength) * znear)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this