Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

BabylonJS, creare animazioni e giochi 3D con WebGL

Link copiato negli appunti

Babylon.js (o BabylonJS) è un framework per la creazione di giochi in JavaScript. Nasce dalla mente di David Cauthe, che ha deciso di realizzarlo insieme ad altri contributor come David Rousset, dopo aver scoperto il supporto di Internet Explorer 11 di WebGL.

In questo articolo vedremo quali sono le caratteristiche di BabylonJS e come iniziare a lavorarci creando una semplice scena completa di telecamera, due oggetti in rotazione e una luce per illuminarli.

Le Features di BabylonJS

BabylonJS si classifica come Framework, ma è una libreria tutt'altro che banale: nonostante attualmente sia ancora in una fase iniziale di sviluppo presenta parecchie features interessanti:

  • Un sistema completo di scene graph con luci, telecamere, materiali, sprites, livelli e meshes;
  • Un sistema di collisioni affidabile con relativo sistema di response;
  • Una gestione dei materiali ottimamente realizzata, che permette di specificare diffuse, specular, emissive, alpha, reflection, ambient e bump. A breve vedremo di cosa si tratta;
  • Più tipologie di luci: point, directional, spot ed hemispheric;
  • Tre tipologie diverse di telecamere: free (un po' come nei giochi fps, per intenderci), una telecamera compatibile con i dispositivi touch e un'arc rotate camera;
  • Un sistema di texture che comprende Texture 2D, mirror, texture dinamiche, video;
  • Un sistema particellare perfettamente funzionante e configurabile;
  • Antialiasing, tecnica usata per ridurre l'effetto di scalettatura delle immagini, realizzando dei risultati più gradevoli alla vista;

Presenta inoltre svariate altre caratteristiche come un engine per l'animazione, frustum clipping, scene picking, il supporto per billboards e sprites e così via.

Merita una speciale menzione un convertitore in JSON per modelli 3D nei formati OBJ, FBX, MXB e Blender!

Nota: BabylonJS usa il sistema di coordinate "left-handed", illustrato nell'immagine seguente:

Figura 1. Sistema di coordinate "left-handed"
Sistema di coordinate 'left-handed'

Installare BabylonJS e costruire una prima scena

Possiamo scaricare BabylonJS da Github, ma non è necessario effettuare il download dell'intero pacchetto: per iniziare ci serviamo di due files di cui uno opzionale.

Cominciamo dal file obbligatorio: è il file .js che troviamo nella root (attualmente babylon.1.6.0.js, dalle dimensioni di circa 340KB). Il secondo file, facoltativo, è HandJS che permette di aggiungere la gestione degli input da tocco.

Ora che abbiamo tutto il necessario esaminiamo il file HTML principale, che è la base da cui partire.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Using babylon.js - Test page</title>
    <script src="babylon.js"></script>
    <style>
        html, body {
            width: 100%;
            height: 100%;
            padding: 0;
            margin: 0;
            overflow: hidden;
        }
        #renderCanvas {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="renderCanvas"></canvas>
</body>
</html>

In BabylonJS, tutto è controllato da un oggetto centrale ben specifico, il motore, o engine. Occorre quindi istanziarlo, sfruttando il contesto generato dall'elemento canvas che abbiamo inserito nella pagina:

<script>
    var canvas = document.getElementById("renderCanvas");
    var engine = new BABYLON.Engine(canvas, true);
</script>

Per fare le cose per bene possiamo effettuare una feature detection per verificare che WebGL sia supportato. Per farlo usiamo isSupported(), un "utility method" apposito:

<script>
    if (BABYLON.Engine.isSupported()) {
        var canvas = document.getElementById("renderCanvas");
        var engine = new BABYLON.Engine(canvas, true);
    }
</script>

In questo modo possiamo mostrare un messaggio di errore se si verificano problemi di compatibilità con il browser dell'utente.

Una volta istanziato l'engine vediamo come creare una scena dove poter inserire modelli tridimensionali, luci e telecamere:

var scene = new BABYLON.Scene(engine);

Il metodo BABYLON.Scene() prende come parametro l'oggetto engine e gli associa, automaticamente, una nuova istanza della classe Scene. Cosa manca? Qualche oggetto da mostrare, una luce per illuminare e una telecamera per vedere. Provvediamo subito!

var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 0, -10), scene);
var light0 = new BABYLON.PointLight("Omni0", new BABYLON.Vector3(0, 200, 100), scene);
var sphere = BABYLON.Mesh.CreateSphere("Sphere", 16, 3, scene);
var box = BABYLON.Mesh.CreateBox("Box", 1.0, scene);
box.position = new BABYLON.Vector3(0, 2, 2);
box.parent = sphere;

La sintassi è simile nelle varie istruzioni: si nota subito il parametro finale "scene" di ogni metodo usato per specificare la scena di destinazione dell'oggetto appena creato.

