Skip to content
← 02 / Projects

06 / Description

Light2D: Dispersion in 2D

A 2D light transport simulator in C: mirrors, scatterers and glass lenses, with colour dispersion that splits white light into rainbows.

  • C
  • Optics
  • Snell's law
  • Fresnel
  • Dispersion
refracting lenses in the scene
12
dispersion: index shifts with hue h
n + 0.5h

Interactive

Drag lights and shapes, add or remove them, and resize with the sliders. Rays re-trace live.

Add to scene

Selected: none

Click a light or shape in the scene.

Symmetric scene of twelve glass circles lit by a point source at the centre, with rainbow fringes along the refracted beams
Fig. 1 Full scene: 12 glass circles, point light at the centre
Close-up of a beam leaving a lens, split into red, green and blue bands
Fig. 2 Detail: dispersion fringes

Problem

Simulate how light moves through a box of objects: it bounces off mirrors, scatters off rough walls, and bends through glass. The starter code (CSC D18, F.J. Estrada) supplied the scene, image and ray-drawing machinery. I wrote the propagation core and then went past the brief.

Approach

Rays leave a point source in random directions and are traced recursively. Each step finds the nearest hit among the four walls and the circles (a quadratic solve per circle), draws the segment, then branches by material. Mirrors reflect, scattering surfaces send the ray out in a random direction in the hemisphere around the normal, and glass splits it into a reflected and a transmitted ray whose brightness is shared by the Fresnel term. Each ray is drawn additively, so bright regions come from many rays overlapping.

Key technical decision

Dispersion. Every ray is born with a random hue in [0, 1], converted to RGB, and that hue also shifts the glass's refractive index (n + 0.5 × hue). Because Snell's law then bends each colour by a slightly different angle, the white light fans out into a spectrum with no extra rendering step. The strength of the effect is a single constant.

Result

A symmetric scene of twelve glass circles produces caustics and rainbow fringes along the refracted beams. The image above is the submitted render.

Build it

cd light2D_1009319881
gcc -O2 -o light2D light2D.c -lm              # add -fopenmp for multithreading, if available
./light2D 1080 1080 300000 12                 # width height rays max_depth, writes light2D_output.ppm

Output is a PPM, so convert it to PNG to view it. Each glass hit spawns two child rays, so cost grows quickly with depth: a small run (512 x 512, 3,000 rays, depth 8) takes about 2 seconds single-threaded.