eπi +1 = 0
i² = j² = k² = ijk = -1
Moments of Happiness
“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
Web standard | |
Cross-device | |
Cross-platform | |
Combination of JavaScript API | |
and GLSL language |
Canvas based | |
GPU access from browser | |
Control via shader programs | |
Rasteriser - 2D and 3D graphics and more |
JavaScriptCreate Context/Canvas Compile GLSL Draw commands Data control GLSLShader program (compiled) Vertex shader transform vertices Fragment (pixel) shader transform pixels |
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
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;
}
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);
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);
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;
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!
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)
uniform
varying
attributes
Variables initialised
Out of bounds
WebGL is
• long winded
• complicated
BUT
• scales well
Still, APIs
• hide complexity
• simplifies
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
!important
!!important
¡important!
"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);
}
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) });
}
[email protected] | |
@CarlBateman | |
meetup.com/WebGL-Workshop-London | |
linkedin.com/in/dcbateman |