Advertisement
  1. Game Development
  2. WebGL
Gamedevelopment

Creazione di terreni realistici per giochi HTML5 con WebGL

by
Difficulty:IntermediateLength:LongLanguages:
Sponsored Content

This sponsored post features a product relevant to our readers while meeting our editorial guidelines for being objective and educational.

Italian (Italiano) translation by Chip (you can also view the original English article)

La prima versione di Flight Simulator venduta nel 1980 per Apple II, era sorprendentemente in 3D! Fu un risultato notevole. E' ancora più sorprendente se si considera che tutto il 3D fu fatto a mano, risultato di calcoli meticolosi e operazioni sui pixel a basso livello. Quando Bruce Atwick affrontò le prime versioni di Flight Simulator, non solo non c'erano framework 3D, ma non c'erano proprio framework in giro! Queste versioni del gioco furono scritte per lo più in assembler, giusto un passo sopra lo zero e zero sopra il flusso che attraverso una CPU.

Quando abbiamo deciso di ri-immaginare Flight Simulator (o Flight Arcade come lo chiamiamo noi) per il web e per dimostrare cosa era possibile fare col nuovo browser Microsoft Edge ed il motore di rendering EdgeHTML, non abbiamo potuto fare a meno di pensare al contrasto tra creare 3D allora e ora - vecchio Flight Sim, nuovo Flight Sim, vecchio Internet Explorer, nuovo Microsoft Edge. La moderna programmazione sembra  quasi un lusso per come abbiamo scolpito mondi 3D in WebGL con grandi framework come Babylon.js. Ci permette di concentrarci sugli stessi problemi ma ad alto livello.

In questo articolo, condividerò il nostro approccio ad una di queste divertenti sfidei: un modo semplice per creare terreni realistici su larga scala.

Nota: Il codice interattivo e gli esempi di questo articolo si trovano anche a Flight Arcade/Learn.

Modellazione e Terreni 3D

La maggior parte degli oggetti 3D vengono creati con strumenti di modellazione e per una buona ragione. Creare oggetti complessi (come un aereo o anche un edificio) è difficile da fare nel codice. Gli strumenti di modellazione hanno quasi sempre un senso nell'usarli, ma ci sono eccezioni! Uno di questi potrebbe essere il caso delle dolci colline dell'isola di Flight Arcade. Abbiamo concluso usando una tecnica che abbiamo trovato essere più semplice e forse anche la più intuitiva: una heightmap.

Una heightmap è un modo per utilizzare una immagine bidimensionale regolare per descrivere il i rilievi di elevazione di una superficie come un'isola o un altro terreno. E 'un modo abbastanza comune per lavorare con dati di elevazione, non solo nei giochi, ma anche nei sistemi informativi geografici (GIS) utilizzati dai cartografi e geologi.

Per aiutarvi a ottenere un'idea di come funziona, controllate la heightmap in questa demo interattiva. Provate a disegnare nel editor di immagini, e quindi controllate il terreno risultante.

Screenshot of the heightmap demo

Il concetto dietro ad una heightmap è abbastanza semplice. In un'immagine come quella di sopra, il nero puro è il "piano" e il bianco puro è la vetta più alta. I colori in scala di grigi nel mezzo rappresentano le corrispondenti elevazioni. Questo ci dà 256 livelli di elevazione, che sono abbastanza per i dettagli del nostro gioco. Le applicazioni realistiche potrebbero utilizzare lo spettro di colore completo per memorizzare molti più livelli di dettaglio (2564 = 4.294.967.296 livelli di dettaglio se si include un canale alfa).

Una heightmap ha alcuni vantaggi rispetto ad una tradizionale mesh poligonale:

