Wednesday, April 16, 2014

28x faster renders

I finally got a simple BVH implemented. To get a quick idea of what a BVH is, check out the Bounding Volume Hierarchy page on Wikipedia. My tree generation algorithm is pretty simple:

  • if the number of remaining shapes is less than or equal to the target group size
    • add the shapes to this node's list
    • create a bounding box for the group
  • otherwise
    • find the bounding box that contains the remaining shapes
    • figure out on which axis (x, y, or z) the bounding box is longest
    • sort the shapes on the longest axis
    • split the list at the median
    • create a left node containing the first half of the list
    • create a right node containing the second half of the list
It's nothing fancy, and I haven't tried to find an optimal group size yet, but it works. And, like the title of this post implies, for certain scenes the render times are almost 28 times as fast. Not too shabby.


Tree traversal is pretty simple, too....

Wednesday, April 9, 2014

OBJ Importing and Anti-Aliasing

Thanks to a new tutorial by Mike Farnsworth at Renderspud, I added an OBJ Loader class to my ray tracer. My implementation only supports the basics (no quads, vertex normals, nor texture coordinates; just triangles), but it works. And what better model to test it on than everyone's favorite open-source monkey, Suzanne:
The model has 968 faces. At 512x512 with 2-4 anti-aliasing samples, this took nearly 4 hours to render on my trusty laptop. It's a start.

Speaking of anti-aliasing, we now have it. There are two modes. The first one sends out an equal number of rays through each pixel, each slightly offset from one another. The results are averaged together to form the final pixel color. The second mode sends out a single ray through each pixel to get a rough image. It then finds the edges (the parts of the image that will benefit most from anti-aliasing) by calculating the color gradient of the image (see Sobel Operator for more on this). Then it re-renders only the high-contrast pixels with a higher number of samples. This way, smooth parts of the image render quickly, but the edges are properly anti-aliased.
 (I'm being really liberal with the definition of the + sign in this graphic)
I'm still fiddling with the edge detection and how to get the best-looking image for the most reasonable render time.

Now it's time to start implementing an acceleration structure like a BVH.

Thursday, April 3, 2014

A quick update

So I've been quite busy since the last post. The progress is very encouraging. And a lot of fun. Here's a screenshot of my very first raytraced image. (When I say 'first' I actually mean first):
There it is! Six red spheres on a green plane. Can't you see them? Well, at least I got the color right on the spheres.

Here's my latest image. As you can tell, it's come a long way.
I've implemented point lights, a diffuse shader, a reflective shader, plane intersection, and sphere intersection. The diffuse shader took me about 3 hours to write. Once that was working, the reflective shader took about 10 minutes. When I find some time, I'll implement a specular shader, then get started on anti-aliasing.
Fun fun fun!

Edit: And another screenshot with specular highlights.

Monday, March 24, 2014

Finally starting

So when I started this blog a few years ago, I was very gun-ho about making a render engine. The only problem was that I had no idea what I was doing. I quickly realized that I got in way over my head with my skill set at the time. But after taking two computer graphics courses, an algorithms course, working with several 3D packages, talking with professors and people in the industry, and doing a lot of reading on Wikipedia....I'm back.

And I know what I'm doing now. And it's gonna be good. (and I'm doing this for a class project so I have more time and motivation to do it.)

So I thought I'd give an overview of my plans for the engine. I'm open to tips and suggestions; I know for a fact that there are people who are smarter than I am.

I've got at least two phases in mind for the foreseeable future of this project.
Phase 1: A ray tracer that will fulfill the requirements of the class project but leave tons of room for building a pretty good render engine.
Phase 2: A unidirectional path tracer that simulates bounce lighting or 'Global Illumination' as some call it. I'll try and leave room for a modern shader language as well.

In order to keep myself motivated, I'll post a list of the features I'd like to implement. This will also serve to remind me what I hope to achieve. So here goes. My goals for phase 1 are as follows:

  • Recursive ray tracing
  • Shapes:
    • Sphere
    • Plane
    • Triangle (and triangle meshes)
  • Customizable shader model
    • Diffuse
    • Specular
    • Reflection
    • (Maybe) Refraction
  • Two anti-aliasing modes using super sampling:
    • uniform number of AA samples per pixel
    • Variable number of samples: more for edges and fewer for smooth areas
  • Two sample patterns:
    • Grid pattern
    • Jitter pattern
  • Box filter to average the samples (with room for other filters)
  • Point light (spot and area lights will have to wait until phase 2)
  • Camera movement controls
  • Render to OpenGL window
The project is due April 12th, so I've got some work to do. I've already created all of the header files for the classes I'll need. I might end up posting a UML diagram of the project. It never hurts to be organized.

Stay tuned!