WebGL - Geometria

Dopo aver ottenuto il contesto WebGL, devi definire la geometria per la primitiva (oggetto che vuoi disegnare) e memorizzarla. In WebGL, definiamo i dettagli di una geometria, ad esempio vertici, indici, colore della primitiva, utilizzando array JavaScript. Per passare questi dettagli ai programmi shader, dobbiamo creare gli oggetti buffer e memorizzare (allegare) gli array JavaScript contenenti i dati nei rispettivi buffer.

Note: Successivamente, questi oggetti buffer verranno associati agli attributi del programma shader (vertex shader).

Definizione della geometria richiesta

Un modello 2D o 3D disegnato utilizzando i vertici è chiamato a mesh. Ogni sfaccettatura in una mesh è chiamata apolygon e un poligono è composto da 3 o più vertici.

Per disegnare modelli nel contesto di rendering WebGL, è necessario definire i vertici e gli indici utilizzando gli array JavaScript. Ad esempio, se vogliamo creare un triangolo che giace sulle coordinate {(5,5), (-5,5), (-5, -5)} come mostrato nel diagramma, allora puoi creare un array per i vertici come -

var vertices = [
   0.5,0.5,    //Vertex 1
   0.5,-0.5,   //Vertex 2
   -0.5,-0.5,  //Vertex 3
];

Allo stesso modo, puoi creare un array per gli indici. Gli indici per gli indici triangolari di cui sopra saranno [0, 1, 2] e possono essere definiti come -

var indices = [ 0,1,2 ]

Per una migliore comprensione degli indici, considera modelli più complessi come il quadrato. Possiamo rappresentare un quadrato come un insieme di due triangoli. Se (0,3,1) e (3,1,2) sono i due triangoli con cui intendiamo disegnare un quadrato, allora gli indici saranno definiti come -

var indices = [0,3,1,3,1,2];

Note -

Per disegnare le primitive, WebGL fornisce i seguenti due metodi:

  • drawArrays() - Durante l'utilizzo di questo metodo, passiamo i vertici della primitiva utilizzando gli array JavaScript.

  • drawElements() - Durante l'utilizzo di questo metodo, passiamo sia i vertici che gli indici della primitiva utilizzando l'array JavaScript.

Oggetti buffer

Un oggetto buffer è un meccanismo fornito da WebGL che indica un'area di memoria allocata nel sistema. In questi oggetti buffer, è possibile memorizzare i dati del modello che si desidera disegnare, corrispondenti a vertici, indici, colori, ecc.

Utilizzando questi oggetti buffer, è possibile passare più dati al programma shader (vertex shader) tramite una delle sue variabili di attributo. Poiché questi oggetti buffer risiedono nella memoria della GPU, possono essere renderizzati direttamente, il che a sua volta migliora le prestazioni.

Per elaborare la geometria, esistono due tipi di oggetti buffer. Sono -

  • Vertex buffer object (VBO)- Contiene i dati per vertice del modello grafico che verrà renderizzato. Usiamo oggetti del buffer dei vertici in WebGL per memorizzare ed elaborare i dati relativi ai vertici come le coordinate dei vertici, le normali, i colori e le coordinate della trama.

  • Index buffer objects (IBO) - Contiene gli indici (dati indice) del modello grafico che verrà renderizzato.

Dopo aver definito la geometria richiesta e averla memorizzata negli array JavaScript, è necessario passare questi array agli oggetti buffer, da cui i dati verranno passati ai programmi shader. I seguenti passaggi devono essere seguiti per memorizzare i dati nei buffer.

  • Crea un buffer vuoto.

  • Associare un oggetto array appropriato al buffer vuoto.

  • Passa i dati (vertici / indici) al buffer utilizzando uno dei typed arrays.

  • Scollega il buffer (facoltativo).

Creazione di un buffer

Per creare un oggetto buffer vuoto, WebGL fornisce un metodo chiamato createBuffer(). Questo metodo restituisce un oggetto buffer appena creato, se la creazione è riuscita; altrimenti restituisce un valore nullo in caso di errore.

WebGL funziona come una macchina a stati. Una volta creato un buffer, qualsiasi operazione successiva verrà eseguita sul buffer corrente fino a quando non lo scioglieremo. Usa il codice seguente per creare un buffer:

var vertex_buffer = gl.createBuffer();

Note - gl è la variabile di riferimento al contesto WebGL corrente.

Bind the Buffer

