2013-01-05 15 views
11

Ho un vertex che accetta i seguenti attributi:OpenGL: attributo singolo vertice per più vertici?

  • a_posCoord: posizione del vertice
  • a_texCoord: coordinata trama (passata allo shader frammento)
  • a_alpha: fattore di trasparenza (passato allo shader frammento

Gli oggetti che sto rendendo sono tutti "tabelloni" (una coppia di triangoli rettangoli per formare un rettangolo).

Sto utilizzando una singola chiamata a glDrawArrays per il rendering di molti tabelloni pubblicitari, ognuno dei quali può avere un valore alfa univoco. Un singolo tabellone ha 6 vertici. Ecco alcuni pseudocodice per illustrare come organizzo vertice attributo tampone per un singolo cartellone: ​​

vertexAttributes = [ 

    px1,py1,pz1, // vertex 1: a_posCoord 
    tx1,ty1,  // vertex 1: a_texCoord 
    alpha,  // vertex 1: a_alpha 

    px2,py2,pz2, // vertex 2: a_posCoord 
    tx2,ty2,  // vertex 2: a_texCoord 
    alpha,  // vertex 2: a_alpha 

    px3,py3,pz3, // vertex 3: a_posCoord 
    tx3,ty3,  // vertex 3: a_texCoord 
    alpha,  // vertex 3: a_alpha 

    px4,py4,pz4, // vertex 4: a_posCoord 
    tx4,ty4,  // vertex 4: a_texCoord 
    alpha,  // vertex 4: a_alpha 

    px5,py5,pz5, // vertex 5: a_posCoord 
    tx5,ty5,  // vertex 5: a_texCoord 
    alpha,  // vertex 5: a_alpha 

    px6,py6,pz6, // vertex 6: a_posCoord 
    tx6,ty6,  // vertex 6: a_texCoord 
    alpha  // vertex 6: a_alpha 

    // ... Many more billboards not shown ... 
]; 

noti come lo stesso valore alpha viene ripetuto per 6 volte, una volta per ogni vertice.

C'è un modo per specificare un attributo per tutti e 6 i vertici senza doverlo ripetere per ogni singolo vertice?

Ecco quello che voglio attribuire il vertice tampone a guardare come, nell'interesse di ridurre la dimensione del buffer:

vertexAttributes = [ 
    px1,py1,pz1, // vertex 1: a_posCoord 
    tx1,ty1,  // vertex 1: a_texCoord 

    px2,py2,pz2, // vertex 2: a_posCoord 
    tx2,ty2,  // vertex 2: a_texCoord 

    px3,py3,pz3, // vertex 3: a_posCoord 
    tx3,ty3,  // vertex 3: a_texCoord 

    px4,py4,pz4, // vertex 4: a_posCoord 
    tx4,ty4,  // vertex 4: a_texCoord 

    px5,py5,pz5, // vertex 5: a_posCoord 
    tx5,ty5,  // vertex 5: a_texCoord 

    px6,py6,pz6, // vertex 6: a_posCoord 
    tx6,ty6,  // vertex 6: a_texCoord 

    alpha  // vertex 1-6: a_alpha 

    // ... Many more billboards not shown ... 
]; 

Per quel che vale, la mia soluzione attuale funziona bene, ma mi fa mi sento sporco Ho appena iniziato a capire come usare glVertexAttribPointer e mi chiedevo se in qualche modo supportasse qualcosa di simile, o se ci fosse un metodo o una tecnica diversa che potrei usare per ottenere qualcosa di meno forza bruta.


Questa è più specificamente una domanda WebGL, ma sono curioso di OpenGL in senso generale.

Sono consapevole che uno shader di geometria è davvero ciò di cui ho bisogno per questo particolare esempio, ma è fuori discussione dal momento che attualmente non sono supportati in WebGL.

+0

possibile duplicato [Rendering ingrana con diversi indici] (http://stackoverflow.com/questions/11148567/rendering-meshes-with-multiple-indices) –

+1

molto vicino ad essere un duplicato, anzi, ma mi piacerebbe tenerlo aperto per alcuni giorni per vedere se ci sono altre conoscenze là fuori dal momento che la mia domanda è un po 'più specifica e qualcuno potrebbe avere un approccio completamente diverso di cui non sono a conoscenza. Immagino che dovrò mantenere i dati ridondanti fino a quando WebGL non utilizzerà il supporto shader della geometria di ES3. – namuol

+0

Ho notato che glVertexBindingDivisor non fa parte di WebGL 1.0 o ES 2.0 (che sto usando) ... :( – Andy

risposta

6

Un vertice non è una posizione Un vertice è un lungo vettore composto di attributi multiplie. Cambia un singolo attributo e finisci con un vertice diverso. Quindi no, non puoi usare un singolo attributo vertice per più vertici, perché questo non ha senso semanticamente.

Tuttavia, ciò che è possibile con le versioni più recenti di OpenGL è l'impostazione della velocità con cui l'offset del buffer di un determinato vertice avanza.In pratica, ciò significa che i dati per un determinato array di vertici vengono duplicati su n vertici prima che l'offset del buffer per un attributo avanzi. La funzione per impostare questo divisore è glVertexBindingDivisor. Nel tuo caso, avresti impostato un Binding Divisor di per l'array alfa. Ma è importante che questo non usi un singolo attributo per più vertici, ma fa fare a OpenGL quella duplicazione che stavi facendo per te.

+1

Penso che sia anche importante notare che questa duplicazione avviene solo durante il rendering, quindi i valori alfa memorizzati con un divisore di binding di 6 utilizzerebbero meno memoria. (A meno che non abbia frainteso questa caratteristica!) – Andy

+0

Qual è il lato negativo di OpenGL che fa la duplicazione invece di usare un singolo attributo per mul vertici di punta? Questo significa che il buffer dei vertici sulla GPU è in qualche modo espanso e la memoria non viene salvata? Se no, allora qual è la differenza osservabile? – Ruslan

0

Se un attributo vertice è costante per ogni vertice, perché non si utilizza una variabile uniforme? Se è costante, è uniforme! In questo modo si imposta il valore uniforme solo una volta e il set di dati viene ridotto.

+1

Questo non funzionerà perché sto chiamando 'glDrawArrays' solo una volta per l'intero oggetto buffer che contiene _many_ tabelloni, ognuno dei quali ha il proprio valore alfa – namuol

+0

Non è stato chiaro per me, anzi penso che tu sia sfortunato! Mi spiace, – Luca

+0

Sì, dopo aver riletto la mia domanda mi sono reso conto che non sottolineo le parti importanti. ! – namuol

0

Ottengo questo effetto con il rendering istanziato. glVertexAttribDivisor(1); rende openGL read vertice attributo una volta per istanza. Se i tuoi bullboard hanno una geometria diversa, potresti considerare di passare la matrice del modello come attributo allo stesso modo di alfa.

+1

Questo non sembra essere supportato da WebGL ma lo esaminerò Grazie! – namuol

0

Un paio di idee:

1.) stringere i denti e aggiornare il vertex buffer, ma solo quando alfa cambiare.

2.) Rompere l'elenco dei quad in lotti e ricostruire solo i lotti che cambiano ..

3.) Controllare il numero di cartelloni pubblicitari e si legano una matrice di valori alfa per una divisa ... Nel alfa dei dati del vertice o in qualche canale/canale aggiuntivo non utilizzato, memorizzare l'indice dell'alfa per quel tabellone, nell'array uniforme. almeno in questo modo stai potenzialmente caricando solo n valori alfa.

4.) combinano 2 e 3 ...

sto solo prendendo un ipotesi ... Mi piacerebbe vedere se qualcun altro ha buone soluzioni!

0

Non ho esaminato questo in dettaglio, ma penso che potresti anche usare glDrawElementsInstanced. Con questo si inseriscono i valori alfa in una matrice uniforme e l'indice di istanza verrebbe in qualche modo passato allo shader. Controllare questo fuori:

http://sol.gfxile.net/instancing.html

Problemi correlati