Logo with initials

Under the hood: WebGL sketch

──── 4 mins
Last Updated: 9 October 2022

This is the daily log that I wrote back in, erm, 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.

Requirements

I’ve always felt weird about projects that encourage people to create and share works everyday. Projects like Codevember, Inktober or the all-so-toxic #100DaysOfCode. Any kind of peer pressure on carving time out of the weekend always felt uninclusive and unfair. That’s why I never participate on weekends even when I can.

Y U NO THREE.js ?

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 major features are actually a few rogue files buried in the /examples folder.
  2. The three.js way of thigs.” 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 online work in an ES2015/modern environment that doesn’t expect a stupid THREE global variable.
    • Actually implement it

In Regl, these are the steps:

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

Daily log

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 to the present

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

Acknowledgements

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

  • Mikola Lysenko, Eric Arnebäck and Jeremy Freeman, for creating 👑 Regl.
  • Matt Deslauriers and Hugh Kennedy for creating stack.gl, many helpful modules and for each module creating a standalone demo that still works.

As always, feel free to let me know if you have any questions.

753 words

Share