Dopo aver creato un oggetto buffer vuoto, è necessario associare ad esso un buffer array appropriato (destinazione). WebGL fornisce un metodo chiamatobindBuffer() per questo scopo.

Sintassi

La sintassi di bindBuffer() metodo è il seguente:

void bindBuffer (enum target, Object buffer)

Questo metodo accetta due parametri e vengono discussi di seguito.

target- La prima variabile è un valore enum che rappresenta il tipo di buffer che vogliamo associare al buffer vuoto. Sono disponibili due valori enum predefiniti come opzioni per questo parametro. Sono -

  • ARRAY_BUFFER che rappresenta i dati dei vertici.

  • ELEMENT_ARRAY_BUFFER che rappresenta i dati dell'indice.

Object buffer- La seconda è la variabile di riferimento all'oggetto buffer creato nel passaggio precedente. La variabile di riferimento può essere di un oggetto buffer di vertice o di un oggetto buffer di indice.

Esempio

Il frammento di codice seguente mostra come utilizzare il metodo bindBuffer ().

//vertex buffer
var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

//Index buffer
var Index_Buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

Passaggio di dati nel buffer

Il passaggio successivo consiste nel passare i dati (vertici / indici) al buffer. Fino ad ora i dati hanno la forma di un array e prima di passarli al buffer, dobbiamo avvolgerli in uno degli array tipizzati WebGL. WebGL fornisce un metodo denominatobufferData() per questo scopo.

Sintassi

La sintassi del metodo bufferData () è la seguente:

void bufferData (enum target, Object data, enum usage)

Questo metodo accetta tre parametri e vengono discussi di seguito:

target - Il primo parametro è un valore enum che rappresenta il tipo di buffer dell'array che abbiamo usato. Le opzioni per questo parametro sono:

  • ARRAY_BUFFER che rappresenta vertex data.

  • ELEMENT_ARRAY_BUFFER che rappresenta index data.

Object data- Il secondo parametro è il valore dell'oggetto che contiene i dati da scrivere nell'oggetto buffer. Qui dobbiamo passare i dati usandotyped arrays.

Usage- Il terzo parametro di questo metodo è una variabile enum che specifica come utilizzare i dati dell'oggetto buffer (dati memorizzati) per disegnare forme. Sono disponibili tre opzioni per questo parametro, come elencato di seguito.

  • gl.STATIC_DRAW - I dati verranno specificati una volta e utilizzati più volte.

  • gl.STREAM_DRAW - I dati verranno specificati una volta e utilizzati più volte.

  • gl.DYNAMIC_DRAW - I dati verranno specificati ripetutamente e utilizzati molte volte.

Esempio

Il frammento di codice seguente mostra come utilizzare il bufferData()metodo. Supponiamo che i vertici e gli indici siano gli array che contengono rispettivamente i dati del vertice e dell'indice.

//vertex buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

//Index buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

Array tipizzati

WebGL fornisce un tipo speciale di array chiamato typed arraysper trasferire gli elementi di dati come vertice indice e texture. Questi array tipizzati memorizzano grandi quantità di dati e li elaborano in formato binario nativo che si traduce in prestazioni migliori. Gli array tipizzati usati da WebGL sono Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, UInt32Array, Float32Array e Float64Array.

Note

  • Generalmente, per memorizzare i dati dei vertici, utilizziamo Float32Array; e per memorizzare i dati dell'indice, usiamoUint16Array.

  • Puoi creare array digitati proprio come gli array JavaScript usando new parola chiave.

Scollega i buffer

Si consiglia di svincolare i buffer dopo averli utilizzati. Può essere fatto passando un valore nullo al posto dell'oggetto buffer, come mostrato di seguito.

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

WebGL fornisce i seguenti metodi per eseguire operazioni di buffer:

Sr.No. Metodi e descrizione
1

vuoto bindBuffer(enum target , Object buffer )

target : ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

2

vuoto bufferData( destinazione enum , dimensione lunga , utilizzo enum )

target : ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

utilizzo - STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW

3

vuoto bufferData( destinazione enum , dati oggetto , utilizzo enum )

destinazione e utilizzo : come perbufferData sopra

4

vuoto bufferSubData(enum target , long offset , Object data )

target : ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

5 Oggetto createBuffer()
6 vuoto deleteBuffer( Buffer oggetto )
7

qualunque getBufferParameter(enum target , enum pname )

target : ARRAY_BUFFER, ELEMENT_ ARRAY_BUFFER

pname - BUFFER_SIZE, BUFFER_USAGE

8 bool isBuffer( Buffer oggetto )