I’ve always been inspired by Shadertoy, so I thought I’d use that idea to make a few interactive backgrounds for my website. The concept is simple: render two triangles and create awesome images in the fragment shader. While Shadertoy has many inputs to query and buffers to draw to, I limited myself to the image resolution, mouse position, and time since the program started. Since I had no persistence or multiple passes, I went with some simple and fun effects.
If you look at the top of the page, there are several icons that you can click on to change the background. The first background is a vertical gradient that changes colors over time. You can move the mouse up and down to affect the interpolation between two gradients. I chose this to be the landing background, so nothing moves or is too distracting if you just want to browse the website. The second background is a metaball grid where you can move a separate metaball within the grid. I chose this because metaballs seem like a good precursor to learning raymarching, which is something I’ve been looking into lately. The final background is a fractal image where you can pan around with the mouse. Fractal patterns have always interested me, and there’s ton’s of examples on Shadertoy to reference.
I’m using the html canvas and WebGL to render each background. Currently, WebGL uses OpenGL ES 2.0, which provides some interesting limitations. The vertex shader for every effect simply passes the vertex coordinate along to the fragment shader. The rendering quad has points (-1, 1), (1, 1), (1, -1), and (-1, -1). Here’s the shader code:
All of the work is done in the fragment shader. There are 4 uniforms: backgroundAlpha, which is the alpha for fading the backgrounds in and out, globalTime, which is the time in seconds since the program started, resolution, which is the resolution in pixels of the canvas, and mouse, which is the pixel coordinates of the mouse.
The gradient shader fades between two different gradients over time. The gradients are the same ones I use for the site’s .favicon.
The metaball (or droplet) background is more complex. The metaball function checks the distance between the target position (metaball position) and the fragment position. Larger values will be returned the closer the fragment is to the target position. The values for each metaball in the scene are added together, then used to color the fragment. This is what causes the metaballs to blob together.
While researching fractals I learned of the Julia set, which is similar to the classic Mandelbrot set. To me, it’s more visually appealing, so I decided to use it as the basis for this effect. They are implemented in a nearly identical fashion - the only difference being that the Mandelbrot set calculates new coordinate values for every iteration, where the Julia set calculates one value that is used by every iteration.
I had fun creating these over the weekend. Of the three backgrounds, I like the fractal image the most, but I think the metaball background is the most fun. This was a good way to practice creative coding, and I think I’ll be able to use some of the ideas from this project in my future games.