Workshop

Practical Learnings of WebGL for
Make Benefit Glorious Internet of Web


Thursday, 22nd October 2015
Skills Matter | Code Node, 10 South Place, EC2M 2RB, London

Next: TBD

Carl Bateman

By day

  • Software Engineer (desktop)
  • C#, C++, VB, MySQL, .NET, Linq, blah, blah... blah...


By night

  • Software Engineer (still)
  • OpenGL, Unity, JavaScript, PHP, CSS, HTML and, of course, WebGL

Carl Bateman


  • WebGL Workshop Organiser
  • Khronos London Chapter Coordinator
  • Self-appointed WebGL Evangelist
    • Nerd
      • Zealot
        • Looney

Basically

  • I love to code
  • I love to graphic
  • I love to math
  • I love to web


the verb form is the only correct use of “math” all other forms are an abomination before man and God.

Carl Bateman

Thanks to...

Khronos.org

• For the pizza & beer
• With whom I am affiliated



Skills Matter (venue)

• With whom I am in no way affiliated



Pearson

• 45% discount "WebGL Programming Guide" eBook edition
• Check out the MeetUp page

WebGL Workshop



After workshop drinkies

and further networking

across the road

WebGL Workshop

Agenda

  • Who are Khronos?
  • What is WebGL?
  • Sites using WebGL
  • Uses
  • Demos
  • Code
  • APIs



This slide deck at:

webglworkshop.com/18

Khronos.org

Who are Khronos?

Khronos.org

Who are Khronos?

Khronos.org

Who are Khronos?

Khronos.org

Who are Khronos?

What is WebGL?

  • Canvas based
  • JavaScript API
  • Renders 2D and 3D graphics
  • Giving access to the GPU
  • Integrated into all web standards

Why WebGL?

Executive summary:

CPU bad - GPU bad!

Examples

Simple site decoration

WebGL Paris 2015

Pixel Shaders

tamapolis : Javi Agenjo's personal blog

TWGL: A Tiny WebGL Helper Library

WebGL Fundamentals


Decidely more ambitious site decoration

Hackery, Math & Design — Acko.net


OTT

Opus Live Wallpaper for Android


What the what?

WebGL Presentation Editor

What is WebGL (part 2)?

OpenGL ES 2.0 for the browser

Programmable pipeline

Great power

Great responsilbility

Which means what exactly?

Code time (nearly)

Canvas

Shader program (glsl)

Vertex shader

Fragment shader (pixels)

Code time

Your html page will look something this...


<html>
  <head>
    // 
         
        
        
  </head>
  <body onload="init()">
    
        
  </body>
</html>
          


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

Error check


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

JavaScript

Get data location


gl.useProgram(shaderProgram);
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!

More (basic) examples

With a bit more effort

Coloured cube

Feelin' lucky?

Models and glyphs

We have such sites to show you


May seem long winded

Scales well

Plenty of utility libraries

GLSL

Langauge features

C-like

Strongly typed

Optimised for geometry

Native support of vectors and matrices (but no quaternions)

Swizzle vec3 a; a.xyz = a.rgb; a.zyx = a.bbb;

Built-in functions like dot, cross, reflect

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

WebGL as markup

Currently two candidates (that I know of)

GLAM

CSS


body{
  margin: 0px;
  background-color: #000;
}
#sun {
  width-segments: 64;
  height-segments: 64;
  vertex-shader: url(../../shaders/sun.vs);
  fragment-shader: url(../../shaders/sun.fs);
  shader-uniforms: time f 0 
                   texture1 t url(../../images/cloud.png) 
                   texture2 t url(../../images/lavatile.jpg);
}
  
@-webkit-keyframes kfRotateY {
  from {
    -webkit-transform: rotateY(0deg);
  }  
  to {
    -webkit-transform: rotateY(360deg);
  }
}
.animRotateY {
  -webkit-animation-duration: 90s;
  -webkit-animation-name: kfRotateY;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-timing-function:linear;
}
            

GLAM

JavaScript


var theSun = null;
var startTime = Date.now();
window.addEventListener('load', function(){
  glam.ready();
  theSun = document.getElementById("sun");
  run();  
},
false);
function run() {
  requestAnimationFrame(run);
  if (theSun.material) {
    var now = Date.now();
    var elapsed = (now - startTime) / 1000;
     theSun.material.uniforms.time.value = elapsed;
  }
}
            

HTML



          
          
  

            

GLAM

Sunny side up

jQuery Three

Home sweet home

APIs

Oh so very many...

Two of the best known

  • THREE.js
  • Babylon.js

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

Three.js is a bit... unstable

Three.js


var camera, scene, renderer, mesh;
  
init();
animate();
  
function init() {
  camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
  camera.position.z = 400;
  
  scene = new THREE.Scene();
  
  var texture = THREE.ImageUtils.loadTexture( 'textures/crate.gif' );
  var geometry = new THREE.BoxGeometry( 200, 200, 200 );
  var material = new THREE.MeshBasicMaterial( { map: texture } );
  
  mesh = new THREE.Mesh( geometry, material );
  scene.add( mesh );
  
  renderer = new THREE.WebGLRenderer();
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  document.body.appendChild( renderer.domElement );
}
  
function animate() {
  requestAnimationFrame( animate );
  mesh.rotation.x += 0.005;
  mesh.rotation.y += 0.01;
  renderer.render( scene, camera );
}
        

Babylon.js


var createScene = function () {
  var scene = new BABYLON.Scene(engine);
  scene.clearColor = new BABYLON.Color3(0,0,0.2);
  var camera = new BABYLON.ArcRotateCamera("Camera", 1.0, 1.0, 12, BABYLON.Vector3.Zero(), scene);
  camera.attachControl(canvas, false);
  var light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);
  light.groundColor = new BABYLON.Color3(0.5, 0, 0.5);
  var box = BABYLON.Mesh.CreateBox("mesh", 3, scene);
  box.showBoundingBox = true;
  var material = new BABYLON.StandardMaterial("std", scene);
  material.diffuseColor = new BABYLON.Color3(0.5, 0, 0.5);
  box.material = material;
  return scene;
};
        

Moar APIs

  • Pixi.js (2D)
  • PlayCanvas
  • Away3D (Flash replacement)
  • XTK (JS implementation of ITK / VTK)
  • GLGE
  • SpiderGL
  • CopperCube
  • TWGL: A Tiny WebGL helper Library

Online Editors (Scene Graph)

  • PlayCanvas
  • Clara.io
  • Goo / GooCreate
  • WebGLStudio.js
  • Three.js
  • Babylon.js
  • Unity !?! (via export)
  • 3D tin

Online Editors (Shader)

  • http://www.kickjs.org/example/shader_editor/shader_editor.html
  • http://shdr.bkcore.com/
  • http://pixelshaders.com/editor/

Techniques

"Just" a renderer / rasteriser, but can be bent to our will

Applications

Support

get.WebGL.org

CanIuse.com/#search=WebGL

BrowserLeaks.com/WebGL

WebGLreport.com

WebGLstats.com

Resources

  • Yobi 3D (google for models)
  • SketchFab (model hosting and embedding)

The end

Thank you

Questions?