Raytracer

C++
Graphics 3D Rendering Math
View on GitHub

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

C++17 STL CMake OpenMP stb_image

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.