depth of field coc questions

Started by
2 comments, last by nico92 9 years, 10 months ago

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 !

Advertisement

Argh, this editor is giving me lots of trouble. I will re-post when I get back from lunch.

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.

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)

This topic is closed to new replies.

Advertisement