4. Introduzione a WebGL
OPENGL ES
Open Graphics Library for Embedded Systems
Versioni Fixed Function
hardware
OpenGL API
1.0 (OpenGL 1.3+ specs)
accelerazione hardware base, fixedpoint data type
1.1 (OpenGL 1.5+ specs) OpenGL ES
supporto multitexture, auto mipmap, vertex buffer objects... API
2.X (OpenGL 2.0 specs)
Fixedpipeline sostituita da shaders, non compatibile con ES 1.X
Programmable
hardware
7. Introduzione a WebGL
GLSL
Graphics Library Shading Language
Shader = set di istruzioni per effettuare effetti di rendering su hardware grafico
Vertex Shader Geometry Shader Pixel Shader
manipolazione di per combinare elabora I pixel per applicare
vertici e della insiemi di vertici e generare texture e effetti (bump
loro posizione nuove primitive Mapping, nebbia, ecc.)
E' un programma che viene eseguito su ogni vertice/pixel direttamente
all'interno della scheda video utilizzando dei processori appositamente dedicati
a questo scopo
8. Introduzione a WebGL
GLSL
Parole chiave:
Uniform → variabile globale accessibile in lettura anche fuori dallo shader
Program → nome dato a una coppia vertexfragment shaders
Attribute → parametro in input passato a un vertex shader dall'applicazione
Varying → informazione passata dal vertex al fragment shader
10. Introduzione a WebGL
CANVAS
E' un componente del DOM (Document Object Model) di un
documento HTML5
Introdotto inizialmente da Apple per WebKit, poi adottato anche
da Gecko e Opera
Rendering di contenuti 2D e bitmap all'interno di un'
area della pagina opportunamente definita
<html>
<body>
...
<canvas id=”myCanvas” width=”500” height=”500”>
Il tuo browser non supporta i canvas... :(
</canvas>
...
</body>
11. Introduzione a WebGL
CANVAS
E' possibile, attraverso JavaScript, accedere a un canvas e
disegnare dinamicamente attraverso le funzioni messe a
disposizione (rif. esempi_lezione/example_canvas)
HTML
<html>
<body>
...
<canvas id=”myCanvas” width=”500” height=”500”>
Il tuo browser non supporta i canvas... :(
</canvas>
...
</body>
var myCanvas = document.getElementById('myCanvas');
var context = myCanvas.getContext('2d');
context.fillStyle=”rgb(255,0,0”);
context.fillRect(50,50,80,80);
JS
12. Introduzione a WebGL
WEBGL
Standard sviluppato da Khronos Group
WebGL Working Group – Apple, Mozilla, Google, Opera
Features
Nuovo rendering context per canvas → WebGLRenderingContext
Gestione della memoria automatica, attraverso Javascript
Implementazione nativa, non richiede plugin esterni
Accelerazione hw 3D nel browser
Comodo per prototipazione
Svantaggi
Richiede la conoscenza di OpenGL e GLSL
Anche un'applicazione semplice richiede (come vedremo) parecchio codice
Standard giovane, soggetto a cambiamenti
Instabilità
13. Introduzione a WebGL
WEBGL
Timeline
2006 Primi prototipi (Canvas 3D, Mozilla Foundation)
2007 Implementazione inbrowser (Mozilla, Opera)
2009 WebGL Working Group (Khronos + Mozilla)
Compatibilità
Browser compatibili (per ora solo versioni di sviluppo):
...e M
Mozilla Firefox (Minefield)
icros
Google Chromium
Apple Safari oft??
Opera ?
14. Introduzione a WebGL
Supporto al momento non previsto :(
Alternativa basata su DirectX?
Da tenere d'occhio:
Google ANGLE (Almost Native Graphics Layer Engine)
http://code.google.com/p/angleproject
“translate OpenGL ES 2.0 API to DirectX 9 API calls”
15. Introduzione a WebGL
HELLO WEBGL
Per utilizzare la tecnologia WebGL dobbiamo:
(rif. esempi_lezione/lesson00)
1. definire il canvas su cui verrà effettuato il rendering all'interno
del documento HTML
<html>
<body>
...
<canvas id=”myCanvas” width=”500” height=”500”>
Il tuo browser non supporta i canvas... :(
</canvas>
...
</body>
nome del canvas dimensione del Drawing Buffer
16. Introduzione a WebGL
HELLO WEBGL
2a. creiamo uno script JS che inizializzi il context WebGL,
modificando la pagina html...
<html>
<head>
<script src=”glUtils.js”></script>
All'apertura della pagina, viene
</head>
eseguita la funzione
<body onload=”initWebGL()”>
initWebGL()
...
<canvas id=”myCanvas” width=”500” height=”500”>
Il tuo browser non supporta i canvas... :(
</canvas>
...
</body>
17. 2b. ...e creando il file glUtils.js
recupero il canvas
dal DOM
function initWebGL() {
var canvas = document.getElementById(“myCanvas”);
creo un nuovo
rendering context.
try {
Contestualmente sarà
gl = canvas.getContext(“experimental-webgl”); creato anche un drawing
gl.viewportWidth = canvas.width; buffer delle dimensioni
gl.viewportHeight = canvas.height; specificate nel canvas
}
catch(e) {}
if(!gl) {
alert(“EPIC FAIL! Could not init WebGL!”);
}
}
18. Introduzione a WebGL
DRAWING BUFFER
Per default, è costituito da:
Color Buffer RGBA (8 bit per componente)
Depth Buffer a (almeno) 16 bit
Al momento dell'inizializzazione, è possibile definire un oggetto di tipo
WebGLContextAttributes e scegliere delle impostazioni custom:
Parametro Effetto
alpha abilita/disabilita l'alpha buffer [default: true]
depth abilita/disabilita il depth buffer [default: true]
stencil abilita/disabilita il color buffer [default: true]
antialias se abilitato, il drawing buffer effettuerà antialiasing
[default: true]
se abilitato, si suppone che i colori siano già comprensivi
premultipliedAlpha del canale alpha [default: true]
19. Introduzione a WebGL
ESEMPIO BUFFER CUSTOM
function initWebGL() {
var canvas = document.getElementById(“myCanvas”);
try {
gl = canvas.getContext(“experimental-webgl”,
{ antialias: false, stencil: true } );
}
catch(e) {}
if(!gl) {
alert(“EPIC FAIL! Could not init WebGL!”);
}
}
20. Introduzione a WebGL
3. completiamo l'inizializzazione
function initWebGL() {
var canvas = document.getElementById(“myCanvas”);
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
gl.clearColor(1.0,0.6,0.0,1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT,gl.DEPTH_BUFFER_BIT);
}
catch(e) {}
if(!gl) {
alert(“EPIC FAIL! Could not init WebGL!”);
}
}
22. Introduzione a WebGL
SYLVESTER
(http://sylvester.jcoglan.com/)
Le API di JavaScript nativamente non danno supporto per
l'algebra matriciale
Sylvester è una libreria per operazioni con vettori/matrici
Vantaggi:
– operazioni geometriche
– pulizia del nostro codice
Useremo questa libreria nei prossimi esempi per gestire model
view e projection matrix!
23. Introduzione a WebGL
WEBGL DRAWING
Proviamo a disegnare sul buffer, ad esempio un triangolo e un quadrato
(rif. esempi_lezione/lesson01)
L'inizializzazione di WebGL è la solita, con qualche novità:
function webGLStart()
{
var canvas =
inizializzo
document.getElementById("lesson01-canvas"); buffers e shaders
initGL(canvas);
initBuffers();
initShaders();
gl.clearColor(1.0,0.6,0.0,1.0);
ridisegno la scena
gl.clearDepth(1.0);
ogni 15 msec
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
setInterval(drawScene, 15);
}
24. Introduzione a WebGL
initBuffers()
Ci servono due buffer, che conterranno i vertici rispettivamente del
triangolo...
// buffer per i vertici
var triangleVertexPositionBuffer;
var squareVertexPositionBuffer;
function initBuffers() implementazione di
{
triangleVertexPositionBuffer = gl.createBuffer();
array di vertici
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); per WebGL
var vertices = [
0.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertices), gl.STATIC_DRAW);
triangleVertexPositionBuffer.itemSize = 3;
triangleVertexPositionBuffer.numItems = 3;
// continua...
26. Introduzione a WebGL
SHADERS
In WebGL gli shaders sono la componente fondamentale, nel nostro esempio
definiamo un vertex shader che agirà su tutti i vertici dei due buffer definiti
prima (traslandoli), e un fragment shader che colorerà ogni pixel di rosso
<script id="shader-fs" type="x-shader/x-fragment">
void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
Nota: gli shader
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition; sono scritti
all'interno della
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix; pagina html
void main(void) {
gl_Position =
uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
}
</script>
27. Introduzione a WebGL
initShaders()
var shaderProgram;
function initShaders()
{ 1. si recupera il codice degli shader
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
dalla pagina HTML
shaderProgram = gl.createProgram(); 2. si crea un program (vs + fs) che
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader); sarà compilato ed eseguito nella
gl.linkProgram(shaderProgram); scheda video
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Errore nell'init degli shaders");
}
gl.useProgram(shaderProgram); 3. recupero i riferimenti ad
attributes e uniforms dichiarati nel
shaderProgram.vertexPositionAttribute =
gl.getAttribLocation(shaderProgram, "aVertexPosition");
codice degli shader
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.pMatrixUniform =
gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform =
gl.getUniformLocation(shaderProgram, "uMVMatrix");
}
28. Introduzione a WebGL
drawScene()
function drawScene()
{ funzioni non direttamente
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); implementate in WebGL
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0); Realizzate con Sylvester, vedi
glutils.js e helper.js per
loadIdentity(); approfondire
mvTranslate([-1.5, 0.0, -7.0]);
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
setMatrixUniforms();
I vertex buffer sono passati al
gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems); program, che cambia il colore
mvTranslate([3.0, 0.0, 0.0]);
e la posizione. Infine viene
effettuata la scrittura sul
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); frame buffer
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);
}
29. Introduzione a WebGL
Ecco il risultato dei nostri sforzi!
Per prendere “confidenza” con il codice,
per esercizio si può provare a:
- cambiare il colore dello sfondo
- cambiare colore del quadrato/triangolo
- cambiare posizione ai vertici
- animare la scena: ad ogni draw
aggiornare la matrice di trasformazione
per fare muovere gli oggetti
Come detto, una scena semplice come
questa (no texture, no illuminazione, no
animazione, ecc.) richiede una quantità
di codice notevole!
Alternative?
30. Introduzione a WebGL
LIBRERIE BASATE SU WEBGL
Pur essendo le specifiche di WebGL molto recenti, sono nate rapidamente
delle librerie JS che si basano su questa tecnologia
Lo scopo generale è quello di facilitare l'utilizzo di WebGL, mascherandone la
natura di basso livello ove possibile, per dedicarsi alla creazione di contenuti
Tra i framework più famosi:
GLGE
SceneJS
EnergizeGL
Copperlicht
SpiderGL
WebGLU
31. Introduzione a WebGL
GLGE: “WebGL for the lazy”
http://www.glge.org
Features:
Keyframe animation
Normal mapping
Animated materials
Skeletal animation
Collada format support
Parallax Mapping
Text rendering
Fog
Planned additions:
Environment mapping
Reflections/Refractions
Collada Animations
Physics
LOD
33. Introduzione a WebGL
GLGE: ESEMPIO
Peculiarità:
la scena viene caricata da un file xml
possibilità di ruotare la camera con il mouse
possibilità di muoversi WASD (FPS like)
i modelli caricati sono file COLLADA
...e se guardiamo index.html, dove si trova lo script del “core”, possiamo
vedere come il codice non sia esageratamente complicato!
Però:
documentazione ancora carente, bisogna affidarsi alle demo
nessun tutorial per iniziare a imparare dalle basi
34. Introduzione a WebGL
SceneJS
http://scenejs.org
Definisce la struttura 3D come un scene graph
Efficiente
genera shader ottimizzati automaticamente
effettua swap delle risorse da/a memoria video
management dei buffer WebGL lazy
Caricamento asincrono di modelli
Frustum Culling
Level of Detail
Generazione procedurale di oggetti
Blog con tutorials
http://learningscenejs.wordpress.com/
Playground per le demo
35. Introduzione a WebGL
SceneJS: sintassi
rif. esempi_lezione/example_scenejs
Tutto il codice di inizializzazione della scena è nel file hello_teapot.js
Di particolare interesse è l'approccio JavaScript-like con cui viene descritto il scene
graph della scena:
var exampleScene = SceneJS.scene({
canvasId: "theCanvas",
loggingElementId: "theLoggingDiv" },
attributi
SceneJS.lookAt({
nodi
eye : { x: 0.0, y: 10.0, z: -15 },
look : { y:1.0 },
up : { y: 1.0 }
},
//continua...
36. Introduzione a WebGL
EnergizeGL
http://energize.cc
Ispirato a Processing (libreria di visualizzazione)
In stato più embrionale rispetto ad altri framework
Da segnalare l'editor
online, che trovate
puntanto il vostro
browser su
http://energize.cc/app/
38. Introduzione a WebGL
SpiderGL
http://www.spidergl.org/
Framework sviluppato dal Visual Computing Lab (Istituto di Scienza e
Tecnologie dell'Informazione - CNR di Pisa)
Sezione demo notevole come qualità, ottimo biglietto da visita per WebGL
39. Introduzione a WebGL
WebGLU
http://github.com/OneGeek/WebGLU
Separazione netta tra fase di definizione degli elementi da renderizzare e
rendering vero e proprio
Può caricare files .frag/.vert/.vp/.fp automaticamente
Implementa un parser obj per caricare modelli
Animazioni procedurali
GameGLU library (key binding)
40. Introduzione a WebGL
PER SAPERNE DI PIU'
Info WebGL by Khronos (specifiche, wiki, ecc.)
http://www.khronos.org/webgl/
Il portale di riferimento sul mondo WebGL
http://learningwebgl.com
WebGL è una tecnologia giovane e in evoluzione!
fonte: delicious.com