Carousel Graphics Scene
Final Project! Repo Class Assignments
Overview
Background
For my final project in Wellesley’s computer graphics course (CS 307), I collaborated with a classmate (Isa Lie ‘23) on creating a 3D graphics scene with an interactive, animated carousel music box using JavaScript. The goal of this project was to leverage the computer graphics concepts we learned throughout the course to create a graphics scene that went beyond the complexity and scope of the assignments. The project was broken up into three stages: a first draft, alpha version, and final version.
Scene Description
Our scene consists of an animated carousel music box from complex geometries that users can interact with by winding up the box and releasing the handle, which plays music. Some other components include texture mapped backgrounds (i.e. wooden floor and sky dome) and various lights (i.e. ambient, directional, spotlights) that can be toggled on/off with the light switch.
Graphics Concepts
Modeling
We used a variety of curves, surfaces, and geometries to model our scene. In addition, we implemented a hierarchical structure with creating meshes, adding them to objects, and building on top of these objects. To further challenge ourselves, we used some Three.js geometries that required us to create our own paths or Bezier curves, which are described in further detail under the Curved Surfaces section.
Material, Lighting, and Shading
We used Phong material for all of our components, and added shininess and specular properties to the handle and music box base to create a metallic appearance. For lighting, we used generic ambient and directional lights positioned at the top of the scene, a spotlight for each horse, and point lights for the light decorations on the tent.
Code snippet of math calculations and adding a point light to the planet decoration:
Camera
We used a perspective camera and established the vertical field of view, aspect ratio, near, and far plane parameters. Additionally, we used the lookAt()
function to initially face the camera at a certain point in the scene. Setting up a camera was essential, as the raycaster in our user interaction component depended on both the camera and mouse position.
Textures and Texture Mapping
We used loaded images to texture map for the wooden floor and the sky background. The wooden floor uses repeated wrapping, and the sky background uses mirror repeated wrapping to create a smooth transition between the repeated sky images.
Code snippet of texture mapping for the sky background:
Curved Surfaces
We used several complicated geometries to create our more detailed components, such as TubeRadialGeometry
for the horses’ manes, ExtrudeGeometry
for the moon light, and TubeGeometry
for the handle. These geometries required us to create our own Bezier curves using vectors or specify settings to control depth and bevel thickness.
Code snippet of using Bezier curves and TubeGeometry
to create a handle geometry:
Transparency
The light bulb at the top of the tent and light decorations make use of the opacity property to create a more realistic glass appearance.
User Interaction
We implemented user interaction in multiple areas. For example, by clicking the light switch, the switch moves and the user can turn on and off the carousel light decorations. This was accomplished by declaring the lights controlled by the light switch as global variables, then using multiple helper functions to control their presence and visibility in the scene. Users can also interact with the music box upon clicking the spinning handle to trigger the animation, which is explained in more detail under the Animation section.
Code snippet of light switch user interaction:
Animation
To model a real music box, users can press ‘w’ to “wind up” the mechanism, allowing the carousel to freely spin upon releasing the handle. This involved 3 variables, windStepCycle
, currentStep
, and total
. While incrementing the currentStep
and total
variables by one with the advancement of each frame, each time the user winds up the handle, the handle and carousel slowly rotate counter-clockwise until reaching a certain number of frames (established as our windStepCycle
constant). Then, pushing ‘r’ emulates releasing the handle, causing the handle and carousel spin faster and clockwise until the total variable is reset to 0.
Code snippet of key wind-up animation:
Technology & Tools
Languages
References
- Three.js: JavaScript API built on top of WebGL that helps users easily model and render graphics
- TW module: Professor Scott Anderson’s custom API layered on top of Three.js to package common operations
- CS 307 website: enrolled in Spring 2021, instructed by Professor Ellen Hildreth