back home

blog

a pane in the glass — part 1: why light slows down

seriesa pane in the glasssnell's law to webgl, one pane at a time
  1. ○part 0the setup
  2. →part 1why light slows down
  3. ○part 2apple's beautiful lie
  4. ○part 3webgl: the real thing

Glass looks like nothing. That's the trick. You press your face against a window and what you see isn't the glass — it's the world on the other side, slightly flattened, slightly cooler. The glass itself is almost absent from your perception, a ghost material that redirects light without announcing itself.

But "transparent" is a massive lie of physics. Glass does a tremendous amount of work behind that frictionless surface. It slows light down. It bends it. It partially reflects it back at you every time. It separates white light into its constituent frequencies if you push it hard enough. The reason it looks like nothing is precisely because it does all of this uniformly, consistently, invisibly — a precise optical machine masquerading as mere air.

This post covers the physics behind that. In Part 3 we'll implement every single concept below as a line of GLSL.

The speed of light isn't universal

The "speed of light" — roughly 299,792 km/s — is the speed in a vacuum. Through any physical medium, it slows down. The ratio by which it slows is the refractive index, notated as n.

Air: 1.0003. Water: 1.33. Soda-lime glass: ~1.5. Diamond: 2.42. The higher the index, the more the material grabs light, and the more dramatic the optical effects. When light hits the boundary between two materials with different n, two things happen simultaneously: some passes through (refraction), and some bounces back (reflection). The ratio is governed by the Fresnel equations.

The refractive index also depends on the frequency of the light. Violet slows more than red in most materials. This is called dispersion, and it's why a prism splits white light into a rainbow — and why our WebGL shader samples the background texture three times with slightly different n values for R, G, and B.

Snell's law

When light crosses from one medium into another, it bends. The governing equation is Snell's law: n₁ sin(θ₁) = n₂ sin(θ₂). A higher refractive index on the exit side means a smaller exit angle — the ray bends toward the surface normal. GLSL exposes this directly as refract(incident, normal, eta) where eta = n₁ / n₂. That single function call in the shader is the equation below.

45°
1.5

Snell's law · n_air=1.00 → glass

Total internal reflection

Flip the scenario: light inside glass trying to escape into air. It goes from a slow medium to a fast one, so it bends away from the normal. Past the critical angle, there's nowhere for the light to go — it reflects completely. For glass (n=1.5) that's 41.8°. For diamond (2.42), just 24.4° — which is why a well-cut diamond traps and bounces light so aggressively before releasing it.

In the WebGL shader, refract() returns a zero vector when the angle exceeds critical — the same physics, handled automatically.

35°
1.5

Total internal reflection · light traveling inside glass → air

The Fresnel equations — why glass is always a mirror

Every glass surface reflects some light. Always. At normal incidence a single surface reflects ~4%. At grazing angles it jumps toward 100%. This is why a pool looks like a mirror at a shallow angle but transparent straight down. In the shader we use the Schlick approximation: R₀ + (1−R₀)(1−cosθ)⁵ — cheap, accurate enough, and it produces exactly the rim brightening you see in the demo.

1.5

Fresnel reflectance vs. angle of incidence (unpolarized light)

Dispersion — the prism effect

The refractive index isn't a fixed number — it varies with wavelength. Violet bends more than red. This is dispersion, quantified by the Abbe number: low = high dispersion (flint glass, prisms), high = low dispersion (crown glass, camera lenses). In the shader, the u_disp uniform is exactly the Abbe number's inverse — it sets how far apart the red and blue indices are, and therefore how wide the chromatic fringing gets at the glass rim.

40°
0.08

Prism dispersion · white light separating into spectrum

That's the physics foundation. In Part 2 we look at how Apple simulates this — which parts they implement, which parts they skip, and why the brain accepts the shortcut. In Part 3 we come back to each equation above and write it in GLSL.