Intro to WebGL

Speaker: Carl Bateman

Are we
having
fun, yet?

Oh, God!
The pressure!

Slides, files, etc. at

webgl.io/algo

Carl Bateman


    

Carl Bateman


Workshop

Carl Bateman

Software Engineer
    

Carl Bateman

Computer Graphics (3D)
    

Carl Bateman

Maths

   eπi +1 = 0
   i² = j² = k² = ijk = -1


Fun!!!

Carl Bateman

Convergence

WebGL Thing
of the Month

WebGL Thing of the Month

Moments of Happiness

Chill the Lion

WebGL Thing of the Month

3D Face Reconstruction from a Single Image

Executive Summary

Executive Summary

What is WebGL?

WebGL - OpenGL ES 2.0 for the Web

“WebGL is a royalty-free, cross-platform API that brings OpenGL ES 2.0 to the web as a 3D drawing context within HTML, exposed as low-level Document Object Model interfaces.
“It uses the OpenGL shading language, GLSL ES, and can be cleanly combined with other web content that is layered on top or underneath the 3D content.
“It is ideally suited for dynamic 3D web applications in the JavaScript programming language, and will be fully integrated in leading web browsers.”

Khronos.org

What is WebGL?

Web standard
Cross-device
Cross-platform
Combination of JavaScript API
and GLSL language

What is WebGL?

Canvas based
GPU access from browser
Control via shader programs
Rasteriser - 2D and 3D graphics
and more

How WebGL Works

JavaScript

Create Context/Canvas

Compile GLSL

Draw commands

Data control

GLSL

Shader program (compiled)

Vertex shader

   transform vertices

Fragment (pixel) shader

   transform pixels

How WebGL Works

Vanilla WebGL

Your html page will look something this...


<html>
  <head>
    <!-- place holders for glsl code -->
    <script id="vertex" type="x-shader">
    </script> 
           
    <script id="fragment" type="x-shader">
    </script>
  </head>
           
  <body>
    <!-- canvas to hold webgl context -->
    <canvas id="glCanvas">
  </body>
</html>
          

"x-shader" arbitrary name, no special meaning
<script> convenient place to put GLSL source

Obvs, JavaScript can go in separate .js file
Shaders can be loaded with XHR

Shaders

Simple vertex shader



          


Simple fragment shader


 
          

JavaScript

Get a WebGL context


var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
for (var i = 0; i < names.length; ++i)  {
  try {
    gl = canvas.getContext(names[i]);
  }
  catch (e) { }
  if (gl) break;
}
          

Get source, build, compile and link the shader


var v = document.getElementById("vertex").firstChild.nodeValue;
var f = document.getElementById("fragment").firstChild.nodeValue;
           
var vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, v);
gl.compileShader(vs);
           
var fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fs, f);
gl.compileShader(fs);
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vs);
gl.attachShader(shaderProgram, fs);
gl.linkProgram(shaderProgram);
        

JavaScript

Error check then use the program


if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS))
  console.log(gl.getShaderInfoLog(vs));
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS))
  console.log(gl.getShaderInfoLog(fs));
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS))
  console.log(gl.getProgramInfoLog(shaderProgram));
           
gl.useProgram(shaderProgram);
          

JavaScript

Get data location


shaderProgram.uColor = gl.getUniformLocation(shaderProgram, "uColor");	
shaderProgram.aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition");	
gl.enableVertexAttribArray(shaderProgram. aVertexPosition);
          

Define Geometry


var vertices = new Float32Array([-0.5,  0.5, 
                                  0.5, -0.5,
                                 -0.5, -0.5]);
cubeVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
cubeVertexPositionBuffer.itemSize = 2;
cubeVertexPositionBuffer.numItems = vertices.length / cubeVertexPositionBuffer.itemSize;	
          

JavaScript

Send data to GPU and draw


gl.uniform4fv(shaderProgram.uColor, [0.0, 1.0, 0.0, 1.0]);
gl.vertexAttribPointer(shaderProgram.aVertexPosition,
                       cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.clearColor(0, 0.5, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, cubeVertexPositionBuffer.numItems);
          


Ta da!

WebGL

Is

Triangles

GLSL

Language features

C-like

Strongly typed

Optimised for geometry

Native support of vectors and matrices (no quaternions)

Built-in geometry functions e.g. cos, sin, dot, cross, reflect

Swizzle:

vec3 v1, v2;
v1[0] = v2.r;
v1.xyz = v2.rgb;
v1.zyx = v2.bbb;

Textures via sampler2D and texture2D (no 1D or 3D textures)

GLSL

Language features

Type modifiers

uniform

varying

attributes

Security

Variables initialised

Out of bounds

APIs

WebGL is

 • long winded

 • complicated


BUT

 • scales well


Still, APIs

 • hide complexity

 • simplifies

APIs

Oh so very many...

Two of the best known

Both have plenty of support, big communities and on-line editors of varying utility

Three.js is a bit... unstable

Finally,
the good stuff

Resources

Moar APIs

  • PEX
  • XTK (JS implementation of ITK / VTK)
  • SpiderGL
  • CopperLicht
  • A Tiny WebGL helper Library
  • etc.

On-line editors


Feature Support

Feature Support

Feature Support

Feature Support

Feature Support

JavaScript
humour
that is funny

THIS
is a joke

Some CSS Madness

!important

!!important

¡important!

JavaScript funny, ha ha

"Down to" "operator"


  var x = 10;
  while (x --> 0) // x goes to 0
  {
      console.log(x);
  }
               


 


  var x = 10;
  while ((x--) > 0) // x goes to 0
  {
      console.log(x);
  }
               

JavaScript funny, ha ha

O(n) sort in JavaScript


numbers = [8, 42, 38, 111, 2, 39, 48, 37, 90, 1]
                
for (var i = 0; i < numbers.length; i++) {
  setTimeout(function(i) { console.log(i) });
}             
            

Contact / Questions?

[email protected]
@CarlBateman
meetup.com/WebGL-Workshop-London
linkedin.com/in/dcbateman