Wednesday, March 28, 2012

Ray Tracer Checkpoint 2 – Camera

For the second checkpoint we focus on the core functionality of the ray tracer; the actual ray-casting and collision detection.

I took an object-oriented design approach, keeping different components as separate as possible from one another. I ended up with the following design:
  • Camera - represents the camera. Stores it's position, up, and forward vectors. Doesn't bother storing the right vector as that can be quickly determined with a cross product. Also contains the "render" method; it takes in a World object and does the ray-casting, returning a 2D array of Colour objects (the final image to be displayed).
  • World - stores a list of 3D objects to be rendered. That's pretty much it. Also contains a method to transform all those objects based on a transformation matrix, but it isn't used yet.
  • Object3D - represents an object to be rendered. It's an abstract class and contains one method that must be implemented by all child classes; intersect(Ray).
  • Vector3 - represents a 3D vector, and implements all the standard vector math functions.
  • Point3 - represents a 3D point. Essentially a vector, but without the vector math functions.
  • Ray - a point (Point3) with direction (Vector3).
  • Colour - stores a red, green, and blue value.
Designing it this way makes it really easy to add things in, like additional objects types (besides basic sphere and polygon) and improved camera functionality. This should be pretty awesome for future checkpoints.

Known Problems

I have a variable that sets how far away the "screen" that the rays shoot through is. Unfortunately, if I try to position the screen correctly (in between the camera position and the scene), everything that rendered is too small to see. Instead, I position it on the opposite side of the scene. I get desirable results, but it's such a hack that it makes me upset. It'll hopefully be fixed by next release.

Additionally, the actual drawing to the screen is currently done with OpenGL ( glRect ). I feel like using OpenGL for just that is a bit overkill, so I'll be looking into alternatives.

Results

Ray Casting, no extras
Ray Casting with Super Sampling
I rendered the super sampled image with a rather large offset value to show the results. In practice the value would probably be much smaller.

Lighting and Shadowing: Project Proposal

Proposal Document

The Presentation

For a previous class project, I tried to implement a dynamic lighting and shadowing system in OpenGL. The main reasons for this were that OpenGL 2.0 lights don't cast shadows and that OpenGL 3.0 and 4.0 don't give you any lights at all.

After some research I found three ways for me to go about doing such a thing:
  • Per-pixel lighting
  • Per-vertex lighting
  • Light mapping
Per-pixel and per-vertex lighting require the use of shaders and GLSL, which at the time I had no desire to learn. I went with light mapping. Although it was fairly easy to implement, it was unbelievably slow and I spent the majority of my time trying to speed it up. So I've scrapped that project and moved onto better things.

The Proposal

I will create a dynamic illumination and shadowing system in OpenGL 4.0, using shaders and GLSL. I'm going to generate some random terrain, illuminate the whole thing using different models (Phong, Gouraud, and Lamertian), then implement shadow volumes. It will be glorious.

Timeline

I'm never good about keeping personal deadlines, but here's the game plan:
  • Now: Begin shader research and experimentation.
  • Week 4: Have random scene generation completely finished.
  • Week 5: Be familiar enough with OpenGL 4.0 and GLSL that actual work can begin.
  • Week 7: Have at least one illumination model completely finished.
  • Week 8: Have all illumination models completely finished. Begin work on shadow volumes.
  • Week 10: Have shadow volumes implemented.
I'm going to aim for a post on each of these milestones outlining what I did, how I did it, and numerous papers, articles, and websites that I use.

Monday, March 19, 2012

Ray Tracer Checkpoint 1 – Setting the Scene

The ray tracer assignment is a quarter long project for Computer Graphics II. Since building a ray tracer is a pretty ambitious project as a whole, it's been divided into more manageable milestones.

The first and easiest milestone is to just create the scene geometry to be ray traced. In this case, the scene is a recreation of Turner Whitted's first ray traced scene. It was recreated using OpenGL; as such, not everything is completely accurate.

Scene Geometry

  • Camera
    • Position: (0, 0, 0)
    • Forward: (0, 0, -1)
    • Up: (0, 1, 0)
  • Floor Corners
    • (7, -5, -38)
    • (-13, -5, -38)
    • (7, -5, -8)
    • (-13, -5, -8)
  • Big Sphere
    • Position: (0, 1, -13)
    • Width: 3.125
  • Small Sphere
    • Position: (-3, -5/3, -18)
    • Width: 3.125
I was pretty adamant about keeping the spheres the same size (as I believe they are in the original, but one is further away) and the camera at the origin. This led to an acceptable recreation, but some pretty unusual values.

 Results

 

Whitted's 1980 ray traced scene.
Original. Whitted, 1980
Recreation of Whitted's 1980 ray traced scene
Recreation