2011-10-03 11 views
12

Sto provando a creare un terreno 3D utilizzando WebGL. Ho un jpg con la texture per il terreno e un altro jpg con i valori di altezza (da -1 a 1).WebGL - Terreno strutturato con heightmap

Ho esaminato varie librerie di wrapper (come SpiderGL e Three.js), ma non riesco a trovare un esempio sutable, e se lo faccio (come in Three.js) il codice non è documentato e posso capisco come si fa.

Qualcuno può darmi un buon tutorial o esempio?

C'è un esempio in Three.js http://mrdoob.github.com/three.js/examples/webgl_geometry_terrain.html che è quasi quello che voglio. Il problema è che creano il colore delle montagne e i valori di altezza in modo casuale. Voglio leggere questi valori da 2 diversi file di immagine.

Qualsiasi aiuto sarebbe appagato. Grazie

+0

Solo una nota che JPEG potrebbe non essere il formato migliore per un terreno poiché è fiacco, e gli artefatti JPEG finiranno come dossi sottili nel terreno che potresti non aspettarti di trovare. – izb

risposta

5

due metodi che mi viene in mente:

  1. creare i tuoi vertici del paesaggio come una griglia piatta. Usa le ricerche Texture Vertex per interrogare la tua heightmap e modulare l'altezza (probabilmente il tuo componente Y) di ogni punto. Questo probabilmente sarebbe il più semplice, ma non penso che il supporto del browser per questo sia molto buono in questo momento. (In effetti, non riesco a trovare alcun esempio)
  2. Carica l'immagine, rendila su una tela e usala per leggere i valori di altezza. Costruisci una mesh statica basata su questo. Questo sarà probabilmente più veloce da eseguire, poiché gli shader stanno facendo meno lavoro. Tuttavia, richiede più codice per creare la mesh.

Per un esempio di lettura di dati di immagine, è possibile controllare this SO question.

+1

L'opzione 2 funzionerà meglio per te in quasi tutti i casi. L'opzione 1 è adatta solo se quello che stai rendendo è solo il terreno, perché tutti i dati di elevazione saranno noti solo dallo shader e avrai bisogno di altri mezzi per posizionare i tuoi (presumibilmente) altri oggetti di scena. – Chiguireitor

12

controllare questo post sopra su GitHub:

https://github.com/mrdoob/three.js/issues/1003

L'esempio ci collegata da florianf mi ha aiutato ad essere in grado di farlo.

function getHeightData(img) { 
    var canvas = document.createElement('canvas'); 
    canvas.width = 128; 
    canvas.height = 128; 
    var context = canvas.getContext('2d'); 

    var size = 128 * 128, data = new Float32Array(size); 

    context.drawImage(img,0,0); 

    for (var i = 0; i < size; i ++) { 
     data[i] = 0 
    } 

    var imgd = context.getImageData(0, 0, 128, 128); 
    var pix = imgd.data; 

    var j=0; 
    for (var i = 0, n = pix.length; i < n; i += (4)) { 
     var all = pix[i]+pix[i+1]+pix[i+2]; 
     data[j++] = all/30; 
    } 

    return data; 
} 

Demo: http://oos.moxiecode.com/js_webgl/terrain/index.html

2

Potreste essere interessati al mio post sul blog sul tema: http://www.pheelicks.com/2014/03/rendering-large-terrains/

mi concentro su come creare in modo efficiente la geometria del terreno in modo tale che si ottiene un adeguato livello di dettaglio nel campo vicino e anche lontano.

È possibile visualizzare una demo del risultato qui: http://felixpalmer.github.io/lod-terrain/ e tutto il codice è su GitHub: https://github.com/felixpalmer/lod-terrain

Per applicare una texture per il terreno, è necessario fare una ricerca consistenza nel frammento di shader, la mappatura la posizione nello spazio in una posizione nella trama. Per esempio.

vec2 st = vPosition.xy/1024.0; 
vec3 color = texture2D(uColorTexture, st) 
0

A seconda delle abilità GLSL, è possibile scrivere uno shader GLSL vertice, assegnare la texture per uno dei canali di texture, e leggere il valore nel vertex shader (Credo che hai bisogno di una scheda moderna di leggere le texture in uno shader di vertici, ma potrebbe essere solo io che mostro la mia età: P)

Nel vertex shader, tradurre il valore z del vertice in base al valore letto dalla trama.

0

Babylon.js rende questo estremamente facile da implementare. Potete vedere un esempio a: Heightmap Playground

Hanno anche implementato il motore fisico Cannon.js con esso, in modo da poter gestire le collisioni: Heightmap with collisions

Nota: a partire da questa scrittura che funziona solo con il cannone il plugin di fisica .js, e l'attrito non funziona (deve essere impostato su 0). Inoltre, assicurati di impostare la posizione di una mesh/impostore PRIMA di impostare lo stato fisico, o otterrai un comportamento strano.