WebGL shader renderer for awesome animations

Nowadays, WebGL is a popular technology for developing engaging frontend web apps. I see more and more global companies like Stripe use WebGL to create awesome animations on their landing pages.

Stripe landing with WebGL background

This background mesh gradient is smoothly animated ☝️ (visit https://stripe.com/ to see it in action)

Below you can see realtime rendered by your device running WebGL programs 👇🏻

💡
Click on animation to enter Full Screen mode if your device supports it

Tubes with textures

Glass

Matrix with the flag of Ukraine

Metaball

Helix

How to create such animations?

Learning WebGL might seem an overwhelming because of new terminology, new approach to render things on a screen and a setup of WebGL is not straightforward comparing to usual 2D canvas context.

Here are base steps you may do:

  • Go through WebGL tutorial on MDN
  • Google about "introduction to WebGL shaders"
  • Install IDE extensions to to highlight and explain GLSL language (e.g. for VS Code, I recommend this one - slevesque.shader)
  • Search for YouTube videos
  • Feel overwhelmed 😩, rest for a while 😌
  • Repeat steps multiple times ♻️
  • Finally, produce first meaningful WebGL programs ✅

Or can it be simpler?

Yes! Focus only on WebGL fragment shaders without caring about vertex shaders, WebGL API and other stuff . All you need is to understand fragment shaders (written in a language called glsl).

Here are my favourite sources I recommend to go through:

To simplify things for you, I have created an overshader - a simple NPM package to render WebGL shaders without complex details behind the scene.

Animations above - which are called WebGL programs - are created with overshader.

To get started, just checkout README.md of my package - https://github.com/overshom/overshader

Explore source code (shaders) of examples - https://overshom.github.io/overshader/github-demo/index.html

README.md on GitHub describes how you can easily launch your own WebGL shader program which is as simple as:

import { runWebglProgram } from 'overshader';

runWebglProgram({
    canvasContainer: '.responsive-canvas-container',
});
  • canvasContainer - simple div, inside which canvas with WebGL program will be inserted
  • by default, my package renders a simple program so you can easily see it is working

Feel free to fork or just clone my repo and launch it locally - it is fast and convenient to work with inside IDE like VS Code.

Benefits of using WebGL

  • Leverage GPU processor of your device to run animations at impressive 60Hz or even 120Hz (device dependent, of course) (usual Canvas 2D context will not provide such a fast rendering for any complex animation)
  • Control every pixel rendered on a screen - create very complex and mind blowing rendering scenes
  • Improve your math skills (a shader program is full of vectors, matrices, dot products, sin and cos and lots of other stuff)

Debug WebGL

Short answer - there is no actual debug tools in browser yet for WebGL like console.log or Chrome Dev Inspector, no breakpoints, what we can do instead is to use canvas rendered pixels itself as our inspector.

For that purposes, I have written a simple fragment shader debugger - it renders red, green and blue channels for vec3 vectors and has vertical lines which indicate value of every vector component ( r,g,b or x,y,z if you like)

This way ☝️ you can render your values (vectors) and see their value from a range (-∞, -2, -1, 0, 1, 2, ∞+)

How it works:

  • Very first vertical line on the left - means value is -2
  • Second vertical line - means value is -1
  • Center vertical line - means value is zero
  • Next line - means value is 1
  • And the last line - the very right one - means value is 2

Simpler debugging

The simplest debug you can make is just to output a high-contrast color on a screen, like red:

gl_FragColor = vec4(1., .0, .0, 1.);

Get inspired by Shadertoy

To uncover awesome approaches of using fragment shaders - visit Shadertoy - a playground and collection of interactive fragment shaders.

Shadertoy homepage

NOTE: fragment shaders are not efficient to render everything.

The best rendering performance (FPS) for complex scenes will be a combination of dozens different fragment and vertex shaders applied to different rendering objects, scenes, with properly optimized 3D models (exported from other tools like Blender) and other stuff.

Once you are good with fragment shaders, I recommend you to go further and learn libraries like THREE.Js

I hope now you will find an opportunity to integrate WebGL shaders into your apps and make the web even more beautiful and interactive place.