( 2016-2017 )  

Shader programs are executed by the GPU to perform highly parallel computations much more efficiently than possible with a CPU. Currently, WebGL allows GPU programs to read and write to images called “textures”. By encoding input and output data as RGBA pixels in texture images, it’s possible to use the GPU to perform arbitrary calculations in a web browser; this technique is sometimes called “General-Purpose GPU” (GPGPU), since the GPU is not used exclusively for graphics rendering. The following are a collection of programs I’ve written (mostly physics simulations), where math or other logic is processed in WebGL fragment shader programs in order to solve a large system efficiently.

This simulation solves the Navier-Stokes equations for incompressible fluids in a GPU fragment shader. Click and drag to apply forces to the fluid and add color, making it look somewhat like marbled paper. I implemented no-slip boundary conditions at the borders to keep the fluid contained within the bounds of the screen. To increase performance, I solved for the velocity vector field of the fluid at a lower resolution than I used to compute the visualization of fluid flow; I used bilinear interpolation to smooth out artifacts caused by this speedup. I also added 160,000 Lagrangian particles on top of the simulation - these particles are rendered using threejs, but their positions are computed on the GPU following methods described in Real-time ink simulation using a grid-particle method. Live demo here, code on Github.

This simulation solves the Navier-Stokes equations for incompressible fluid flow past an obstacle in a GPU fragment shader. It exhibits a phenomenon called vortex shedding, where vortices of alternating spin spontaneously emerge behind the obstacle. Click and drag to interact with the fluid in realtime. To increase performance, I solved for the velocity vector field of the fluid at a lower resolution than I used to compute the distribution of material moving through the fluid (shown in black and white). The Navier Stokes solver was adapted to WebGL from the article Fast Fluid Dynamics Simulation on the GPU. Live demo here, code on Github.

This is a simulation of a Gray-Scott reaction-diffusion system, running in a GPU shader. The system describes the behavior of two chemicals that mix and react with each other while diffusing through a 2D environment. The parameters for this model are F = 0.0545 and K = 0.062; with these parameters the system forms a mitosis-like pattern, where small cells divide and spread across space. Reaction diffusion patterns are interesting, but they can be difficult to control in meaningful ways for design purposes. In this project I added an underlying vector field that controls the orientation of diffusion across the system to produce directed, global patterns. Click on the screen to change the location of the sinks in the vector field. The math used to created oriented diffusion is discussed in the papers Display of Vector Fields Using a Reaction-Diffusion Model and Reaction-Diffusion Textures. Code on Github, demo available here.

A physics simulation of a mesh of masses attached to their four nearest neighbors with springs and dampers, all running in a GPU fragment shader with WebGL. In the simulation, each pixel on the screen is a mass in a 2D mesh. At each frame, the masses exert forces on each other and the resulting acceleration, velocity, and position of each mass is solved via Euler integration. The vertical displacement of the masses is indicated by the color of the pixel, blue pixels have positive vertical displacement, white have negative displacement, and pink is zero displacement. Scrolling over with your mouse applies an upward force to the nearby pixels. The physics is equivalent to a discrete, damped 2D wave equation or cloth simulation. Masses at the edges of the screen are fixed with zero displacement, making the simulation behave like a giant trampoline. Live demo here, code on Github.

A simple implementation of Conway’s Game of Life in a fragment shader. Use your mouse to add new living cells into the world. Code on Github, demo available here.