C++ implementation of Computer Graphics from Scratch book for self-studying purposes.
The book is using JavaScript and HTML Canvas to implement logic and display results. It seems to me that the easiest implementation in C++ without using any libraries, is to render results straight into the bmp files. So I've added a quick bmp implementation.
mkdir -p bin results
clang++ -std=c++17 examples/<example>.cc -o bin/<example>
bin/<example> && open results/<example>.bmp
| 01 - Basic Raytracing | 02 - Diffuse Reflection | 03 - Specular Reflection | 
|---|---|---|
|  |  |  | 
| 04 - Shadows | 05 - Reflections | 06 - Camera | 
|---|---|---|
|  |  |  | 
Here I had to introduce few changes to the code.
First, a "shadow acne" appeared on the yellow ball when I've added a reflections computation. We're recursively firing rays that are very close to the surface, and a floating-point error can be accumulated after each bounce. The book examples don't have it since, they are using JS language where numbers have double-precision, while here I'm using a float which has a single-precision.
Another thing I've noticed is that when I was using uint8_t values to represent a color ranging from 0 to 255, I was getting a bit different results with lights and reflections.
So I switched to float with 0 to 1 range, which allowed me to represent more variety of colors during computations. I also didn't need to clamp values anymore until the very last moment when converting the image data into the bmp file format.
| Shadow Acne | Color uint8_t | Color float | 
|---|---|---|
|  |  |  | 
Here I've implemented shadow optimization and bounding volume hierarchy tree (BVH) myself as an extra exploration of the topic. I've also added a subsampled option to see what effect it has on quality and performance.
| Original | BVH & Shadow Optimizations | Subsampling | 
|---|---|---|
|  |  |  | 
Next, based on the existing BVH tree and Object abstraction, I've added Triangles to the scene. Then I've spent quite some time to get CSG right - had to rewrite intersect method few times and ended up with the simple event-walking which suits any amount of enter-exit object pairs. Reflection was a bit easier but not less fun - it looks pretty cool when you see the result of CSG+Transparency combo as a magnifying glass on top of the pyramid. And blending reflection with refraction colors showed that I had to increase raytracing recursion depth to see the refracted reflection of the maginfying glass :D
| Other Primitives | Constructive Solid Geometry | Transparency | 
|---|---|---|
|  |  |  |