The books are now available in unprotected pdf for PAY WHAT YOU WISH, with 50% going to not for profit programming education organizations.
Here are the files.
Ray tracing was invented by Turner Whitted around 1980. His classic paper is really amazing; it had bounding volume hierarchies, adaptive sampling, and it's future work suggested randomized reflection. Since then it has branched into a ton of variations and is used in most movies for the indirect
"bounce" lighting.
I've was assigned a 2D ray tracer in a physics class in 1984 and I was hooked. Since then I have written a bunch of ray tracers in Pascal, Fortran, Scheme, C, C++, Java, and most recently Swift (which is awesome for writing ray tracers). I've also taught classes with ray tracing about a dozen times, most recently at
Westminster College in 2015. My approach over the years has evolved to do what I think are the most fun parts of ray tracing that are still in the direction of writing a production-quality ray tracer.
Ray Tracing in One Weekend
is a kindle book that goes through all of the details to generate a rudimentary ray tracer. It's $2.99 on amazon. It uses C plus classes plus operator overloading. I have heard this referred to as "C plus" which I now call it. Most production renderers are written in C++ so I opted for that as the driving language. I put the most primal set of these assignments so that it's very doable in a weekend, the fundamental unit of coding self-improvement :) Here is the book:
The resulting program generates this image:
Here's my MacOS
code for the book. Should be semi-portable but drand48() will need to be written on some systems and the fileio may be too. I also have a
little post on the tools I used to write the book for those interested in doing a little book of their own. Please let me know if you do!
Links for further reading and exploration related to the book:
Chapter 0: Overview
Here is a list of basic graphics texts that cover the vector background the book assumes:
Fundamentals of Computer Graphics, Fourth Edition
Computer Graphics: Principles and Practice (3rd Edition)
The Graphics Codex
Real-Time Rendering, Third Edition
Chapter 1: Output an image
For output of most LDR and HDR images I love stb_image.
For more info on HDR images and tone mapping the I like the book High Dynamic Range Imaging, Second Edition: Acquisition, Display, and Image-Based Lighting
Chapter 2: The vec3 class
I advocate using the same class for points, displacements, colors, etc. Some people like more structure and type checking (so for example multiplying two locations would be rejected by the compiler). An example article where points and vectors are different is here. Jim Arvo and Brian Smits experimented with not only distinguishing points and vectors, but using the compiler to do dimensional analysis (so velocity, length, and time would be different types for example). They found this to be too cumbersome in 1990s C++ but I'd love to hear about anybody's experience. Researchers at Dartmouth have taken a really serious effort at this and their code and paper are available at github.
Chapter 3: Rays, a simple camera, and background
The first thing you might add to your background function is an environment map. Paul Debevec has a terrific history of environment mapping. The easiest mapping for this uses a single image for the entire sphere of directions. Paul also provides some good images to use for your environment map.
Chapter 4: Adding a sphere
There are a bunch of other object types you can add. Triangles are usually first and I am a fan of
barycentric methods. After triangles, many people quit adding primitives because graphics has such a big infrastructure for triangles. Ellipses are an easy thing to add but instancing is usually a more "ray tracey" approach (let the software do the heavy lifting). Composite objects via CSG are
surprisingly straightforward.
Chapter 5: Surface normals and multiple objects.
If you want your code to be more efficient for large numbers of objects, use a BVH-- they are as good as any other in efficiency and are the most robust and easiest to implement.
Chapter 6: Antialiasing
Chapter 7: Diffuse Materials
"Ideal" diffuse materials, also called "Lambertian" are used 99% of the time in graphics. The
wikipedia article on this approximation is good. Real diffuse surfaces do not behave exactly as Lambertian (for example they get specular at grazing angle) but especially with interreflection in the mix the appearance differences are minor. So this is probably not where you should push your renderer until many many other features are addressed.
Chapter 8: Metal
The first improvement you might make is to have the color of the metal go to white at grazing angle. The Schlick approximation (used in Chapter 9 for glass where grazing behavior matters more) works for that. Full-bore Fresnel equations will describe color variation with angle, but in my experience getting
normal incident color is good enough.
Chapter 9: Dielectrics
Chapter 10: Positionable camera
Camera parameter setting is just plain ugly. The system used in the book is relatively common and is in my opinion the prettiest. I avoid the matrix formulation wherever possible because I never understand my code when I am done. But it is
very elegant and works.
Chapter 11: Defocus blur
Chapter 12: Where next?
You should have the core of a very serious ray tracer now. I would now take it in one of three directions. They are not mutually exclusive but explicitly deciding your goals will simplify architectural decisions.
- Make it physically accurate. This will imply using spectra instead of RGB (I like just using a big array of wavelengths) and get something where you know the reflectances. Popular is to get a X-Rite MSCCC ColorChecker Classic
whose data is available online.
- Make it good for generating animations. Lots of movies use a ray traced system, and Disney, Pixar, and the Solid Angle teams have both disclosed a remarkable amount about their code. Work on features and then efficiency. I think you will be amazed how soon you can produce amazing images.
- Make it fast. Here you can roll your own, or start using a commercial API. To see exactly where that community is now, go to the 2016 HPG conference. Or backtrack in their previous papers. They are a very open community and the papers go into much detail relative to many sub-fields in computer graphics.
Please send me your questions, comments, and pictures. Have fun with ray tracing!