CS 563 Advanced Computer Graphics Spring Semester 2007
Project 2 - Camera Simulation
Due March 13, 2007
Many rendering systems approximate the light arriving on the film plane by assuming a pin-hole camera, which produces images where everything that is visible is in-focus and sharp. In contrast, real cameras contain multi-lens assemblies with different imaging characteristics such as limited depth of field, field distortion, vignetting and spatially varying exposure. In this assignment, you'll extend pbrt to support a more realistic camera model that accurately simulates these effects.
Specifically, you are provided with data from real wide-angle, normal and telephoto lenses, each composed of multiple lens elements. You will build a camera plugin for pbrt that simulates the traversal of light through these lens assemblies.
With this camera simulator, you'll explore the effects of focus, aperture and exposure. You will empirically characterize the critical points of the telephoto and normal lenses. Using these data you can optimize the performance of your simulator considerably.
Read A Realistic Camera Model for Computer Graphics by Kolb, Mitchell, and Hanrahan, in SIGGRAPH 1995.
Step 2: Compound Lens Simulator
- Copy this zip file to the 'core' directory of your PBRT installation. This zip file contains:
- A Makefile for Linux, and a Visual Studio 2003 project for Windows.
- A stub C++ file, realistic.cpp, for the code you will write.
- Six scene files, which end in .pbrt.
- Four lens data files, which end in .dat.
- Binaries for a reference implementation of realistic.cpp on Linux, Windows and OSX.
- Various textures used by the scene files.
- Modify the stub file, realistic.cpp, to trace rays from the film plane through the lens system supplied in the .dat files. The following is a suggested course of action, but feel free to proceed in the way that seems most logical to you:
- Build an appropriate data structure to store the lens parameters supplied in the tab-delimited input .dat files. The format of the tables in these file is given in Figure 1 of the Kolb paper.
- Develop code to trace rays through this stack of lenses. Please use a full lens simulation rather than the thick lens approximation in the paper. It's easier (you don't have to calculate the thick lens parameters) and sufficiently efficient for this assignment. Read and think about section 3 first, as it will probably be useful to be able to trace rays both forwards and backwards through the stack of lenses.
- Write the RealisticCamera::GenerateRay function to trace randomly sampled rays through the lens system. For this part of the assignment, it will be easiest to just fire rays at the back element of the lens. Some of these rays will hit the aperture stop and terminate before they exit the front of the lens.
- Render images using commands such as 'pbrt dof-dragon.dgauss.pbrt'. Decrease the noise (and increase the rendering time) by changing the "integer pixelsamples" parameter in the scene files.
- You may compare your output against the reference implementation, (realistic.so on Linux RedHat 9.0 and realistic.dll on Windows.
- From left to right: telephoto, normal, wide angle and fisheye.
- Note that these were produced with 512 pixel samples rather than the default 32.
- Notice that the wide angle image is especially noisy -- why is that? Hint: look at the ray traces at the top of this web page.
- Assume that the origin of the camera system is at the left-most element of the stack (the point closest to the world).
- Assume that the 'filmdistance' parameter passed to the RealisticCamera constructor is measured from the right-most element of the stack (the point closest to the film).
- There is exactly one aperture stop per lens data file. This is the entry with a radius of 0. Note that the diameter of this entry is the maximum aperture of the lens. The actual aperture diameter to use is passed in the scene file, and appears as a parameter to the RealisticCamera constructor.
- In this assignment, everything is measured in millimeters.
- ConcentricSampleDisk() is a useful function for converting two 1D uniform random samples into a uniform random sample on a disk. See p. 270 of the PBRT book.
- It may be helpful to decompose the lens stack into individual lens interfaces and the aperture stop. For the lens interfaces, you'll need to decide how to test whether rays intersect them, and how they refract according to the change of index of refraction on either side (review Snell's law).
- For rays that terminate at the aperture stop, return a ray with a weight of 0 -- pbrt tests for such a case and will terminate the ray.
- Be careful to weight the rays appropriately (this is represented by the value returned from GenerateRay). You should derive the weight from the integral equation governing irradiance incident on the film plane (hint: in the simplest form, this equation contains a cosine term raised to the fourth power). The exact weight will depend on the sampling scheme that you use to estimate this integral. Using the simplified cos^4 falloff assumes that the effective aperture is small relative to the film. This is not always accurate; you can use the analytic form factor given in the paper, but it's not required for this assignment. Note that the GenerateRay() function returns a weight value for each ray.
- As is often the case in rendering, your code won't produce correct images until everything is working just right. Try to think of ways that you can modularize your work and test as much of it as possible incrementally as you go. Use assertions liberally to try to verify that your code is doing what you think it should at each step. Another wise course of action would be to produce a visualization of the rays refracting through your lens system as a debugging aid (compare to those at the top of this web page). For instance, to visualize the rays through each type of lens, you can first write an OpenGL program that produces line drawings that are similar to the figure above.
- You should trace rays from the image plane through the exit pupil instead of the rear lens element.
- For rays that terminate on the aperture stop or elsewhere in the lens system, make sure you set mint greater than maxt. pbrt will misbehave if you don't at least set these ray values.
- For rendering with full open aperture, you will need to use high sample densities (probably around 128) to reduce noise. This will increase rendering time substantially, so be sure to keep the sample rates low when you are debugging.
Step 3: Web page submissionCreate a web page that describes your work and mail the URL to me. The page should contain the following:
- A clear description of your approach and summarize the steps you took to simulate the camera.
- Your code (attached to this website)
- Describe parameter setting you used to generate your images for each lens type.
- Use exrtotiff to convert your .exr renderings to tiffs, and then convert these to jpgs to include in your web pages.
- Though it is not a requirement, feel free to append a discussion of anything extra or novel that you did at the end of your web page.
- Q: PBRT complains that it can't find realistic.dll or realistic.so. What should I do?
A: Make sure that '.' (the local directory) is in your PBRT_SEARCHPATH environment variable. In this assignment, you will compile a camera plugin (realistic.so/dll) in your working directory. Note that the path is ':' delimited on Linux and ';' delimited on Windows.
- Q: Should we be implementing the thick lens approximation described in the paper or a full lens simulation?
A: Please implement the full lens simulation, which is less work for you and only slightly less efficient computationally. Implementing the thick lens approximation is a superset of the work, since you need the full lens simulation in order to calculate the thick lens parameters.
- Q: Why are my images so noisy?
A: Integrating over the surface of the lens, especially for large apertures, requires multiple samples for accuracy. Too few samples increases the variance of the integral estimate, resulting in noisy images. The problem is exacerbated in Step 2 by the fact that you will fire many rays at the lens system that will not make it into the world because they will hit the aperture stop. To drive down the noise, you can increase the number of samples ("integer pixelsamples" parameter in the scene file).
Adapted from UT Austin CS 395T, which adapted it from Pat Hanrahan's Stanford CS348B course.