BadEggGames

Depth of Field Aperture Help

Recommended Posts

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 :)

Edited by BadEggGames

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites

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.

Edited by missionctrl

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