Logo with initials

Under the hood: WebGL sketch

──── 4 mins#Code, #WebGL

This is the daily log that I wrote back in, erm, let’s say some years ago, when I tried doing Codevember. It’s how the 3D WebGL graphics currently on the homepage came to be. I’m using Regl 👑, as mentioned in my Tech Stack Article.

The original sketch is still available on this link:

This wouldn’t have been possible without the open-source contributions of the following people:

  • Mikola, Erkaman and Freeman lab, for creating Regl 👑
  • Matt Deslauriers and Hugh Kennedy for creating stack.gl and a lot of helpful modules and for each module creating a standalone demo that still works.


I gave Codevember a try in 2016. I had an absolutely horrible experience when trying to create quick sketches with Three.js. I was not alone in those frustrations. Here they are:

  1. The Examples folder, a lot of what I’d consider major features are actually a few rogue files buried in the examples folder. In my case I needed to load a very simple Collada model.
  2. “The three.js way.” Every time I wanted to play with a new concept (e.g: instancing), I had to:
    • Understand the concept
    • Rummage through the depths of the Internet to look at how to implement that undocumented feature in Three
    • Make the example code that I found work with the current version of Three in an ES2015/modern environment that doesn’t expect a THREE global variable.
    • Actually implement it

In Regl, these are the steps:

  • Understand the concept
  • cmd/ctrl+f in the docs
  • Implement

Day 1: Setup and simple torus 🛠️

Started out by setting up all the workflow. I’m not too fond of the default camera, so I leveraged orbit-controls and perspective-camera instead. The Regl tutorials and examples have been very useful too.

The workflow is now only Browserify and Glslify. I think I found a good trade-off between convenience (no Webpack involved!) and speed of iteration.

Day 2: Multiple tori and Glslify 🙈

Figured out how to write reusable GLSL snippets. It usually works fine using a Babel plugin, but for some reason I couldn’t get it to function today. But given that I’m in a Browserify environment, I can directly use Glslify.

Created several tori (that’s the plural form of “torus”) with different arc lengths.

Day 3: Rotated tori 📐

Today I tried to rotate each torus in an intuitive way. Rotations in x, y, and z are a lot easier for me to wrap my head around/visualise compared to the traditional yaw, pitch, roll. This is no airplane.

After trying out a few matrix-based solutions I’ve come up with an approach in the vertex shader which doesn’t look as boilerplate-y as the other ones.

Day 4: Post-processing 🖼️

Implemented post-processing effects. It is done by drawing the scene to a frame buffer and manipulating it.

I’ve done a fair bit of fighting with one of the FBO examples. The version on the website and on GitHub look different, the code didn’t run, but it all worked out in the end.

Day 5: Polish 💅

Played around with Matt Deslaurier’s GLSL hash blur module, and wanted to add toon shading with a slightly grainy vignette around it. Then, one of those “generative art happy accident” occurred and resulted it what you’re currently seeing, so I’m going to leave it as it is!

Day 6: Toon shading 😈

So, I got toon shading to work based on a combination of things seen here and there, but mainly from Nathan Gordon’s Zelda series.

Day 7: Clean-up! 🧹

My next step was going to be about adding an outline shader to the tori, but everything in the code started to a bit too tightly coupled and I’d rather spend half an hour and waste “a day” now, than waste three days later down the line, it’s boring but useful!

Back in the present

I’m happy with how this turned out. Migrating the code from the original repository was a smooth lift-and-shift process. This shows the strength of Regl and the stack.gl ecosystem, as it’s not always easy to reuse code that dates back many years.

As always, feel free to let me know if you’re curious about a specific part.