Final Report

Alyssa Lau, Jessica Plotkin, Jonathan Liu, and Zoe Zhang



Abstract

In this project, we built a 2D lava lamp simulator on ShaderToy from scratch. Our program attempts to simulate the movement patterns of the wax blobs and the various interactions between them. The wax objects in our simulation are represented using a system of metaballs, which allows for the smooth merging and divisions. To make our simulation more physically realistic, we utilize a temperature gradient to modify the size and speed of the wax blobs at different depths of the lava lamp. To make our simulation visually appealing and interesting, we created a variety of wax and background color combinations and wax effects. We also created a shaded version of the lava lamp using imaginary normals and a fake light source.

Implementation

Wax blobs

To represent the wax blobs in our lava lamp, we utilized a system of circular metaballs. We experimented with a variety of different equations to define our metaballs and eventually found that we got the best looking metaballs by modifying the equation from this site (metaball analysis):


\[ M = {r \over 0.8 * \sqrt{x^2 + y^2}} \]

We had to be strategic with our metaball placement, as putting them at the wrong starting locations could cause the balls to constantly “clump” together, leading to some unsatisfying visuals. We also had to fine tune the size of the balls, since they would constantly merge if they were too big or rarely interact if they were too small.

Three Balls, Radius=0.1

Three Balls, Radius=0.08F

Three Balls, Radius=0.05

By carefully placing circles of different sizes at various locations within the lava lamp, we were able to create a simple system with smooth merging and satisfying visuals.

Simple Circular Metaballs

However, most of the wax blobs in a real lava lamp aren’t perfect circles. To make our wax blobs more realistic looking, we placed multiple metaballs of varying sizes in close proximity to each other, which made them constantly merge together into more interesting shapes. The distance between the “submetaballs” needed to be fine tuned, since spacing them out could cause irregular shapes to form.

Wax Blobs with Metaballs Exposed

To add more interactions between the wax in our lava lamp, we added a wax pool at the bottom of the lava lamp. We experimented with different ways of representing the wax pool, but we got the best results from a half-hidden elliptical metaball defined by the equation:

\[ E = {0.5 \over {{x^2 \over b^2} + {y^2 \over a^2}}} \]
Blob Emerging From Wax Pool

Movements

After trying out various methods and functions for the movement of the wax blobs, we determined that sine and cosine functions closely replicated the flow of a real lava lamp. We found that the blob movement looked most realistic when each blobs' x position was controlled by cosine as a function of time scaled by a multiplier and a limited range and each blobs’ y position was controlled in the same manner but with sine instead of cosine. We spent a lot of time experimenting with different multipliers and ranges to make the flow look as realistic as possible.

In order to generate more realistic acceleration and deceleration of the blobs, we took into account differences in their velocity based on temperature and blob depth. The wax blobs should move faster as they travel closer to the bottom of the lava lamp, where the temperature is higher, and slower as they travel progressively towards the top, where the temperature is lower. We implemented this by calculating the distance between each blob and the bottom of the container and used this distance to scale our sine and cosine functions appropriately. This gave us more accurate movement.

Additionally, we decided to make our simulation move faster than an actual lava lamp would in real time since we found the faster pace to be more visually compelling. However, for the sake of realism we also implemented a slow mode which more closely replicates the true speed of a lava lamp.

Temperature effects

To make the simulation more realistic, we researched the temperature changes across different depths of a lava lamp. Considering the three different types of heat transfer within the lava lamp (convection, advection, and conduction), temperature and pressure determine the velocity and volume of a blob and is dependent on a blob’s distance from the wax pool.

There are several effects we created to simulate the influence of temperature on the lava lamp, including the temperature gradient of the background liquid, the volume of the blobs, and their movement. To demonstrate the temperature change across different depths in the lava lamp, we created a background color gradient that becomes warmer and lighter as the temperature increases. We researched how temperature and hydrostatic pressure affect the density and size of the wax blobs and utilized some insights from the thermocline of a larger body fluid, such as the ocean. Based on Gyure and Janosi's paper, with trial and error, we found it most effective to scale the volumes and movements of the blobs using the following functions to represent the temperature and pressure change.

We used


\[ radius Scale Factor = {({1 \over log(height + c) -k} )^ {1/3} * l} \]

to simulate the impact of temperature and pressure, both of which are proportional to depth (and thus density). This determines the volume, which is proportional to the cubic of the radius. c, k, l are constants that can be adjusted based on the effects desired for our simulation. Height is inversely proportional to depth and is calculated by the y component of each fragment coordinate divided by the y component of the resolution of the screen.

We further adjusted the positions of the blobs at each time step by their respective depths to improve on the sine and cosine base functions we used on movements for more realistic simulation. We used


\[ p1 = {p0 + ({l \over log(height + c) -k} )^ 2} \]

to simulate the impact of volume, pressure, and buoyant force that is proportional to volume (and thus velocity and density). While the blobs are within the wax pool, we set their initial speeds to be close to 0. Taking v = u + at , the final velocity is thus proportional to acceleration at any given time step. Again, c, k, l are adjustable parameters and p0 is the base position at each time step after applying the sine and cosine function.

