Single shot vibe coded path tracer in python
Find a file
2026-09-18 15:25:19 +02:00
cornell_box_render.png first version 2026-09-18 14:27:37 +02:00
preview.png first version 2026-09-18 14:27:37 +02:00
raytracer.py first version 2026-09-18 14:27:37 +02:00
README.md first version 2026-09-18 14:27:37 +02:00
requirements.txt add requirements 2026-09-18 15:25:19 +02:00

Cornell Box Raytracer

A pure Python raytracer that renders the Cornell Box scene with:

  • Reflections - mirror/chrome spheres reflect surrounding geometry
  • Caustics & Refraction - glass spheres bend light (dielectric material with Schlick approximation)
  • Multiple Bounces - recursive path tracing up to configurable depth
  • Next Event Estimation (NEE) - explicit light sampling for fast convergence
  • Anti-aliasing - supersampled pixels with jittered rays
  • Multiprocessing - parallel rendering across CPU cores

Requirements

  • Python 3.8+
  • numpy
  • Pillow
pip install numpy Pillow

Usage

python raytracer.py [width] [height] [samples_per_pixel] [max_bounces] [output]

Examples

# Quick preview (4 min)
python raytracer.py 200 150 20 10 preview.png

# Good quality (~10 min)
python raytracer.py 400 300 50 15 cornell.png

# High quality (~40 min)
python raytracer.py 800 600 100 15 cornell_hq.png

# Custom camera and scene parameters can be set by editing the __main__ block

Parameters

Parameter Default Description
width 400 Image width in pixels
height 300 Image height in pixels
samples_per_pixel 50 Anti-aliasing samples per pixel
max_bounces 15 Maximum ray bounce depth
output cornell_box.png Output PNG filename

Workers

Multiprocessing uses 4 workers by default. Change workers=4 in the render() call.

Scene Description

The scene is the classic Cornell Box:

  • 5 walls (floor, ceiling, left=red, right=green, back=white) with the front face open
  • A small bright light source on the left wall
  • A glass sphere (refractive, IOR=1.5) - demonstrates refraction and caustics
  • A mirror sphere (perfect reflection) - demonstrates reflections
  • A red diffuse sphere - demonstrates diffuse scattering

Camera

  • Position: (278, 278, -800)
  • Look-at: (278, 278, 278) (box center)
  • FOV: 40°
  • Focus distance: 1078

Materials

Material Implementation
Diffuse (Lambertian) Cosine-distributed random scattering + NEE
Mirror Perfect specular reflection
Dielectric Snell refraction + Schlick fresnel + random bounce
Light Emissive surface, sampled via NEE

Performance

Approximate render times (with multiprocessing, 4 workers):

Resolution spp Time
200x150 20 ~2 min
400x300 50 ~10 min
800x600 50 ~40 min

How It Works

  1. Primary rays are cast from the camera through each pixel (with supersampling jitter)
  2. Ray-object intersection tests against planes (walls), spheres, and boxes (light)
  3. Surface scattering:
    • Diffuse: random hemisphere direction + explicit light sampling (NEE)
    • Mirror: perfect reflection vector
    • Dielectric: refraction with Snell's law, Schlick approximation for total internal reflection
  4. Recursive bouncing: each scattered ray continues tracing up to max_bounces
  5. Radiance estimation: L = Le + ∫ f_r * L_i * cos θ dω approximated via Monte Carlo integration

Next Event Estimation

For diffuse surfaces, the direct light contribution is computed by explicitly sampling points on the light source, testing visibility via shadow rays, and weighting by the BRDF and light PDF. This dramatically reduces variance compared to pure path tracing.

Output

Renders save as PNG with gamma correction (sqrt/gamma 2.0 applied).