Depth of Field Aperture Help

Started by
2 comments, last by missionctrl 6 years, 10 months ago

Hi

I have written a simple CPU raytracer which just generated this image:

Image_1497762772.png

I just realized that I am calculating the secondary rays origin incorrectly. I was simply adding a random number to the x and y of the origin point. This is fine when my lookat point is at the same height at my camera position but if it is higher or lower, my square aperture will be tilted. How do I find a random point in the aperture rectangle around my camera?

Some code:


//primary ray

Ray newRay = camera.GetRay(x, y, HEIGHT, WIDTH, antiX, antiY);

//convergent point on focal plane

Vec3 focalPoint = newRay.calculate(camera.focalLength);

            double origX = randOrigin(generator);

            double origY = randOrigin(generator);

            Vec3 randomOrigin(newRay.origin.x + origX, newRay.origin.y + origY, newRay.origin.z);

            //direction to focal plane

            Vec3 focalDir(focalPoint - randomOrigin);

            focalDir = focalDir.normalized();

            newRay = Ray(randomOrigin, focalDir);

Thanks :)

Advertisement
Quote

I just realized that I am calculating the secondary rays origin incorrectly. I was simply adding a random number to the x and y of the origin point.

Wait... you don't do anything to your secondary rays. The algorithm for DoF in ray tracing works as following:

  • Start by casting a ray from camera into the scene. But instead of intersecting it with anything, you just determine the focal point for given pixel in the scene (pixel focal point).
  • Now, for N samples, do:
  1. Select a random starting point on aperture. For circular - random polar angle + random radius, for rectangular - just use some distribution over the rectangle. Just make sure your probability distribution functions for your random number generator integrate to 1.
  2. Cast a ray through this point on aperture and focal point like you do normally, reflecting/refracting it around.

I can put you a smallpt-like example up in few hours from now (I still have something to finish at work).

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

If I understand the problem correctly, you need to know which direction is "left and right" and "up and down" relative to your "focalDir" vector, correct?  You could calculate this with a few cross products, but you need to throw in another point of reference, usually an "up" vector (in this case, i'm assuming the Y vector is "up")


    zAxis = vectorMinusVector(target, camPos); //this is your current focalDir
    zAxis.vectorNormalize();
    xAxis = vectorCrossProduct(up, zAxis);
    xAxis.vectorNormalize();
    yAxis = vectorCrossProduct(zAxis, xAxis);
    vectorNormalize(yAxis);

    //now you have you an xAxis and yAxis to move around on
    pos.addVector( vectorTimesFloat(xAxis, randomX) );
    pos.addVector( vectorTimesFloat(yAxis, randomY) );

Another option would be to use the camera matrix instead of generating all new vectors.  Then all of these vectors are sorta bundled together in a neat package, and you can just do local translations, but the results would be the same.

This topic is closed to new replies.

Advertisement