Ray Tracer
- 3 Devlogs
- 15 Total hours
I have been looking at making my own ray tracer for a long time now, so I decided that I can make one now!
I have been looking at making my own ray tracer for a long time now, so I decided that I can make one now!
Just a quick update. It turned out that I didn’t use any compiler optimizations when testing the renderer. With them the renderer is even faster. I need to do further testing on how faster, but in the meantime you can enjoy this render that took a whopping 4,500 seconds to render! Each pixel is made of 2500 samples and the ray bounce depth is set to 50.
This will be quite a short one…
So basically this works by “randomizing” the camera’s origin point. So now, when you want, it could be a small disk on which rays will originate randomly! This “defocuses” (adds a depth of field) effect to the image.
This was a very simple change. I basically just split the work (by scanlines) between multiple threads. Right now you have to hard code it into the code but I promise that I will make a UI for the RayTracer some day. Or at least a CLI. The performance gains are significant. On my CPU (Ryzen 7 9800x3d) was the render almost 5x faster. For how simple this change was, its a massive jump.
I have also linted the code with clang tidy so it follows modern conventions and google’s rules.
Also I’m a bit tired of all the balls already. So next I will look into model loading!
Hi people!
I’ve been getting bored making my LMU Telemetry app, so I started experimenting with ray tracing, and its so fun. You can’t imagine how refreshing is working on a new project!
The first thing I have implemented was the camera. In retrospect it wasn’t even that hard, but let me tell you, it was a pain. Mainly because I had no prior experience with vector math. So I had to learn how to do dot products and cross products and then wrap my head around how the camera functions. Its pretty simple: there is a point in space which is the origin of the camera called the eye. In front of this eye is the viewport. The depth of the viewport is defined by the desired FOV. On this viewport, we need to know which way is right (to positive x in ppm coordinates) and which way is “down” (to positive y in ppm coordinates) so we create 2 vectors in these directions. Then we need to know where the actual pixels are, therefore we find where pixel 00 lives and the deltaX and deltaY to the next pixel and iterate over all those pixels and do the raytracing stuff, which is sending out rays through each pixel and checking what they hit!
After sorting out the camera, I have implemented the sphere! Sphere is possibly the simplest shape for ray tracing, because it has a simple formula: x^2 + y^2 + z^ = r^2 where (x,y,z) is the center of the sphere and r is the radius.
Next we need to give our sphere some material to know what color should the ray have and how should it reflect. I have implemented 2 materials: lambertian, metal, and dielectric. Lambertian is basically a diffuse material. The rays scatter in almost random directions and therefore no reflections can be seen. Metal is basically a mirror, and dielectric is glass.
I antialias the renders by basically torturing the computer! Instead of sending one ray in the dead center of the pixel, I send multiple rays with small random offsets and average them out.
And that’s basically it! I might have forgotten something but that’s probably fine. I have followed the RayTracing in a weekend book and will continue with the next of the triology.