Web Raytracer
A fully featured, browser-based raytracer built from scratch in TypeScript with a live XML scene editor.

This project is a custom-built rendering engine that draws pixel-by-pixel to an HTML Canvas, implementing core raytracing mathematics from first principles. It features an integrated live editor allowing you to configure scenes using custom XML markup with real-time visual updates.
Rendering Pipeline
For every pixel on the canvas, the engine:
- Casts a ray from the camera origin through the pixel’s position on the view plane.
- Intersects the ray against every object in the scene — spheres and planes — computing the closest hit point and surface normal.
- Shadows: From the hit point, casts a secondary ray toward each light source. If an object blocks the path, the point is in shadow.
- Lighting: Computes colour at the hit point using three components:
- Ambient — constant base illumination
- Diffuse (Lambertian) — proportional to the cosine between the surface normal and the light direction
- Specular (Phong) — creates highlights based on the reflection of the light vector around the normal, controlled by a specular coefficient
kSand shininess exponentalphaS
- Reflections: If the surface has reflectivity > 0, the ray recurses — casting a reflected ray from the hit point and blending the result with the local colour.
- Bump Mapping: Perturbs surface normals using a texture image, simulating roughness without adding geometry. The bump map is sampled at the hit point and the RGB channels are converted to normal displacements.
Key Features
- Custom Raytracing Engine: Core mathematics for ray-sphere and ray-plane intersections, shadow casting, and recursive reflections — all hand-rolled in TypeScript with no graphics library dependencies.
- Live Scene Editor: CodeMirror 6 integration for real-time XML editing. Changes to the scene file update the render immediately on keystroke.
- Material Properties: Full support for ambient, diffuse (Lambertian), and specular (Phong) lighting models, plus configurable reflectivity per object.
- Bump Mapping: Texture-based normal perturbation for rough surfaces — includes sample bump maps for cobblestone, metal, and moon surfaces.
- XML Scene Definition: Scenes are entirely decoupled from the engine code and defined via an intuitive XML format, making them trivially shareable and version-controllable.
Example Scene
<scene>
<ambient-light colour="#050505"/>
<point-light x="-2" y="2" z="1" colour="#FFFFFF" intensity="80"/>
<point-light x="2" y="-2" z="1" colour="#AAAAFF" intensity="60"/>
<plane
x="0" y="-1" z="5"
nx="0" ny="1" nz="-0.2"
colour="#222222" reflectivity="0.6"
/>
<bumpy-sphere
x="0" y="0" z="3.5" radius="0.7"
colour="#FFFFFF" kS="0.8" alphaS="20"
bump-map="metal.png" bump-scale="15"
/>
</scene>
Technical Implementation
Built with TypeScript, Vite, and the HTML Canvas API. The rendering loop processes pixels in batches to avoid blocking the UI thread. The engine is entirely client-side — no server, no WebGL, just raw pixel manipulation on a <canvas>. The live editor uses CodeMirror 6 for syntax highlighting and real-time parsing of the custom XML scene format.
The Web Raytracer makes the rendering equation tangible. It bridges the gap between the mathematical models covered in the Graphics course and their concrete implementation in code.
See the Computer Graphics revision notes for the underlying theory on ray tracing, shading models, and rendering techniques.