An interactive 3D world built with Three.js: a tropical coast that drifts into a fantasy village and a rain-soaked mountain range. Every object is procedural or hand-built from primitives, animated with custom GLSL shaders, particle systems and spline paths, and the camera can ride along with the boat, the swimmer or the flock of geese.
| Area | Highlights | Code |
|---|---|---|
| Beach | Animated sand dunes: a custom vertex + fragment shader displaces the plane with 4-octave value noise that drifts over time and tints the crests by height. | app/sandShader.js |
| Sea | A subdivided water plane rippled in real time, two boats that bob, roll and patrol the strip, and an articulated swimmer with windmilling arms and kicking legs. Boats and swimmer are rideable. | app/extras.js |
| Park | Carousel, teacup ride, tilt-a-wheel, swings and roundabouts with layered sinusoidal motion; a flock of geese following a closed Catmull-Rom spline, steering toward a look-ahead point, each bird flapping with its own phase. | app/07-08-parkobjects.js |
| Village | Wizard tower, blacksmith workshops, market stalls, palm trees, enchanted oaks and mushroom clusters, all built from primitives with hand-made textures. | app/08-06-buildings.js |
| Mountains and sky | Mountains from per-vertex noise displacement with height-blended snow caps, drifting low-poly clouds, and a rain particle system (THREE.Points) that recycles drops from the cloud layer. |
app/extras.js |
| Lighting and environment | A cube-map skybox that doubles as the PBR environment map, a shadow-casting sun with PCF soft shadows, and a glTF campfire loaded asynchronously and wrapped into the animation loop. | app/final-grtown.js |
- Orbit camera (default): drag to rotate, scroll to zoom, right-drag to pan.
- Ride something: in the control panel pick Drive Object or Follow Object, then choose the boat, the swimmer or the flock of geese.
- Fly camera:
WASDto move,R/Ffor up and down, drag to look around. - LookAt: jump the camera to any object. The speed slider scales all animation; Run pauses it.
There is no build step; any static file server works. Modules and textures have to be served over HTTP, so opening the HTML files straight from disk will not work.
git clone https://github.com/drunkcaterpillar/graphics-town.git
cd graphics-town
python3 -m http.server 8000
# open http://localhost:8000/ (project page)
# open http://localhost:8000/app/ (the demo)index.html project page
app/index.html the demo page
app/final-grtown.js scene assembly: world, skybox, sun and shadows, layout of every strip
app/extras.js sea, beach and sky objects: water, boats, swimmer, chairs, umbrellas, mountains, clouds, rain
app/sandShader.js animated dune ShaderMaterial (GLSL)
app/07-08-parkobjects.js amusement rides and the bird flock
app/08-06-buildings.js buildings and vegetation, shared texture loading
app/models/campfire.glb the loaded model
textures/ hand-made textures and the skybox cube map
libs/CS559-Three/ Three.js r173, trimmed to the modules the demo imports
libs/CS559-Framework/ the Graphics Town framework (GrWorld, GrObject, WorldUI)
libs/CS559/ small DOM helpers used by the framework
assets/ screenshot used by the page and this README
- Vanilla ES modules served as static files. No bundler and no framework build; the page loads
app/final-grtown.jsdirectly and it imports everything else. - Three.js r173 is vendored and trimmed to the modules that are actually imported (core build,
OrbitControls,FlyControls,GLTFLoaderand their dependencies). - The CS559 Graphics Town framework is a thin
GrWorld/GrObjectwrapper around Three.js that provides the animation loop, the camera modes (orbit, fly, follow, drive) and the control panel. All scene objects inapp/are subclasses ofGrObjectwith their ownstepWorldanimation logic. - The project started as my final project for CS559 Computer Graphics at UW–Madison (Spring 2025).
The file names under
app/keep the numbering from the course workbook they were first written for.
- Everything in
app/and the textures intextures/*.pngare my own work and are released under the MIT license. - The skybox in
textures/skybox_mountains/is the "Ryfjället" cube map by Emil Persson (Humus), used under CC BY 3.0. app/models/campfire.glbis from CGTrader and is used under its own license, not the MIT license.- Three.js (MIT) and the CS559 framework (BSD-2-Clause) are vendored in
libs/; their license texts are kept alongside them and summarised in THIRD_PARTY_NOTICES.md.