Innanzitutto, le heightmaps sono molto più compatte. Solo i dati più significativi (l'elevazione) vengono memorizzati.  Essa dovrà poi essere trasformata in un oggetto 3D a livello di codice, ma questo è un classico prezzo da pagare: si risparmia spazio ora per pagare più tardi con il calcolo. Memorizzando i dati come una immagine, si ottiene un altro vantaggio in termini di spazio: è possibile sfruttare le tecniche standard di compressione delle immagini e rendere i dati più piccoli (in confronto)!

In secondo luogo, le heightmaps sono un modo conveniente per generare, visualizzare e modificare terreni. E 'abbastanza intuitivo quando se ne vede uno. Ci si sente un pò come guardare una mappa. Questo si è rivelato particolarmente utile per Flight Arcade. Abbiamo progettato e curato la nostra isola giusto con Photoshop! Ciò ci ha reso molto semplice effettuare piccole regolazioni quando necessarie. Quando, per esempio, abbiamo voluto fare in modo che la pista fosse completamente pianeggiante, abbiamo semplicemente dipinto su quella zona con un unico colore.

Potete vedere la heightmap per Flight Arcade sotto. Vedete se riuscite ad individuare le aree "piatte" che abbiamo creato per  la pista de il villaggio.

heightmap for Flight Arcade
La heightmap per l'isola di Flight Arcade. E' stata creato in Photoshop e si basa sulla "grande isola" di una famosa catena di isole dell'Oceano Pacifico. Qualche ipotesi?
Una texture che viene mappata sulla mesh 3D risultante dopo la heightmap creata via codice. Più informazioni a seguire.

Decodifica della Heightmap

Abbiamo costruito Flight Arcade con Babylon.js, e Babylon ci ha fornito una bella  scorciatoia per andare dalla heightmap al 3D. Babylon offre una API per generare una mesh geometrica da una immagine heightmap:

La quantità del dettagli è determinata dalla proprietà di suddivisione. E 'importante notare che il parametro si riferisce al numero di suddivisioni su ciascun lato dell'immagine heightmap, non il numero totale di celle. Quindi il leggero aumento di questo numero può avere un grande effetto sul numero totale di vertici nella vostra mesh.

  • 20 suddivisioni = 400 celle
  • 50 suddivisioni = 2.500 celle
  • 100 suddivisioni = 10.000 celle
  • 500 suddivisioni = 250.000 celle
  • 1.000 suddivisioni = 1.000.000 celle

Nella prossima sezione impareremo come texturizzare il terreno, ma quando si sperimenta con la creazione di heightmap, è utile vedere il wireframe. Ecco il codice per applicare una semplice texture wireframe così che sia facile vedere come i dati della heightmap vengono convertiti in vertici della nostra mesh:

Creare i Dettagli della Texture

Una volta ottenuto il modello, la mappatura di una texture era relativamente semplice. Per Flight Arcade, abbiamo semplicemente creato una grande immagine che combaciasse con l'isola nella nostra heightmap. L'immagine viene allungata sui contorni del terreno, in modo che la texture e la heightmap si mantengano in correlazione. Questo è stato veramente facile da visualizzare e, ancora una volta, tutto il lavoro per produrla è stato fatto in Photoshop.

L'immagine della texture originale è stata creata da 4096x4096. E' abbastanza grande! (Alla fine abbiamo ridotto le dimensioni per un livello a 2048x2048 in modo da mantenere il download ragionevole, ma tutto lo sviluppo è stato fatto con l'immagine a dimensione piena).  Ecco un esempio completo pixel dalla texture originale.

A full-pixel sample of the original island texture
Un campione full-pixel della texture originale dell'isola. L'intera città è di soli 300 px quadrati.

Quei rettangoli rappresentano gli edifici della città sull'isola. Abbiamo notato subito una differenza nel livello del dettaglio di texturing che potremmo ottenere tra il terreno e  gli altri modelli 3D. Anche con la nostra texture gigante dell'isola, la differenza era evidente a occhio nudo!

Per risolvere questo problema, abbiamo "miscelato" (blend)  dettagli aggiuntivi nella texture del terreno sotto forma di rumore casuale. Potete vedere il prima e dopo sotto. Notate come il rumore aggiuntivo migliora l'aspetto del dettaglio nel terreno.

Before and after comparison of airport texture

Abbiamo creato uno shader personalizzato per aggiungere il rumore. Gli shaders vi danno una quantità incredibile di controllo sul  rendering di una scena 3D WebGL, e questo è un grande esempio di come una shader possa essere utile.

Uno shader WebGL è composto da due pezzi: il vertex ed il fragment shader. L'obiettivo principale del vertex shader è di mappare i vertici di una posizione nella schermata di rendering. Il fragment (o pixel) Shader controlla il colore risultante dei pixel.

Gli Shaders sono scritti in un linguaggio di alto livello chiamato GLSL (Graphics Library Shader Language), che assomiglia al C. Questo codice viene eseguito dalla GPU. Per uno sguardo più in profondità su come funzionano gli shaders, seguite questo  tutorial  su come creare il proprio shader personalizzato per Babylon.js, oppure consultate questa guida per principianti alla programmazione di shader grafici.

Il Vertex Shader

Non stiamo cambiando il modo in cui la nostra texture è mappata su alla mesh del terreno, il nostro vertex shader è abbastanza semplice. Calcoliamo giusto la mappatura standard e assegnamo la posizione.

Il Fragment Shader

Il nostro Fragment Shader è un pò più complicato. Esso combina due immagini diverse: la base e l'immagine da mescolare (blend). L'immagine di base viene mappata su tutta la mesh del terreno. In Flight Arcade questa è l'immagine a colori dell'isola. L'immagine da miscelare (blend) è il piccolo rumore utilizzato per dare al terreno una texture e dettagli a distanza ravvicinata. Lo shader unisce i valori di ogni immagine per creare una texture combinata in tutta l'isola.

La lezione finale in Flight Arcade si svolge in un giorno di nebbia, così l'altro compito del nostro pixel shader è di regolare il colore per simulare la nebbia. L'aggiustamento si basa su quanto il vertice è lontano dalla telecamera, con i pixel più distanti che vengono "oscurati" più pesantemente dalla nebbia. Vedrete questo calcolo della distanza nella funzione calcFogFactor  sopra il codice dello shader principale.

Il pezzo finale per il nostro shader di blending personale è il codice JavaScript usato da Babylon. Lo scopo principale di questo codice è quello di preparare i parametri passati ai nostri vertex e pixel shader.

Babylon.js rende facile creare un Shader per materiali base personalizzati. Il nostro materiale di Blend è relativamente semplice, ma in realtà fa molta differenza nell'aspetto dell'isola, quando  l'aereo vola basso sul terreno. Gli Shaders portano la potenza della GPU nel browser, espandendo i tipi di effetti creativi che è possibile applicare alle vostre scene 3D. Nel nostro caso, quello era il tocco finale!

Più pratica con JavaScript

Microsoft ha un sacco di lezioni gratuite su molti argomenti open-source di JavaScript e l'intenzione è di crearne molti di più con Microsoft Edge. Eccone alcuni da controllare:

E alcuni strumenti gratuiti per iniziare: Visual Studio Code, Azure Trial e strumenti per il test cross-browser - tutto disponibile per Mac, Linux o Windows.

Questo articolo fa parte della serie di tecnologia web dev di Microsoft. Siamo entusiasti di condividere Microsoft Edge ed il nuovo motore di rendering EdgeHTML con voi. Ottenete le macchine virtuali libere o testate da remoto su dispositivi Mac, iOS, Android o Windows @ http://dev.modern.ie/.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.