In this assignment, you will add antialiasing to your ray-tracer. You will use super-sampling and filtering to alleviate jaggies and Moire patterns. You will experiment with different sampling patterns and filters. To implement antialiasing, you will use a new image representation that stores multiple samples per pixel. A filter class will then use this representation to compute the final image. For extra credit, you can implement a simple pre-filtering technique for Perlin noise in order to band-limit the signal before sampling.
The Sample class stores a 2D coordinate offset from (0,0)->(1,1) within the pixel and the color of the sample. The Film stores width*height*num_samples samples. We will use a constant number of samples per pixel, which will be specified on the command line (see below). The Film constructor initializes all the sample colors black:
Film(int _width, int _height, int _num_samples);
virtual Vec2f getSamplePosition(int n) = 0;which returns the 2D offset for the specified sample.
void Film::setSample(int x, int y, int i, Vec2f offset, Vec3f color);
x and y are the integer pixel coordinates, i is the sample number, offset is the sample position within the pixel, ranging from (0,0) -> (1,1), and color is the value returned by RayTracer::TraceRay for that sample.
void Film::renderSamples(char *samples_file, int sample_zoom);
This function creates a zoomed-in version of the image plane with a pixel at each sample location. Verify that your RandomSampler creates a nice random distribution across the pixels. Do not try it with a large image resolution, as the zoom factor will result in a huge image. Now you can create interesting "pointillist" versions of your image. Verify that with a small zoom factor this visualization looks like the scene.
Vec3f Filter::getColor(int i, int j, Film *film);
which computes the appropriately filtered color for pixel (i,j) from the samples stored in the Film instance. An important helper function for the Filter::getColor method is:
virtual float Filter::getWeight(float x, float y) = 0;
which returns the weight for point (x + pixel center, y + pixel center). In general, this function will have maximum value at the pixel center (when x=0 & y=0). getWeight is a pure virtual function which will be defined in the Filter subclasses.
Some filters span multiple pixels, but we do not want to access all samples in the Film. For each filter we can have a conservative integer supportRadius which will indicate which pixel samples might contribute to the final color. The second helper function for the Filter::getColor method is:
virtual int Filter::getSupportRadius() = 0;
If the filter only relies on samples in the center pixel, this function returns zero. If it relies on the center pixel and the 8 neighboring pixels (9 pixels total) this function returns 1, etc. In other words, to compute the output at pixel (i, j) of the Film, we will take the weighted average of the samples from pixels i-supportRadius through i+supportRadius included, and from j-supportRadius through j+supportRadius included.
-box_filter <radius> -tent_filter <radius> -gaussian_filter <sigma>
For the box filter, the radius specifies the orthogonal distance from pixel center to the boundary edges. The tent filter is a linear function with value 1 at the pixel center and 0 for points with distance further than the radius from the pixel center. Finally the Gaussian filter uses the normal distribution to weight pixel samples:
e-d2/2*sigma2
You may clamp this function to zero for points further than than 2*sigma from the pixel center.
void Film::renderFilter(char *filter_file, int filter_zoom, Filter *filter);
Please think about good code design as you restructure your main rendering loop. We will be grading you on coding style, as usual.
raytracer -input scene7_01_sphere_triangle.txt -size 180 180 -output output7_01.tga
raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_samples samples7_01a.tga 20 -random_samples 4 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_samples samples7_01b.tga 20 -uniform_samples 4 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_samples samples7_01c.tga 20 -jittered_samples 4 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_samples samples7_01d.tga 20 -random_samples 9 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_samples samples7_01e.tga 20 -uniform_samples 9 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_samples samples7_01f.tga 20 -jittered_samples 9 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_samples samples7_01g.tga 20 -random_samples 36 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_samples samples7_01h.tga 20 -uniform_samples 36 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_samples samples7_01i.tga 20 -jittered_samples 36
raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_filter filter7_01a.tga 20 -box_filter 0.5 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_filter filter7_01b.tga 20 -tent_filter 0.5 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_filter filter7_01c.tga 20 -gaussian_filter 0.5 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_filter filter7_01d.tga 20 -box_filter 1.7 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_filter filter7_01e.tga 20 -tent_filter 1.7 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_filter filter7_01f.tga 20 -gaussian_filter 1.7 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_filter filter7_01g.tga 20 -box_filter 2.3 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_filter filter7_01h.tga 20 -tent_filter 2.3 raytracer -input scene7_01_sphere_triangle.txt -size 9 9 -render_filter filter7_01i.tga 20 -gaussian_filter 2.3
raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01_low_res.tga raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -render_samples samples7_01a_low_res.tga 15 -random_samples 9 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -render_samples samples7_01b_low_res.tga 15 -uniform_samples 9 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -render_samples samples7_01c_low_res.tga 15 -jittered_samples 9 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -render_filter filter7_01a_low_res.tga 15 -box_filter 0.5 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -render_filter filter7_01b_low_res.tga 15 -tent_filter 1.5 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -render_filter filter7_01c_low_res.tga 15 -gaussian_filter 1.0 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01a_low_res.tga -random_samples 9 -box_filter 0.5 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01b_low_res.tga -random_samples 9 -tent_filter 1.5 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01c_low_res.tga -random_samples 9 -gaussian_filter 1.0 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01d_low_res.tga -uniform_samples 9 -box_filter 0.5 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01e_low_res.tga -uniform_samples 9 -tent_filter 1.5 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01f_low_res.tga -uniform_samples 9 -gaussian_filter 1.0 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01g_low_res.tga -jittered_samples 9 -box_filter 0.5 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01h_low_res.tga -jittered_samples 9 -tent_filter 1.5 raytracer -input scene7_01_sphere_triangle.txt -size 12 12 -output output7_01i_low_res.tga -jittered_samples 9 -gaussian_filter 1.0
raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02.tga raytracer -input scene7_02_checkerboard.txt -size 9 9 -render_samples samples7_02a.tga 20 -random_samples 16 raytracer -input scene7_02_checkerboard.txt -size 9 9 -render_samples samples7_02b.tga 20 -uniform_samples 16 raytracer -input scene7_02_checkerboard.txt -size 9 9 -render_samples samples7_02c.tga 20 -jittered_samples 16 raytracer -input scene7_02_checkerboard.txt -size 9 9 -render_filter filter7_02a.tga 20 -box_filter 0.5 raytracer -input scene7_02_checkerboard.txt -size 9 9 -render_filter filter7_02b.tga 20 -tent_filter 1.5 raytracer -input scene7_02_checkerboard.txt -size 9 9 -render_filter filter7_02c.tga 20 -gaussian_filter 0.6 raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02a.tga -random_samples 16 -box_filter 0.5 raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02b.tga -random_samples 16 -tent_filter 1.5 raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02c.tga -random_samples 16 -gaussian_filter 0.6 raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02d.tga -uniform_samples 16 -box_filter 0.5 raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02e.tga -uniform_samples 16 -tent_filter 1.5 raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02f.tga -uniform_samples 16 -gaussian_filter 0.6 raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02g.tga -jittered_samples 16 -box_filter 0.5 raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02h.tga -jittered_samples 16 -tent_filter 1.5 raytracer -input scene7_02_checkerboard.txt -size 180 180 -output output7_02i.tga -jittered_samples 16 -gaussian_filter 0.6
raytracer -input scene7_03_marble_vase.txt -size 200 200 -output output7_03a.tga -grid 15 30 15 -shadows raytracer -input scene7_03_marble_vase.txt -size 200 200 -output output7_03b.tga -grid 15 30 15 -shadows -jittered_samples 4 -gaussian_filter 0.4 raytracer -input scene7_03_marble_vase.txt -size 200 200 -output output7_03c.tga -grid 15 30 15 -shadows -jittered_samples 9 -gaussian_filter 0.4 raytracer -input scene7_03_marble_vase.txt -size 200 200 -output output7_03d.tga -grid 15 30 15 -shadows -jittered_samples 36 -gaussian_filter 0.4
raytracer -input scene7_04_6.837_logo.txt -size 400 200 -output output7_04a.tga -shadows -shade_back -bounces 5 -weight 0.01 -grid 80 30 3 raytracer -input scene7_04_6.837_logo.txt -size 400 200 -output output7_04b.tga -shadows -shade_back -bounces 5 -weight 0.01 -grid 80 30 3 -jittered_samples 9 -gaussian_filter 0.4
raytracer -input scene7_05_glass_sphere.txt -size 300 300 -output output7_05a.tga -shadows -shade_back -bounces 5 -weight 0.01 -grid 20 20 20 raytracer -input scene7_05_glass_sphere.txt -size 300 300 -output output7_05b.tga -shadows -shade_back -bounces 5 -weight 0.01 -grid 20 20 20 -jittered_samples 4 -gaussian_filter 0.4 raytracer -input scene7_05_glass_sphere.txt -size 300 300 -output output7_05c.tga -shadows -shade_back -bounces 5 -weight 0.01 -grid 20 20 20 -jittered_samples 16 -gaussian_filter 0.4
raytracer -input scene7_06_faceted_gem.txt -size 200 200 -output output7_06a.tga -shadows -shade_back -bounces 5 -weight 0.01 -grid 20 20 20 raytracer -input scene7_06_faceted_gem.txt -size 200 200 -output output7_06b.tga -shadows -shade_back -bounces 5 -weight 0.01 -grid 20 20 20 -jittered_samples 9 -gaussian_filter 0.4
See the main Assignments Page for submission information.