Raytracer
A software raytracer built entirely from scratch in C++. This project implements physically-based rendering techniques including reflections, refractions, soft shadows, and support for multiple light sources.
Overview
Raytracing is one of the most elegant algorithms in computer graphics. At its core, it simulates how light travels through a scene by tracing rays from the camera through each pixel and calculating how they interact with objects in the scene.
I built this raytracer to deeply understand the mathematics behind 3D rendering. Rather than using existing libraries, I implemented everything from vector math to the rendering pipeline, which gave me invaluable insight into how modern graphics engines work under the hood.
Key Features
Reflections & Refractions
Physically accurate reflection and refraction calculations using Snell's law and Fresnel equations for realistic glass and metal surfaces.
Soft Shadows
Area light sources that cast soft, realistic shadows with penumbra regions, creating more natural-looking scenes.
Multiple Light Sources
Support for point lights, directional lights, and area lights with proper color mixing and intensity falloff.
Anti-Aliasing
Multi-sample anti-aliasing (MSAA) for smooth edges and reduced jaggies in the final rendered image.
Technical Implementation
The raytracer is built using modern C++17 features. The core algorithm traces rays recursively through the scene, calculating intersections with primitives (spheres, planes, triangles) and computing lighting at each hit point using the Phong reflection model.
Performance optimizations include a bounding volume hierarchy (BVH) for fast ray-object intersection tests, reducing the complexity from O(n) to O(log n) for scenes with many objects. I also implemented multi-threading using std::thread to distribute ray calculations across CPU cores.
The BVH implementation alone improved render times by 10x for complex scenes with 1000+ objects.
Tech Stack
What I Learned
Building a raytracer from scratch taught me more about linear algebra than any course. Understanding how to transform vectors between coordinate spaces, calculate ray-surface intersections, and implement physically-based lighting models gave me a solid foundation for graphics programming.
I also gained experience with performance profiling and optimization, learning to identify bottlenecks and apply data-oriented design principles to maximize cache efficiency.