https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ec582c37-ef53-4c8a-93db-98f9858a2be1/Screen_Recording_2021-05-09_at_4.12.33_PM.mov
For our project, we implemented a simulation of raindrops sliding on a glass window using WebGL for rendering graphics. The main components of this project were architecting the raindrops themselves, the motion of the raindrops, and the fragment shaders used to simulate the reflection and refraction of raindrops. We also used a physically-inspired hack on the background image, blurring it to give it the appearance of glass for the raindrops to "slide" on. Our simulation responds to user controls and there are two menus to change the background and shaders and a GUI available to manipulate different raindrop architecture and motion parameters.
<aside> 💠Disclaimer: we're all pretty new to web development, so to minimize struggles with the infrastructure surrounding this project, we decided to clone an existing project with a similar stucture (RainEffect) and use its WebGL infrastructure as a foundation. We rewrote the motion simulation of each raindrop, and the shaders, from scratch, while using the article as a guide on specific physics/graphics areas to research and understand. We also added several novel components, including a handful of different shaders and a GUI to modify hyperparameters.
</aside>
When raindrops fall onto a window, they exhibit a few key behaviors. Below, we walk through the seven attributes of a raindrop that we define to characterize the behavior of a drop. Then, we discuss how we simulate the motion of each drop. This approach doesn't explicitly model the viscocity of the water/gravitational forces/etc. - but it does look realistic, and the approach is inspired by these physical properties.
rand(this.width)
rand(this.height) * 0.95
, where 0.95
is a factor that forces each raindrop to be slightly above the bottom of the viewrand(min_radius, max_radius)
Intuitively, we'd like larger drops to have larger momentums, so this momentum should be some random component scaled by the drop's radius.
Through trial and error, we define the initial momentum to be:
0.5 * [(d.r - min_radius) / (max_radius - min_radius)] * rand(2)
Over time, the momentum should vary based on randomness (how likely a drop is to "slip" down) as well as due to collisions with other drops.
The default momentum variable, momentum
, refers to the momentum along the main axis (y-axis). We also define a momentumX
variable that models the change in x position due to collisions and other randomness (intuitively, drops rarely fall in a perfectly straight line).