By day
By night
Basically
† the verb form is the only correct use of “math” all other forms are an abomination before man and God.
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
After workshop drinkies
and further networking
across the road
Agenda
This slide deck at:
tamapolis : Javi Agenjo's personal blog
TWGL: A Tiny WebGL Helper Library
OpenGL ES 2.0 for the browser
Programmable pipeline
Great power
Great responsilbility
Which means what exactly?
Canvas
Shader program (glsl)
Vertex shader
Fragment shader (pixels)
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
Simple vertex shader
Simple fragment shader
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);
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;
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!
We have such sites to show you
May seem long winded
Scales well
Plenty of utility libraries
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)
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;
}
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
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
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 );
}
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;
};
"Just" a renderer / rasteriser, but can be bent to our will
Thank you
Questions?