Qual è il modo migliore per disegnare molti alberi


8

Sto scrivendo un'app che rende un'isola casuale alberata. Gli alberi sono attualmente due quadrupli, incrociati e disegnati con trame. Ho in programma di avere maglie più complesse che formano diversi tipi di piante, ad esempio una palma, una quercia, erbe ecc.

Isola campione

Il problema che devo affrontare è che, poiché le trame sono trasparenti, devo disegnarle da dietro a davanti. Plan-b consiste nel chiamare l'uso di scartare nello shader di frag, ma l'ordine z dà risultati migliori:

uniform float uTreeAlpha;
uniform sampler2D uTexture;

varying vec2 vTexCoordOut;

void main (void)
{
  vec4 colour = texture2D(uTexture, vTexCoordOut);
  if (colour.a < 0.1) {
    discard;
  }
  gl_FragColor = vec4(colour.rgb, colour.a * uTreeAlpha);   
}

Il secondo problema è perché l'ordine cambia a seconda della fotocamera e del lookat Non conosco un modo efficiente per disegnarli in OpenGL in una sola chiamata.

Al momento il mio codice di rendering è simile a questo pseudocodice:

if cameraChangedFromLastTime() then
  sortTreesBackToFront();
end
for i = 0 to trees.size() -1
  drawTree()
end

Dove ogni drawTree () imposta alcune uniformi, imposta la trama e quindi chiama glDrawArrays (). Ho alcune ottimizzazioni per saltare l'impostazione di una trama o l'aggiornamento dei cordoni di trama se l'ultimo albero e la corrente sono uguali e l'impostazione di alcune uniformi comuni al di fuori del ciclo e di saltare alberi che sono troppo lontani ma fondamentalmente se ho 3000 alberi andare 3000 volte intorno al ciclo.

Disegnare ogni albero singolarmente è il killer delle prestazioni. Se potessi disegnarli in una sola chiamata, o lotti (preservando l'ordine Z) probabilmente lo farei in 1/10 del tempo.

Quindi come lo farei. Tieni presente che i miei alberi sono segnaposto e alla fine avrei:

  • Maglie diverse per alberi diversi
  • Diverse scale e angoli per gli alberi per dare un po 'più di varietà
  • Trame diverse per alberi diversi, trame potenzialmente multiple applicate a una mesh (ad esempio lascia una trama, tronco un'altra)
  • Gli alberi sono tutti mescolati insieme, quindi nessun modo semplice per disegnare un tipo e poi un altro
  • Qualche forma di semplice animazione ciclica (rami che soffiano nel vento)
  • Tutte le trame risiederebbero in un unico atlante

Quindi qual è l'approccio migliore qui? È possibile eseguire il rendering in un unico passaggio? Se avessi usato glDrawElements, ricostruendo gli indici ma non i vertici, avrei potuto raggiungere questo obiettivo?


vterrain.org , vedere la colonna di destra nella sezione piante per il rendering dell'impianto, la rispettiva colonna di sinistra, il rendering della sezione per il livello di dettaglio / accelerazioni di rendering generali. Attenzione però: la fonte è più un elenco di articoli di ricerca che tutorial.
Exilyth,

Non ne so molto di queste cose. Ma controlla il software VUE. Viene utilizzato per creare paesaggi con alberi, montagne, atmosfera e molto altro, in 3d. Ma non sono sicuro che ti aiuterà nella tua situazione
user1981248

Risposte:


3

Quello che vuoi è l'istanziamento hardware . Nota: l'ho fatto in XNA (cioè DirectX), ma non so molto su OpenGL. Sono sicuro che esiste una funzione comparabile, però. Fondamentalmente, ciò che equivale a unire i vertici del modello di albero con un altro flusso di vertici che trasporta le coordinate del mondo per ogni istanza.


1
L'equivalente OpenGL sarebbe l'estensione opengl.org/registry/specs/EXT/draw_instanced.txt . Ma, per cominciare, potrebbe essere utile visualizzare gli elenchi degli oggetti OpenGL e Vertex Array Legacy / Vertex Buffer nel moderno OpenGL. In entrambi i casi, un oggetto / mesh viene archiviato in Elenco / VAO / VBO, quindi ogni istanza viene disegnata con una trasformazione diversa. Utilizzando mesh statiche, i dati possono essere caricati una volta e quindi riutilizzati. sol.gfxile.net/instancing.html offre una breve panoramica dei diversi metodi.
Exilyth,

Grazie, instancing è un'idea interessante. Non potrei usare un'estensione draw_instanced tuttavia, poiché sto usando OpenGL ES 2.0 e sto lavorando a qualcosa che funziona su tutto. Sto forse pensando di poter caricare le varie maglie degli alberi in un VBO (potenzialmente con modelli più semplici più lontano), z-sort, e quindi disegnarle in batch da un buffer di indice che creerei per ogni batch. Potrei essere in grado di disegnare 30 o 40 alla volta in quel modo.
Locka,

2

La trasparenza deve essere ordinata solo se utilizza la fusione non additiva. Per un sacco di cartelloni pubblicitari distanti, la miscelazione non è necessaria (non si vede davvero). Renderizza almeno gli altri con trasparenza di ritaglio (alfa di solo 1 o 0) e non è necessario ordinarli.

È possibile utilizzare una sorta di foglio sprite per eseguire il rendering di diversi tipi di alberi, con animazioni al forno. Disegna mesh per alberi più vicini che puoi animare con maggiore fedeltà in base ai venti o qualsiasi cosa tu voglia.


Ho sperimentato l'uso di scarto e nessun ordinamento, ma i risultati sembrano un po 'difficili - gli alberi tendono a sovrapporsi molto, quindi se non c'è un ordine coerente, ottengo un sacco di pop dove un albero va di fronte all'altro e " vince "il pixel. Ho lasciato lo scarto perché ci sono ancora collisioni occasionali (ad es. 2 alberi con la stessa identica distanza dalla videocamera) ma si tratta di un fallback. Ho anche sperimentato cartelloni pubblicitari e l'effetto è troppo falso soprattutto per i cavalcavia.
Locka,

Usa cartelloni migliori. Idealmente, avere un modello ad albero. Genera lo sprite del tabellone per le affissioni per un angolo di visione e usa quello sprite in corrispondenza dell'angolo approssimativo. Per i ritagli, funzionano meglio a distanza, dove non puoi vedere la differenza. Man mano che ci si avvicina, è necessario utilizzare modelli più complessi (forse alcuni quadratini per albero), oppure è possibile passare alla trasparenza dello schermo-porta.
Sean Middleditch,

Ad un certo punto, è necessario capire l'equilibrio accettabile tra qualità e velocità. Non otterrai "incredibilmente veloce" e "perfetto" per le scene più complesse sull'hardware delle materie prime.
Sean Middleditch,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.