Friday, February 27, 2009

Assignment #4

This assignment adds texture mapping and antialiasing to the basic raytracer in assignment #3.

There are two texture maps and mapping methods:
  1. A PNG image of the earth mapped to a sphere using a transform from XYZ coordinates to spherical coordinates.
  2. A procedural checkerboard texture map for the plane. The color for the plane is calculated based on the intersection point.

The antialiasing technique used fairly simple. It takes the number of samples requested and generates that number of equally spaced rays through the corresponding pixel. Each ray's color is determined and the colors are averaged

Adding some jitter to the samples will provide better antialiasing. It would have been added to this version of the ray tracer, but too much time was spent rewriting the code from the previous assignment and fighting with C++. It isn't C++'s fault that my coding skills are rusty. That's my excuse for the simplistic antialiasing :)

The antialiasing removed the jaggy edges from the spheres, triangles and checkerboard pattern on the plane. It also made the earth texture less speckled.

The difference between 16 samples/pixel and 128 samples/pixel is subtle. I suspect that if the surfaces were not being modeled as perfectly smooth that the difference between 16 and 128 samples per pixel would be much more noticeable.

Interestingly, the rewrite sped up rendering by 60%. This was very surprising considering the number of abstractions added to the code.


tar jxf jbowles-assign4.tar.bz2
cd jbowles-assign4
make
./raytracer --width=512 --height=512 --reflections \
--shadows --samples=16


Usage: ./raytracer [options]

options:
--width Window width
--height Window height
--reflections turn on reflections
--maxdepth maximum number of reflections
(default 3)
--shadows turn on shadows
--samples square root of the number of
samples per pixel.
--perf turn on performance measurement
rendering

To exit, pressing Apple-Q, escape, or just q.


Output generated on a MacBook Pro 17" 2.4GHz dual core. Size of each image is 512x512. Each image can be clicked on to view a larger 1280x1024 version.

1 sample/pixel:
4 samples/pixel:
16 samples/pixel:
32 samples/pixel:
128 samples/pixel:

Alternate viewpoints:





Render times:
Samples 512x512 render time (s) 1280x1024 render time (s)
1 0.323498 1.716881
4 1.189341 6.245954
16 4.617202 25.190776
32 7.222273 39.810833
128 36.107344 188.703291

Friday, February 13, 2009

Assignment #3

Assignment #3 - basic ray tracer. Features:
  • Diffuse lighting
  • Ambient lighting
  • Specular highlights
  • Shadows
  • Reflections
  • Simple anitialiasing
  • High dynamic range color
  • Geometric objects: spheres, planes, triangles
  • Perspective is maintained regardless of requested window size - pixels remain "square"
How to build and run:
Platform: Mac OS X 10.5.6, XCode 3.0 / gcc 4.0.1

tar jxf jbowles-assign3.tar.bz2
cd jbowles-assign3
make
./raytracer --width=512 --height=512 --reflections \
--shadows --samples=3

Usage: ./raytracer [options]

options:
--width Window width
--height Window height
--reflections turn on reflections
--maxdepth maximum number of reflections
(default 3)
--shadows turn on shadows
--samples square root of the number of
samples per pixel.
--perf turn on performance measurement
rendering

To exit, pressing Apple-Q, escape, or just q.

Output generated on a MacBook Pro 17" 2.4GHz dual core. Size of each image is 512x512.

./raytracer --width=512 --height=512
1.114634 seconds to render
Number of rays: 262144



./raytracer --width=512 --height=512 --shadows
1.161857 seconds to render
Number of rays: 446464



./raytracer --width=512 --height=512 --shadows --reflections
1.270463 seconds to render
Number of rays: 693328



./raytracer --width=512 --height=512 --shadows \
--reflections --samples=5
32.375095 seconds to render
Number of rays: 17334027

Optimizations

It was time to optimize my raytracer and gprof turned up something unexpected: most of the time was being spent in vec3f constructors. I expected most of the time to be spent checking for intersections. It was time to turn on gcc optimizations.

The result: the constructor calls disappear after passing either a -O or -O1. Best performance was to be had at -O3.

This raytracer is being compiled on a MacBook Pro 17", 2.4GHz Intel Core 2 Duo with 4GB of RAM. gcc:

gcc -v
Using built-in specs.
Target: i686-apple-darwin9
Configured with: /var/tmp/gcc/gcc-5465~16/src/configure --disable-checking -enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib --build=i686-apple-darwin9 --with-arch=apple --with-tune=generic --host=i686-apple-darwin9 --target=i686-apple-darwin9
Thread model: posix
gcc version 4.0.1 (Apple Inc. build 5465)

Image size: 512x512, 1 plane, two spheres, 1 triangle. Average run times for 5 runs each:
Average Run Time Optimization Debugging and profiling
1. 8.1604598 None yes
2. 2.0264776 -O yes
3. 2.036941 -O1 yes
4. 2.2078138 -O2 yes
5. 1.2405112 -O3 yes
6. 1.2331454 -O4 yes
7. 1.1143894 -O3 no
8. 1.1208828 -O6 no
9. 1.1019208 -O4 no

Notes:

  1. 1. gprof shows that most of the time is spent in vec3f constructors

  2. 2. gprof shows that most of the time is spent in sphere and plane intersections,
    but I still see more calls than expected to vec3f constructors

  3. 3. This generates a different binary than the previous test and runs at approximately
    the same speed. Still more vec3f constructor calls than expected.

  4. 4. -O2 yields no real change from -O1

  5. 5. gprof yields expected results, big speedup from -O1 and -O2

  6. 6. Seems to be the same as -O4

  7. 7. Gained 1/10th of a second from dropping debugging and profiling

  8. 8. -O6 shows no gain over -O3

  9. 9. -O4 without debugging and profiling is 1/100th of a second faster than -O3, but that isn't big enough of a change to say that something changed. There could just be less load on this system.