Path tracer depth of field

Scene rendered with 214 samples.

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.

Scene rendered with 214 samples.
Scene rendered with 214 samples.

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

Leave a Reply

Your email address will not be published.