An interactive, real-time 3D simulation of an orbital space station orbiting a planet, built for a university Computer Graphics curriculum. Implemented using WebGL and the Three.js rendering library, featuring custom GPU-level shading pipelines, hierarchical transformation matrices, dynamic multi-point lighting, and procedural surface mapping.
To demonstrate fundamental computer graphics illumination math, the simulation bypasses standard material abstractions to implement custom GLSL Vertex and Fragment Shaders via THREE.ShaderMaterial. The pipeline supports runtime toggling between three classic shading models:
- Flat Shading
[Key 1]— Face normals are computed dynamically in the fragment shader using screen-space partial derivatives (dFdxanddFdy). Renders hard faceted surfaces suitable for industrial cargo bay panels. - Gouraud Shading
[Key 2]— Lighting intensities (ambient, diffuse, specular) are computed per-vertex in the vertex stage and then linearly interpolated across each rasterised face. - Phong Shading
[Key 3]— Normals and positions are passed as varyings. Illumination equations are calculated per-pixel in the fragment stage, producing precise highlights and specular reflections.
Complex physical subsystems are modelled using nested spatial hierarchies where child objects inherit coordinate transforms from their parent groups:
- Robotic Arm (Canadarm) — Multiple articulated joints (shoulder rotation, elbow pivot, wrist orientation) operating sequentially in nested coordinate spaces.
- Solar Array Assemblies — Rotating solar panels track light angles by oscillating on their local joint axes relative to the main station's world rotation.
- Docking Port Clamps — Animated sliding blast doors open and close dynamically using parameterised trigonometric offsets.
- Autonomous Spacecraft — 5 high-fidelity hierarchical vessels orbit on elliptical trajectories, translated trigonometrically and oriented tangent to their orbital paths.
- Directional Light (Sun) — Acts as the primary lighting vector. Toggle Eclipse Mode (
L) to dim the sun and simulate planetary shadow coverage. - Sun Halo / Lens Flare — A procedural additive sprite maps a radial gradient to mimic camera optics when facing the sun.
- Point Lights (Navigation Beacons) — 6 coloured status lights blink in out-of-phase sine patterns, serving as active hazard indicators across the station's axes.
- Spotlights (Perimeter & Docking) — Focused cones with soft penumbra edges illuminate docking ports, while an active searchlight sweeps 360° around the main chassis.
The project relies entirely on procedurally generated HTML5 Canvas textures, requiring no external asset files:
- Diffuse Textures — Custom panel patterns, solar array matrices, and docking guidance stripes generated at startup.
- Normal Mapping — Perturbs lighting vectors on a per-pixel basis using custom normal texture maps to simulate structural rivets and panel grooves without additional geometry.
- Atmospheric & Cloud Dynamics — The planet uses a dual-shell model. The geological core rotates slowly while a translucent cloud shell rotates at an accelerated independent rate to simulate planetary winds.
- Environment Mapping — Starry nebulas and deep-space galaxy clouds are procedurally drawn onto a 6-sided
CubeTexture, providing reflections on metallic hull surfaces.
| Input | Action |
|---|---|
Mouse Drag |
Rotate view (Orbit Mode) · Look around (Free-Fly Mode) |
Scroll Wheel |
Zoom in/out (Orbit Mode) · Adjust speed (Free-Fly Mode) |
W / S |
Move forward / backward |
A / D |
Strafe left / right |
Q / E |
Translate elevation up / down |
| Key | Action |
|---|---|
C |
Cycle camera — Orbit → Free-Fly → Docking → Cinematic Tour |
P |
Pause / resume autonomous spacecraft trajectories |
L |
Toggle Day / Eclipse lighting mode |
B |
Toggle point-light navigation beacons |
F |
Toggle docking and searchlight spotlights |
X |
Toggle sun lens flare |
1 |
Apply Custom GLSL Flat Shading |
2 |
Apply Custom GLSL Gouraud Shading |
3 |
Apply Custom GLSL Phong Shading (default) |
Browser security policies restrict ES module imports over file:// — the project must be served over HTTP.
Option A — Python (built-in, no install required)
cd /path/to/space-station-3d
python3 -m http.server 8080Then open: http://localhost:8080/index.html
Option B — Node.js (npx)
npx serve . Scene Graph (Station, Ships, Robotic Joint Groups)
│
▼
Model Matrix (World Coordinate Space)
│
▼
View Matrix (Camera Coordinate Space)
│
▼
Projection Matrix (Perspective Division)
│
▼
Normalised Clip Space [-1, +1]
│
▼
Rasteriser (Fragment Interpolation of Varyings)
│
▼
Fragment Shader (Texture Maps & Colour Blending)
│
▼
Framebuffer (Double-Buffered Output)
Cylindrical geometry foundations — Structural modules use cylinder primitives because they represent realistic space architecture (designed to distribute internal atmospheric pressure evenly) while keeping polygon counts low.
DPI capping — On Retina displays, rendering at native 3× pixel scale causes GPU bottlenecks. The renderer is capped at 2× to preserve frame rates on macOS M-series hardware:
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));Live diagnostics — The HUD reads directly from renderer.info.render to display real-time FPS, active WebGL draw calls, and rendered triangle counts, enabling direct comparison of shading pipeline costs.