This is a small extension to the previous post. We will add a depth of field simulation to our path tracer project. I ran across this algorithm at this site. Below is a render of our path tracer with the depth of field extension.
Essentially, we will define the distance to the focal plane and a blur radius. For each primary ray we find its intersection with the focal plane, \(\vec{p}\), and jitter the ray origin by an amount, \(\vec{d}\). We then define the new ray direction as \(\vec{r}=\vec{p}-\vec{d}\). Consequently, objects on the focal plane will appear in focus. Below is the addendum to the kernel()
function.
__vector dir = __vector(x - width / 2, -y + height / 2, 0 + width) + offset; __ray ray = { __vector(0, 0, 0), dir.unit() }; u1 = rand_device[i*width*height*3+index+1]; u2 = rand_device[i*width*height*3+index+2]; r1 = 2 * M_PI * u1; r2 = u2; offset = __vector(cos(r1)*r2, sin(r1)*r2, 0.0) * blur_radius; __vector p = ray.origin + dir * (focal_distance / width); ray.origin = ray.origin + offset; ray.direction = (p - ray.origin).unit();
Again, don't forget to update the Makefile
to reference the proper locations for the libcudart.so
and libcurand.so
libraries.
Download the updated project: pathtracer_dof.tar.bz2