In this project, I implemented a real-time simulation of a cloth using a mass and spring based system. I built data structures to discretely represent the cloth, defined and applied physical constraints on them, and applied numerical integration to simulate the way cloth moves over time. Then, I implemented collisions with other objects as well as self-collisions to prevent cloth clipping. Lastly, I made a variety of shaders to visually improve the appearance of the cloth.
Here is a screenshot of the cloth wireframe of scene/pinned2.json
, showing the structure of the point masses and springs.
Here are some images of the wireframe (1) without any shearing constraints, (2) with only shearing constraints, and (3) with all constraints.
![]() |
![]() |
![]() |
Shown below are final resting views of scene/pinned2.json
with different values for the spring constant ks
.
![]() |
![]() |
![]() |
![]() |
A low ks
produces a loose cloth (more folds at top) while a high ks
produces a tight cloth (less folds at top).
Shown below are final resting views of scene/pinned2.json
with different values for density
.
![]() |
![]() |
![]() |
![]() |
A low density
means less downward gravitational force on the cloth (less folds) while a high density
means more gravitational force (more folds).
Shown below are final resting views of scene/pinned2.json
with different values for damping
.
![]() |
![]() |
![]() |
![]() |
A low damping
value means the cloth will behave with more spring (come to rest slower) while a high damping
value means the cloth will react more sluggishly (come to rest sooner).
Here is a screenshot of scene/pinned4.json
at its final resting state with default values.
Shown below are the final resting state of scene/sphere.json
with different values of ks
.
![]() |
![]() |
![]() |
Here is a screenshot of scene/plane.json
at its final resting state.
Here are some gifs of scene/selfCollisions.json
with varying ks
and density
values.
![]() |
![]() |
![]() |
![]() |
With a higher ks
value, the cloth has less ripples and has a smoother look. There are less bends and folds overall.
With a lower density
value, the cloth spreads out more as it hits the plane.
Shaders are isolated programs that run in parallel on GPU, outputting a single 4 dimensional vector representing the color at an input.
There are two basic OpenGL shader types:
gl_Position
. The per-vertex values are interpolated via barycentric coordinates across the face of the polygon.out_color
.explain blinn=phong here.
Here are screenshots of the individual Blinn-Phong model components.
![]() |
![]() |
![]() |
Combing the three components results in:
Here is a screenshot of the texture mapping shader
Bump mapping results in a visual appearance of the texture on the surface, but does not change the geometry. Displacement mapping on the other hand, changes the geometry to match the texture. Here are some screenshot of bump and displacement shaders.
Bump mapping vs displacement mapping on the cloth at -o 128 -a 128
.
![]() |
![]() |
Bump mapping vs displacement mapping on the sphere at -o 128 -a 128
.
![]() |
![]() |
Bump mapping vs displacement mapping on the sphere at -o 16 -a 16
.
![]() |
![]() |
The shaders at different sphere mesh coarseness are, in my opinion, not very noticeable and different. However, I would say that the lower resolution results in a less smooth surface.
Here is a screenshot of the mirror shader.
![]() |
![]() |