Abbiamo anche specificato che il "parent" del box creato è la sfera: questo vuol dire che, ad ogni rotazione della sfera, il box gli girerà intorno. Un po' come mettere un filo invisibile tra sfera e box.

Avremo sicuramente visto che nelle istruzioni vengono usati dei nuovi tipi di dati, come ad esempio Vector3. Il tipo di dato Vector3 è perfetto per indicare la posizione di un oggetto nello spazio. In Babylon abbiamo inclusi sia tipi come questo (es. matrix, rays, quaternioni e colori) sia le relazioni matematiche necessarie per manipolarli agevolmente.

Animare la scena, creare il loop

Ora possiamo è registrare un loop di rendering, per animare gli oggetti che abbiamo creato:

// Render loop
var renderLoop = function () {
    // Start new frame
    engine.beginFrame();
    scene.render();
    // Present
    engine.endFrame();
    // Register new frame
    BABYLON.Tools.QueueNewFrame(renderLoop);
};
BABYLON.Tools.QueueNewFrame(renderLoop);

In questo snippet di codice abbiamo creato un renderLoop, una funzione in cui definiamo cosa deve accadere per ogni frame. Le azioni che si susseguono sono:

  • engine.beginFrame(), che definisce l'inizio di un nuovo frame da disegnare;
  • scene.render(), che si occupa di aggiornare il risultato su schermo;
  • engine.endFrame(), che finalizza l'operazione;
  • BABYLON.Tools.QueueNewFrame(renderLoop), che assegna al frame successivo la funzione del renderLoop
  • .

Per far partire il loop viene agganciata la funzione al più prossimo frame in esecuzione (in modo simile a quanto accade con requestAnimationFrame).

BabylonJS prevede anche una gestione più automatizzata del loop, grazie al metodo runRenderLoop:

engine.runRenderLoop(function () {
	scene.render();
});

Nel primo modo, per modificare posizione o caratteristiche degli oggetti nell'animazione, possiamo inserire istruzioni direttamente all'interno del renderLoop, dopo aver inizializzato il frame. Sfruttando runRenderLoop invece possiamo fare meglio servendoci dell'evento beforeRender, previsto appositamente dal framework.

Vediamo allora come aggiungere il movimento alla sfera: inseriamo l'event handler prima della definizione di scene.render():

var alpha = 0;
scene.beforeRender = function() {
	sphere.rotation.x = alpha;
	sphere.rotation.y = alpha;
	alpha += 0.01;
};

Salviamo tutto ed eseguiamo.

Ecco il codice dell'esempio appena creato:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
	    <title>Using babylon.js - Test page</title>
	    <script src="babylon.js"></script>
	    <style>
	        html, body {
	            width: 100%;
	            height: 100%;
	            padding: 0;
	            margin: 0;
	            overflow: hidden;
	        }
	        #renderCanvas {
	            width: 100%;
	            height: 100%;
	        }
	    </style>
	</head>
	<body>
	    <canvas id="renderCanvas"></canvas>
	</body>
	<script>
	    if (BABYLON.Engine.isSupported()) {
	        var canvas = document.getElementById("renderCanvas");
	        var engine = new BABYLON.Engine(canvas, true);
	        var scene = new BABYLON.Scene(engine);
		var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 0, -10), scene);
		var light0 = new BABYLON.PointLight("Omni0", new BABYLON.Vector3(0, 200, 100), scene);
		var sphere = BABYLON.Mesh.CreateSphere("Sphere", 16, 3, scene);
		var box = BABYLON.Mesh.CreateBox("Box", 1.0, scene);
		box.position = new BABYLON.Vector3(0, 2, 2);
            	box.parent = sphere;
		engine.runRenderLoop(function () {
				scene.render();
		});
		var alpha = 0;
		scene.beforeRender = function() {
			sphere.rotation.x = alpha;
			sphere.rotation.y = alpha;
			alpha += 0.01;
		};
	    }
	</script>
</html>

Tiriamo le somme

Questo breve tutorial ha lo scopo di stimolare un po' di curiosità intorno a Babylon.js, che si configura come alternativa molto valida al più noto Three.js (finora l'unico framework basato su WebGL di alto livello). Ad esempio Babylon.js nasce per essere compatibile anche con IE11, per questo garantisce una miglior compatibilità cross-browser del competitor.

Oltre a questo troviamo un progetto dalla documentazione ricca e ben fatta (comprende tutorial, Wiki) che ci consente di approfondire e arrivare facilmente ad elaborare scene e animazioni complesse.

Molto interessante è la stretta interazione possibile con Blender e non ultimo risulta molto utile il sito, pieno di esempi per testare il framework e prendere spunto per i propri progetti.

Ti consigliamo anche