Assignment 3 Camera Simulation

Kurt Berglund

Date submitted: 9 May 2006

Code emailed: 9 May 2006

Compound Lens Simulator

Description of implementation approach and comments

To represent the camera's lens stack, I created a new Lens class for each lens within the stack. A lens simply stores a reference to a pbrt shape primitive which represents the geometry of the lens, as well as some other basic information relating to the lens (indices of refraction, radius). A sphere with its bounds clipped is used for the actual lenses, while a disk with a diameter equal to the passed in camera's aperture size is used to represent the camera's aperture. To find an outgoing ray then, the incoming ray is traced through the stack of lenses. When an intersection occurs the refracted ray is computed and the process continues until either the ray exits the camera, or it no longer intersects with a lens, or total internal refraction occurs.


To compute the ray to trace through the lens stack I compute the sample's imageX and imageY positions to a point on the film plane. Then I pass lensU and lensV to ConcentricSampleDisk to compute a point on a disk with the same radius as the back lens position that is located at the same z position as the back lens element. The weight for this ray then is equal to (area of the disk being sampled) * (cosine between the ray direction and the positive z axis (since this points towards the lens))4 / (distance from the back lens to the film)2. This weighting follows from the integral described in the paper and the sampling method being used. In the case that the ray does not exit the camera, the weight value returned is 0.


One other issue I ran in to was with with the alpha variable in pbrt's scene render. As I found while debugging, in the case of a 0 weight, this value is uninitalized and is subsequently used by pbrt. In the end, I ended up setting its value to 1, since in the case of the camera, a ray weight of 0 is a ray which hit the inside of the lens, and so should be treated as a black ray.

Final Images Rendered with 512 samples per pixel

My Implementation

Reference

Telephoto

hw3-telephoto

hw3telephoto_512

Double Gausss

hw3-dgauss

hw3dgauss_512

Wide Angle

hw3-wide

hw3wide_512

Fisheye

hw3-fisheye

hw3fisheye_512

Final Images Rendered with 4 samples per pixel

My Implementation

Reference

Telephoto

hw3-telephoto-low

hw3telephoto_4

Double Gausss

hw3-dgauss-low

hw3dgauss_4

Wide Angle

hw3-wide-low

hw3wide_4

Fisheye

hw3-fisheye-low

hw3fisheye_4

Experiment with Exposure

Image with aperture full open

Image with half radius aperture

hw3-dgauss

hw3-dgauss-half

Observation and Explanation

Reducing the aperture radius in half should have the effect of reducing the exposure by a factor of four, which causes less light to reach the film and should decrease the brightness by 4 as well, which my camera simulation appears to produce. Because the F-number is the ratio of the focal length divided by the aperture, cutting the aperture in half causes us to half the F-number. Since an Fstop occurs every multiple of sqrt(2), then having the F-number causes us to move two Fstops. Thus we've reduced the photograph exposure by two stops, which amounts to halving the exposure twice.

Autofocus Simulation

Description of implementation approach and comments

First, to help with the bounds within which I would autofocus, I first computed the thick lens approximation to my given lens. I did this the same way as was described in the paper. I had to modify my lens tracing code to be able to go from a ray entering the camera to one leaving its back lens. After this, I shot a ray parallel to the z axis in to the camera, and then computed where it intersected the z axis after it exited. This became Fprime. Then, I computed the intersection of this ray with the ray entering the camera, which became Pprime. From this I could then calculate the camera's effective focal length. I did the same thing in the opposite direction as well, but this result wasn't used in my final simulation.


With this value then, to autofocus I start at the thick lens approximation's focal point, and move down the -z axis away from the lens, incrementing along the way. I used a step size of 2mm and capped the max distance I would move at 100mm, since this worked in practice, and seemed like a distance at which I would go past a physical camera's depth. Then along the way I compute the sum modified laplacian (SML) with a step size of 1, about the entire auto focus region. I initially experimented with the Y value of the XYZ space as the value used in the calculation, since it closely corresponds to perceived brightness, but I didn't find the results to be good. In the end I used the common (r + g + b) / 3 metric which gave good results.


From watching the output of the SML calculation along the sample space, I saw that there usually is a spike in the SML values when the optimal focus is reached, and then the values quickly drop afterwards. I experimented with heuristics and found that a good exit termination was if the best SML value computed was better than 5/3 * mean value of all computed SMLs, then the depth at the best value was the focal depth to use. I also had tried watching the values and stopping after n values less than the max, but certain configurations could trick this heuristic. In the end the above seemed to work well.


After computing the above value then, I recursively refine the estimate around the current best guess, bounded by the step size with which it was computed, stopping either when the variance of the computed estimates is < 1, or when some max depth is reached (set at 4 in this case). The algorithm can thus be tweaked for speed and accuracy.


I also experimented with the extra autofocus scenes. Whenever there is more than one autofocus zone, my algorithm computes the optimial film depth for each zone independently. Then these depths are sorted, and the distance from each depth to every other is computed. The chosen depth then becomes the value with the smallest distance from every other depth. This heuristic made sense to me since it attempts to compute the depth as close as possible to the others, hopefully in the process getting a good balance of focus within the scene.

Final Images Rendered with 512 samples per pixel

Adjusted film distance

My Implementation

Reference

Double Gausss 1

mm

hw3-foc1

hw3afdgauss_closeup

Double Gausss 2

mm

hw3-foc2

hw3afdgauss_bg

Telephoto

mm

hw3-foc3

hw3aftelephoto

Any Extras

Here are the results of my autofocus algorithm on the harder test cases.

KurtBerglund/Assignment3 (last edited 2006-05-10 05:17:01 by KurtBerglund)