basics

regl is a library for writing WebGL programs.

what is webgl?

WebGL lets your access your computer's graphics processing unit (GPU) from a web browser.

how does WebGL work?

At its core, WebGL is an API for drawing triangles really fast. With the right set up, this can be used to create 3D scenes, fast and detailed animations or perform massive parallel computations.

Before getting too far into the details, let's start take a high level look at how WebGL works.

WebGL is programmed using shaders, which are programs written in GLSL that run on the GPU. There are two kinds of shaders:

Shaders receive information from 3 different types of variables:

Vertex shaders receive inputs from attributes and output varying data to fragment shaders. Fragment shaders take in the interpolated varying variables and output pixel colors.

getting set up

npm

The regl ecosystem is based around npm, a package manager for javascript. To use npm, you'll need to install node.js.

The distributions on the nodejs website come with nodejs and npm included.

You may also prefer to follow distribution-specific instructions for your platform.

Once you have node.js and npm installed, in a new project directory do:

npm install regl

The node.js module system gives you a function require() that you can use to load packages. For example, to load the regl package, in your code you can do:

var regl = require('regl')

Whenever you npm install some package, you can require() it by its name in your code.

To load other files in your project instead of packages, use a relative path beginning in './' or '../'. For example:

var len = require('./len.js')

will assign the exports of the local file len.js into the variable len.

The require() function returns whatever functionality a package saw fit to export. A package set exports by assigning to the variable module.exports. For example, in len.js we can export a function:

module.exports = function len (a, b, c) {
  return Math.sqrt(a*a+b*b+c*c)
}

You can export any kind of object, not only functions, but it's very common to export a function.

Each file in the node module system has its own module scope so you don't have to worry about local variable declarations with var leaking out.

browserify

Packages from npm come in many separate files and use the node.js module system to import and export dependencies.

To make the node.js module system work in the browser, use browserify to compile all your dependencies into a payload of javascript that you can deliver in a single script tag.

It's good to have a copy of the browserify around for building files for production. Install browserify by running:

sudo npm install -g browserify

This will give you a browserify command you can invoke starting from a file, such as main.js and will create a bundle of all the files necessary to run your project.

Start by writing code that requires regl and other libs in main.js and then you can run browserify to produce bundle.js:

browserify main.js > bundle.js

budo

In development, it's nice to have a tool that will recompile your code every time you make a change to a file. You can use budo to incrementally recompile your code like so:

budo main.js --open

This command will compile your code using browserify, set up a local http server with your code in a basic html scaffold and open a web browser.

Every time you change your code, you can reload the page. If you prefer budo to handle that for you, you can pass in --live:

budo main.js --open --live

and budo will reload the page whenever a file changes.

aside: ES6

This section is optional

ECMAScript version 6 (also known as ES6) is a new version of JavaScript which is currently being rolled out. It adds many nice features like template strings which make writing shader code much easier.

Modern browsers like Google Chrome and Firefox already support most of the new language features, but many older browsers like iOS Safari do not yet.

If you want to use ES6 features when you are writing your regl, it is a good idea to transpile your JavaScript down to ES5 so that users with legacy browsers can still see your creation.

A simple way to do this is with the es2020 browserify transform that implements a subset of ES6 features. To install it with npm type:

npm install es2020

And then to use the transform with browserify run:

browserify -t es2020 main.js > bundle.js

Or in budo:

budo main.js --open --live -- -t es2020

hello regl

drawing a color

Now that you have regl set up, let's jump in and create a simple application. For this first example, we're going to make a program that just clears the screen to a solid color. Copy and paste the following code into an example file and try running it:


// First we import regl and call the constructor
var regl = require('regl')()

// Then we hook a callback to draw the current frame
regl.frame(function () {
  // And in the frame loop we clear the screen color to magenta
  regl.clear({
    // This line determines the color of the screen.  It has 4 components:
    //  [red, green, blue, alpha]
    //
    // Each of these is a number between 0 and 1, where 0 = dark and 1 = light.
    // alpha is a special color controlling transparency.
    //
    color: [1, 0, 1, 1]
    //
    // Try changing these numbers in your program and see what happens!
  })
})

animation

regl.frame is a callback method that takes a function which is executed each frame


var regl = require('regl')()

regl.frame(function () {
  // Instead of magenta, we oscillate the color
  regl.clear({
    color: [0, 0.5 * (1.0 + Math.cos(Date.now() * 0.01)), 1, 1]
  })
})