WebGL: 3D real time e OpenGL su HTML5

22 novembre 2010

L’idea di portare il 3D in tempo reale all’interno di una pagina Web non è nuova, anzi, fin dagli esordi del www abbiamo assistito ad un susseguirsi di implementazioni pionieristiche volte a perseguire proprio questo obiettivo: applet Java, VRML, la prima versione di O3D e molte altre.

Tra queste tecnologie le uniche in grado di superare lo stato sperimentale e di trovare collocazione all’interno di applicazioni di largo consumo sono state Flash e alcune librerie JavaScript molto elaborate. Anche in questi (rari) casi si è però quasi sempre trattato di apportare piccoli accorgimenti tridimensionali ad un’interfaccia progettata in modo strettamente bidimensionale.

Con l’arrivo delle nuove specifiche HTML5 ci sono però buone chance di approdare a breve ad uno standard condiviso per l’utilizzo di 3D realtime nel browser; una delle sub-specifiche previste all’interno di questa nuova versione del famoso linguaggio di markup è infatti specificatamente dedicata a questo compito e nasce dalla collaborazione dei principali player del settore come Apple, Google e Mozilla.

La tecnologia in questione si chiama WebGL e si basa sulla scelta del tag HTML <canvas> come base sulla quale costruire ed animare modelli tridimensionali usando delle API Javascript derivate dalle specifiche OPENGL ES 2.0.

Questo articolo si pone l’obiettivo di introdurre le WebGL a livello operativo e di illustrare una panoramica dei framework e degli strumenti di sviluppo ad oggi disponibili; per poter provare gli esempi e le demo che verranno presentate è necessario munirsi della versione ‘sperimentale’ di uno qualunque fra i più noti browser in circolazione; tuttavia suggerisco di utilizzare Chromium in quanto le diverse implementazioni di questa tecnologia differiscono ancora leggermente tra loro e gli esempi proposti sono stati costruiti usando questo browser.

Dettagli sulla procedura di installazione possono essere recuperati su questo sito.

Shaders e tutto il resto

Ci sono due aspetti che rendono ostico il mondo 3D per chi, come l’autore, possiede un background da sviluppatore web: la terminologia e la filosofia con la quale sono state scritte le API. Partiamo da quest’ultimo problema; come già accennato le WebGL nascono come implementazione JavaScript delle ben più note OPENGL ES 2.0, tali API sono di basso livello e funzionano intuitivamente come una sequenza di comandi utilizzati per pilotare le azioni del motore 3D. Un esempio di questo approccio è nel seguente listato WebGL che disegna sullo schermo un singolo triangolo:

gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, ...);
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, new Float32Array ...);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, new Float32Array ...);
gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);

Al di là del significato delle istruzioni è interessante notare come il tutto si riassuma nel mandare messaggi all’oggetto gl; tale istanza identifica un contesto WebGL costruito su di un <canvas> specifico usando la sintassi:

gl = document.getElementById("a_canvas_id").getContext("experimental-webgl");

Passiamo ora alla terminologia: è chiaro che non è possibile elencare e definire l’intero glossario che interessa il mondo legato alla programmazione 3D realtime, però credo che sia importante evidenziare un paio concetti che torneranno utili a breve.

Shader

La prima parola chiave è shader: uno shader è rappresentato da un set di istruzioni che spiegano alla GPU come comportarsi durante la fase di rendering, cioè di visualizzazione a video, di una scena 3D. Le specifiche WebGL richiedono che lo sviluppatore provveda a fornire alla GPU due shaders chiamati rispettivamente Vertex Shader e Fragment Shader.

Il compito imperativo del Vertex Shader è quello di restituire, per ogni tripletta di coordinate che identificano un vertice nello spazio (se stessi disegnando un cubo il Vertex Shader verrebbe interpellato 8 volte), una coppia di coordinate che identifichino lo stesso vertice sul piano bidimensionale del <canvas>. Questa operazione deve chiaramente tenere conto di quale sia il punto di vista e l’angolazione dalla quale si sta osservando la scena. A questo compito essenziale si aggiungono alcuni calcoli facoltativi, legati alla gestione delle luci ed al posizionamento delle textures.

Il compito del Fragment Shader è invece quello di definire il colore di ognuno dei pixel del <canvas> sui quali giace la rappresentazione bidimensionale della scena che è stata calcolata con l’ausilio delle informazioni del Vertex Shader.

WebGL utilizza un dialetto del C chiamato GLSL per definire gli shaders. Questo linguaggio, appositamente studiato per questo compito, è basato su una serie di convenzioni e può essere facilmente integrato in una pagina web. Un semplicissimo Fragment Shader ad esempio ha questo aspetto:

<script id="shader-fs" type="x-shader/x-fragment">
void main(void) {
  gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // vec4 è un vettore di 4 elementi RGBA
}
</script>

GLSL si aspetta nella variabile gl_FragColor il colore col quale dovrà essere renderizzato a video il pixel in oggetto. Usando lo shader appena creato ogni nostro modello tridimensionale verrà visualizzato solamente usando il colore bianco (1.0, 1.0, 1.0, 1.0). Lo stesso identico approccio contraddistingue anche un Vertex Shader; la variabile da valorizzare in quel caso però si chiama gl_Position.

Con questi concetti in mente possiamo accingerci a stendere il nostro primo script WebGL.

Se vuoi aggiornamenti su WebGL: 3D real time e OpenGL su HTML5 inserisci la tua e-mail nel box qui sotto:
 
X
Se vuoi aggiornamenti su WebGL: 3D real time e OpenGL su HTML5

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy