skip to content

Cornell Box

[completed]Three.js, WebGL, TypeScript, Reactgithub ↗

Project Overview

The Cornell Box is the canonical test scene in computer graphics — a simple closed room with a red wall on the left, a green wall on the right, white walls / floor / ceiling, and one or two boxes on the floor. It exists to demonstrate global illumination: how light bounces off colored surfaces and tints nearby objects (the classic "color bleed" from the red wall onto the floor and box).

This is my Three.js implementation. It renders the canonical Cornell Box scene with a single area light, soft shadows, and approximated indirect bounce light. The goal was to get something that looks like the Cornell Box paper screenshots without writing a full path tracer.

scene loads on this page in phase 3

Approach

Three.js doesn't ship a global-illumination renderer out of the box — THREE.WebGLRenderer is a real-time rasterizer, not a path tracer. So I cheated. The scene uses:

  • One RectAreaLight at the ceiling for the primary key light + soft shadow.
  • Per-wall colored point lights at low intensity to fake color bleed. The red wall has a low-intensity red point light tilted toward the floor; same for the green wall.
  • Physically-based materials (MeshStandardMaterial) so the bleed reads as actual lighting rather than texture tinting.
  • Shadow mapping (PCFSoftShadowMap) with a tuned bias to avoid acne on the white walls.

It's a fake. A real Cornell Box renders with path tracing or photon mapping to capture the diffuse interreflection correctly. But for an interactive 3D scene in 60 FPS, this gets ~85% of the visual fidelity at 0.1% of the render cost.

What I Learned

  • RectAreaLight needs RectAreaLightUniformsLib.init() before it'll render — easy to miss, breaks silently otherwise.
  • MeshStandardMaterial with roughness: 1.0 on the walls gives the matte Cornell-paper look — anything less and the walls feel like plastic.
  • Color bleed via secondary lights is the kind of trick that doesn't survive close inspection but reads correctly in a wide shot. Real path tracing would be better, but three-mesh-bvh + a custom rasterizer is its own multi-week project.
  • The classic Cornell Box has one tall box and one short box. I tried with three boxes; it looks wrong. There's a reason the canonical scene is what it is.