Your browser doesn't support the features required by
impress.js, so you are presented with a simplified version of this
presentation.
For the best experience please use the latest Chrome, Safari
or Firefox browser.
Introduction to WebGL
Mobialia
- Since 2010
- Apps: Mobialia Chess, RBKube, Connect-4, Gas-Stations
Spain...
- Focused on Android, but we have some WebGL Apps
Founders:
- @albertoruibal (Galicia)
- @ibancg (The NetherLands)
http://www.mobialia.com
Why WebGL?
- Advanced Graphics in the browser
- Direct Access to the GPU: acceleration
- Javascript API
- Plugin-free
- Not only games: Zygote Body, 3D Maps...
The Standard
- Khronos Group
- Participating: Apple, Google, Mozilla, Opera...
- WebGL 1.0: March 2011
- Based on OpenGL ES 2.0
Browser Support
- Desktop browsers: Chrome, Firefox, Safari, Opera...
- Where are you Microsoft? (IEWebGL Plugin)
- Mobile Browsers: Firefox for Mobile (Nightly), Opera Mobile 12, Playbook...
- IOS? iAd webviews support WebGL
Security
- Direct Access to GPU Hardware
- Disabled by default in Safari
- Microsoft campaigns against WebGL :D
Getting a WebGL context
We need a canvas:
<canvas id="mycanvas"></canvas>
And then we get the GL context:
var canvas = document.getElementById("mycanvas");
var gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
Initializing
After getting a GL context we need to set some parameters:
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
// For transparency
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
Shaders
Programs in "GLSL ES"="ESSL" Shading language compiled into GPU microcode
- Vextex Shader: calculate vertex position and return it in gl_position
- Fragment Shader: calculate point color and return it in gl_FragColor
GLSL
Data types:
- Simple: float, double, bool, int, uint
- Vectors: vec2, vec3, vec
- Matrices: mat2, mat3, mat4
- For textures: sampler2D, samplerCube...
Modifiers (pass values):
- Attribute: JS-> Vertex Shaders (applied to individual vertices)
- Uniform: JS-> Shaders (frame)
- Varying: Vertex -> Fragment shaders
Simple vertex shader
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec2 vTextureCoord;
void main(void) {
gl_Position = uPMatrix * uMVMatrix *
vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
}
Simple fragment shader
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler,
vec2(vTextureCoord.s, vTextureCoord.t));
}
Uploading shaders
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(shader, source);
gl.compileShader(shader);
//...
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
Camera
Defined by: fov, near, far, position, target and upaxis
Represented by two matrices:
- Perspective Matrix (Frustrum): used to calculate perspective deformation
- Lookat Matrix: with position, target and upaxis
3D models
Defined by:
Four JS arrays, must be uploaded to GPU Vertex Buffer Objects (VBOs)
Drawing
1) Upload VBOs to GPU
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array(vertices), gl.STATIC_DRAW);
2) Draw on each frame:
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.drawElements(gl.TRIANGLES,
cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
Textures
texture = gl.createTexture();
texture.image = new Image();
On image load, upload the texture to GPU:
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,
gl.UNSIGNED_BYTE, texture.image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER,
gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, null);
Picking
Touch the screen and detect what object we are "touching" in the scene. Many methods
- Framebuffer with object colors
- Intersections with a ray: Ray Picking
WebGL engines
Their purpose is to provide a scene object model with
- Scene
- Object / Mesh
- Geometry
- Material
- Light
- ...
And a "Renderer" to draw the scene (also model load...)
WebGL Javascript Engines
The most used:
Utils:
Playing with Three.js
We can use the Inline code editor
I don't like Javascript
GWT is a Google technology that compiles Java into Javascript.
GWT WebGL libraries:
- gwtgl: only the bindings
- gwt-g3d: a more complete library (engine)
And some amazing demos with GWT+WebGL:
Our WebGL Games
We use gwtgl with our own 3D engine:
Publishing
We would like the same app visibility that in mobile appstores:
Chrome Web Store
- 5 USD fee
- Payments
- Licensing API for payments
App packaging: zip file with icon and manifest.json...