The Raytracer
Raytracing Engine. From Scratch. In C. Demo Below
The project I want to showcase is the miniRT (mini-raytracer). Like the shell, this was part of the 42 curriculum, and was built under the same rules and constraints as the previous project.
The source code for this project is available here.
This time, the assignment was to create a simple raytracer from scratch, using a custom wrapper around the Linux X11 API for simple window creation and I/O.
A raytracer is a program that uses a technique called raytracing, which is a technique used to create realistic images digitally. Raytracing essentially means that we simulate looking at a scene from our "eye-position", and use the computer screen like a window through which we look at this scene.
We imagine shooting a perfectly straight "ray" from our "eye" through each pixel of the screen, and trace that ray's path to see if it will intersect with an object. If yes, we know that this specific pixel should display the color of the object that it hit. Using some math to check for lighting, shadows from other objects, distance and more, we can determine a final color for each pixel, and with that create a remarkably realistic image from our scene.
On top of the basic image generation, we added extra features that were not required by the subject, but seemed interesting enough to learn about and implement on our own. Some of the extra features are:
- Multithreaded
- Textures and Bumpmaps
- Dynamic Scene/Texture/Bumpmap loading
- Custom font with text rendering functionality
- Custom SDK to create Menus with buttons and sliders
- Simple File-Explorer to load resources at runtime
- Different Reflection Models
- Objects as Perfect Mirrors
- Skybox
This was a team project, and my teammate Benjámin Szilas implemented a lot of features that were essential to the project. He is responsible for a lot of the tracing functions, and implemented things like shadows, mirrors, Phong reflection, multiple lights, anti-aliasing and much more.
In our project, I was responsible for many I/O (input/output) related features, like mouse and keyboard input, file parsing, the custom file explorer, the whole UI concept including menus, buttons, folder navigation, text rendering, and live loading of scenes and textures. I also implemented features like textures and bump maps, the checkerboard pattern, and more.
I had a lot of fun with this project, and learned a lot about graphical programming, working as a team and (some) maths!
As a final note: since we finished the project, I was planning on showcasing it here, and so I have reimplemented the rendering layer to use Raylib since it seemed more appropriate to use.
I have provided a live version below. Feel free to play around with it!
There are two ways to run the app: either directly in your browser as a WASM (WebAssembly) program, or over a live noVNC connection to an instance running on the server.
The raytracer itself is multithreaded, but since JS/WASM runs on a single thread, the WASM version is very slow. I scaled down the resolution for that version in order to have it not run at -5 FPS.
Thanks to noVNC and Raylib for the web integration. Their stuff is really great!