Workshop

WebGL 2.0

Speaker: Carl Bateman


Tuesday, 16th May 2017
Skills Matter | Code Node, 10 South Place, EC2M 2RB, London

Carl Bateman

Software Engineer
    

Carl Bateman

Computer Graphics (3D)
    

Carl Bateman

Maths

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


Fun!!!

Carl Bateman

Software Engineer

Agenda

  1. Khronos
  2. WebGL (1.0)
  3. WebGL 2.0
  4. The future
  5. Spector.js

Khronos

Khronos.org

Khronos.org

Khronos.org

Khronos.org

WebGL

WebGL

WebGL

WebGL

WebGL

WebGL is 3D*
  *pretty much

3D is models

Models are triangles

How WebGL Works

JavaScript

   Create Context/Canvas

   Compile shaders

   Data control

   Draw commands


GLSL

   Shader program

   Vertex shader

      transform vertices

   Fragment (pixel) shader

      transform pixels

How WebGL Works

Setup
web page

WebGL

Your html page will look something this...


<html>
  <head>
    <!-- place holders for glsl code -- coming soon -->
    <script id="vertex" type="x-shader/x-vertex">
    </script> 
             
    <script id="fragment" type="x-shader/x-fragment">
    </script>
             
    <script type="text/javascript">
    </script>
  </head>
  <body>
    <canvas id="glCanvas"></canvas>
  </body>
</html>
            

Obvs, JavaScript can go in separate .js file

Shaders can be loaded with XHR

Shaders

Shaders

Simple vertex shader

attribute vec2 aVertex;
attribute vec3 aColour;
varying vec3 vColour;
             
void main() {
  vColour = aColour;
  gl_Position = vec4(aVertex, 0.0, 1.0);
} 
            
Simple fragment shader

precision mediump float;
varying vec3 vColour;
             
void main() {
  gl_FragColor = vec4(vColour, 1.0);
} 
            

Get
context

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;
}
            

Setup
GLSL program

JavaScript

Compile, attach and link shader programs


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);
               
programInfo.id = gl.createProgram();
gl.attachShader(programInfo.id, vs);
gl.attachShader(programInfo.id, fs);
gl.linkProgram(programInfo.id);
            

Error check

JavaScript

Error check and use

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(program, gl.LINK_STATUS)) 
  console.log(gl.getProgramInfoLog(program));
                
gl.useProgram(shaderProgram);
            

Set up
data

JavaScript

Get data location


programInfo.aVertex = gl.getAttribLocation(programInfo.id, "aVertex");
programInfo.aColour = gl.getAttribLocation(programInfo.id, "aColour");
            

Define shape data


var vertices = new Float32Array([ 0.5,  0.5,
                                 -0.5,  0.5,
                                 -0.5, -0.5]);
var colours = new Float32Array([0, 0, 1,
                                1, 0, 0,
                                0, 1, 0]);
            

bufferInfo.id = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.id);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
gl.vertexAttribPointer(programInfo.aVertex, bufferInfo.itemSize, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(programInfo.aVertex);
            

And finally...

How WebGL Works

Send "clear" and "draw" instructions


gl.clearColor(0.8, 0.8, 1.0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, bufferInfo.numItems);
          

WebGL 2.0

WebGL 1.0 & 2.0
code differences

The future

Spector.js