This project implements a basic ray tracer in C++ and provides an optimized version using Metal for GPU acceleration on macOS. The ray tracer generates a 3D scene with spheres and light sources, rendering the output as a PPM image.
- CPU Implementation: A basic ray tracer written in C++.
- GPU Optimization: A Metal-based implementation for faster rendering on macOS devices with Apple Silicon.
- Reflections and Transparency: Supports reflective and transparent surfaces.
- Lighting: Includes point light sources with shadow calculations.
- Scene Customization: Easily modify the scene by adding or removing spheres and lights.
raytracer.cpp # CPU-based ray tracer implementation
raytracergpu.mm # GPU-optimized ray tracer using Metal
Raytracer.metal # Metal shader for GPU ray tracing
compile.sh # Script to compile the Metal-based implementation
untitled.ppm # Output image (PPM format)
3.png # High-resolution render with transparency 0.7
1.png # First render
2.png # Render with transparency 0.3
The CPU-based ray tracer (raytracer.cpp) uses recursive ray tracing to compute:
- Ray-Sphere Intersections: Determines if a ray intersects a sphere.
- Lighting: Calculates the color of each pixel based on light sources and shadows.
- Reflections and Refractions: Handles reflective and transparent surfaces using recursive rays.
The GPU-optimized version (raytracergpu.mm and Raytracer.metal) leverages Metal's compute shaders to parallelize the rendering process. Each pixel is processed by a separate GPU thread, significantly improving performance.
- Compile the CPU version:
c++ -std=c++14 -O3 -Wall raytracer.cpp -o raytracer
- Run the program:
./raytracer
- The output image will be saved as
untitled.ppm.
- Navigate to the
GPU Optimizeddirectory:cd "GPU Optimized"
- Make the compile script executable:
chmod +x compile.sh
- Compile and run the GPU version:
./compile.sh && ./raytracergpu - The output image will be saved as
untitled.ppm.
To add a sphere, modify the main function in raytracer.cpp or raytracergpu.mm:
spheres.push_back(Sphere(Vec3f(x, y, z), radius, surfaceColor, reflection, transparency, emissionColor));x, y, z: Position of the sphereradius: Radius of the spheresurfaceColor: RGB color of the spherereflection: Reflectivity (0 to 1)transparency: Transparency (0 to 1)emissionColor: RGB color of emitted light
To add a light source, use the same Sphere structure with emissionColor set to a non-zero value:
spheres.push_back(Sphere(Vec3f(x, y, z), radius, Vec3f(0, 0, 0), 0, 0, emissionColor));The rendered image is saved in PPM format. You can view it using any image viewer that supports PPM, such as Preview on macOS.
| Version | Resolution | Time |
|---|---|---|
| CPU | 640x480 | ~10s |
| GPU | 640x480 | ~1s |
- CPU Version: Any platform with a C++14 compiler
- GPU Version: macOS with Metal support (Apple Silicon recommended)
See LICENSE for license information.