Same Wax Blob at Different Depths

Temperature Gradient Background

Shading

After conducting some research on how to add more realistic shading and color to our lava lamp, we were inspired by a shader which generated an interesting 2D shading effect using imaginary normals and an imaginary light source. In a similar fashion to this shader, we experimented with incorporating imaginary normals and an imaginary light source into our simulation to generate a 2D shaded effect for our lava lamp. We did so by smoothing the normals between the metaballs, creating a fake lighting position and direction, calculating max(dot(light_direction, normals), 0), and taking the square root of this to smooth out the lighting. This resulted in some cool 2D shaded effects which, as seen below, somewhat resemble the Lambertian/diffuse shading we learned in class.

2D shaded effect

Problems & Lessons

We encountered several challenges throughout this project. Initially, we wanted to use Navier Stokes equations for our simulation. After extensive research into this method and its visual effects, we felt it would not improve our simulation’s movements. Due to this, we pivoted to implementing separate features that would make our simulation more physically realistic, such as more realistic blobs shape, better movements, coloring, and shading.

When experimenting with the wax blobs’ movement, we originally tried Newton's polynomial interpolation and Hermite interpolation using points and derivatives of the functions, the graphs of which were provided in the paper. However, the polynomials we obtained from interpolation did not give us desirable outcomes. This was due to their high degrees and the difficulty to scale them for the frame used in Shadertoy. We then tried using logarithm functions adjusted by constants and found it sufficiently effective to mimic the behaviors of wax blobs in a real lava lamp.

Shadertoy was unexpectedly difficult and time-consuming to learn and work with, especially in the beginning. We started our program from scratch and found that there was little documentation and useful resources available online. Due to this, we spent a significant amount of time learning and experimenting with Shadertoy. Also, Shadertoy would occasionally go down for long periods of time (up to an entire day), which hindered our progress.

There were a couple features that we spent a lot of time trying to implement, but couldn’t incorporate into our program due to time constraints. Our current movement patterns are deterministic, so we wanted to add some randomness to make them less predictable. In one attempt, we tried using pseudo-random number generators to modify the uv coordinates, start locations, and movement parameters. These changes led to noisy wax blobs, strange movement patterns, and artifacts during merging/splitting.

Noisy Wax Blobs From Different Attempts

Another one of our reach goals was to implement collisions between wax blobs and foreign objects within the lava lamp. Our initial attempt was to adjust the positions of the blobs when they collide with an object. However, this led to clipping and teleportation issues that we couldn’t resolve. In a different implementation, after creating some objects and placing them into our simulation, we attempted to bounce them off the objects by changing the direction of their movement. However, the metaball blobs continued to pass through objects.

Blobs Clipping Into Box and Cylinder

We also created a separate shader where we could test out an implementation where the blobs move around each other, rather than simply passing through one another. In this shader, we had balls keep their y position when colliding while modifying the x position to move around other circles. This was somewhat tricky since it would sometimes cause the balls to jump between the sides of the circle it was going around to match its final position. To solve this, we found that we could calculate the start and end intersection positions and trace the ball along a constant shortest path. However this solution was difficult to incorporate into the lava lamp simulation due to the shapes of the blobs and the number of moving blobs.

Simplified circle model avoiding collision

Results

You can view and play with our main lava lamp here and our shaded lava lamp here. Try switching between different color combinations and speeds! Here is the link to our video.

Here are some pretty pictures from our shaders:


Temperature Gradient

Pink

Orange Sherbet Dreamscicle

Synthwave

Solar Eclipse

Shaded Blue

Shaded Bubblegum Pink

Shaded Rainbow

References

References:
- A 3D Lava Lamp Simulation
- Particle-Based Fluid-Fluid Interaction
- A Particle System Representation of Candle Wax.
- Fluids-2D
- Navier–Stokes equations
- Basics of a Lava Lamp convection
- What is a Thermocline?
- Heat Transfer in a Lava Lamp
- Basic ShaderToy Tutorials
- Metaball Analysis
- 2D Shader Reference

Computing platform:
- Personal Laptops

Software Resources
- ShaderToy

Contributions

Everyone contributed to the deliverables for the proposal, milestone, final presentation, and final write up. Everyone also attempted to implement collisions.

Jonathan created the basic lava lamp container, many of the color combinations/effects, the wax pool and blobs, and the “slow mode” option. He also tweaked and fine-tuned the blobs’ shapes, positions, and movement parameters.

Alyssa researched and experimented with metaball construction, implemented changes in blob speed dependent on temperature, and added a 2D shading effect to the wax blobs.

Jessica explored various ways of making the blob movement more realistic, experimented with blob collisions, and fine-tuned the blobs’ movement and position parameters. She also made the collisions shader.

Zoe researched the heat transfer across various depths of a lava lamp, implemented changes in blob size based on the combined effects of temperature and hydrostatic pressure, and adjusted the positions and movements based on buoyancy.

Thanks for reading our write up!