Come posso ridurre l'impatto delle prestazioni del rendering degli alberi?


24

Sto realizzando un tipo di gioco stilizzato a basso poli. Ho un terreno con un po 'd'acqua e voglio un sacco di alberi; Ho 10.000 alberi disposti in serie, al momento. Ogni albero non contiene più di 200 triangoli, quindi non sono troppo faticosi.

Il problema principale è che ci sono laghi e i laghi sono piuttosto grandi. In realtà non puoi vedere alcun albero sull'altro lato del lago, e questo sembra davvero brutto, specialmente quando cammini lì e gli alberi compaiono improvvisamente.

Per risolvere questo problema, devo aumentare la distanza dell'albero in modo da poter vedere una discreta quantità di alberi sull'altro lato del lago, ma ciò riduce le prestazioni a 40-50 fps e non c'è quasi altro nel gioco. Sto usando una GTX 1080, se questo aiuta.

Cosa posso fare per rendere il mio gioco più veloce con più alberi?


IIRC, Silent Hill ha usato la nebbia per nascondere il taglio sul piano di ritaglio più lontano, che ha permesso loro di iniziare a caricare dinamicamente le cose appena oltre il punto in cui la nebbia si interrompe. Potresti beneficiare di un cambiamento nell'atmosfera del gioco.
Cody,

Gli alberi ti attirano a guardare fuori dalla finestra, riducendo così le tue prestazioni.
mbomb007,

Hai provato a eseguire il profiler? Se è così, dov'è il collo di bottiglia?
Mikael Högström,

Stai facendo qualche tipo di abbattimento di frustum?
Krythic,

Cos'è l'abbattimento di frustum?
sig. Matt

Risposte:


43

Ci sono un paio di cose che puoi fare per aumentare le prestazioni del disegno.

  1. Hai detto che erano abbastanza lontani. È possibile utilizzare LOD per ridurre il conteggio dei vertici di quegli alberi e quindi ridurre il tempo necessario per passare attraverso tutti i vertici da disegnare. Anche se questo probabilmente non è il problema attuale (GTX1080 con solo 10k alberi con 200 tris ciascuno, numeri scarsi per la gpu) l'ho comunque incluso. Il tabellone per le affissioni è uno strumento efficace per il livello LOD più basso, in quanto è essenzialmente un piano piatto sempre rivolto verso la telecamera con un'immagine di rendering dell'albero su di essa. Perde il senso di profondità, motivo per cui è buono per il livello più basso poiché il giocatore molto probabilmente non noterà la differenza.

  2. Hai attivato il batch ? Il batch dinamico di solito viene eseguito automaticamente se i conteggi dei vertici delle mesh sono abbastanza bassi. Il batch statico può anche essere provato rendendo statici gli alberi selezionando la casella di controllo nell'editor di unità sull'oggetto di gioco principale. Questo non funziona bene con oggetti animati. È necessario che gli oggetti abbiano materiale condiviso per farlo funzionare.

  3. Il batch personalizzato consente di controllare il rendering generando i blocchi da soli anziché lasciare che l'unità lo gestisca e consente anche il batch per mesh più grandi. Questo è fatto facilmente da Mesh.CombineMeshes . Anche questo non funziona bene con oggetti animati. È necessario che gli oggetti abbiano materiale condiviso per farlo funzionare. Probabilmente vuoi dividere il tuo mondo in una specie di blocchi e creare lotti da quelli. Il modo in cui dovrebbero essere generati quei pezzi dipende davvero da come la tua telecamera si muove nel mondo.

  4. Abilita istanza sugli shader. L'istanza consente al motore di disegnare più oggetti (con la stessa mesh) con una sola chiamata di disegno. È necessario che gli oggetti abbiano mesh condivisa e shader condiviso affinché questo funzioni. Il materiale può variare, ma lo shader deve supportare tutte le diverse proprietà variabili.

    Per fare in modo che il motore crei meglio i batch di rendering istanziati, probabilmente si desidera raggruppare le stesse mesh nella scena. Anche giocare con la coda di rendering del materiale ti darà buoni risultati se una mesh ha sempre lo stesso materiale. Durante lo sviluppo del gioco per cellulare a cui sto attualmente lavorando, ho usato questo per ridurre i drawballs di oltre la metà nella mia scena di test. Inoltre da Unity 5.6 assicurati di selezionare la Enable Instancingcasella di controllo nel materiale.

  5. Mantieni i tuoi drawcall e le chiamate SetPass in generale. Queste sono le chiamate non elaborate per la tua GPU per disegnare cose e hanno un grande sovraccarico. Ridurre i drawcall (che è ciò che sta facendo il batch e l'istanziamento) aumenterà le prestazioni complessive che la tua CPU può fornire in quanto è necessaria per fare molto meno attesa. Le chiamate SetPass sono modifiche ai tuoi shader attuali, quindi se hai molti materiali diversi avrai più chiamate SetPass, che fanno anche aspettare un po 'la CPU.

  6. Se la tua scena è enorme e il tempo della CPU passa per attraversare tutti gli oggetti nella scena, prova a ridurre gli oggetti nella scena. Raggruppa alcuni alberi invece di posizionarli in modo inverso e li hai come un singolo oggetto. Assicurati anche di non spostare gli alberi o gli oggetti padre, in quanto ciò rende Unity a scartare le trasformazioni memorizzate nella cache e a ricalcolare l'intero albero della scena.

  7. Se la tua scena è enorme e il tempo della tua CPU passa ancora per Unity camminando attraverso l'albero della scena per creare elenchi per il rendering di tutti gli oggetti, una cosa che potresti fare è non permettere a Unity di gestire il rendering. Se hai un modo migliore per tenere traccia degli oggetti disegnabili, puoi usare CommandBuffer.DrawMeshInstanced o Graphics.DrawMeshInstanced per disegnarli a mano. Non approfondirò questo aspetto in quanto è molto più avanzato e comporta l'abbattimento degli obetti di se stessi e quant'altro.

Nel caso in cui il batch statico o dinamico non funzioni correttamente (cosa che si può vedere controllando il debugger del frame), è necessario assicurarsi che si stia effettivamente utilizzando materiale condiviso e che non si stiano facendo copie del materiale per errore con la chiamata meshRenderer.material. La chiamata .materiala farà copie dei materiali e interromperà il batch. Usa .sharedMaterialinvece.

Da Unity 5.6 è possibile utilizzare Frame Debugger per determinare il motivo per cui alcuni drawcall non sono stati raggruppati in batch con i drawcall precedenti. Questo sarà davvero utile mentre provi a ridurre i limiti del tuo gioco.

L'istanza presenta i seguenti vantaggi rispetto al batch statico / dinamico / personalizzato:

  • Utilizza meno memoria poiché la mesh non deve essere duplicata in memoria
  • Può utilizzare più materiali, è richiesto solo lo shader condiviso
  • Gli oggetti possono essere animati

Inoltre, è un aspetto piuttosto nuovo in Unity e potrebbe essere un po 'instabile. Anche le GPU per dispositivi mobili o precedenti non supportano necessariamente l'istanziamento.


1. Sì, ho provato i LOD e, con mia grande sorpresa, ha effettivamente peggiorato le cose. Avevo 3 variazioni degli alberi ognuna con un conteggio dei vertici leggermente inferiore e un piano piatto con un'immagine di rendering dell'albero su di essa.
mr-matt,

2. Tutti i miei alberi sono contrassegnati come statici. Per quanto ne so, ciò consente il batch? È corretto? E quando dici materiale condiviso, intendi semplicemente, gli alberi hanno lo stesso materiale?
sig. Matt

3. Che tipo di miglioramento delle prestazioni avrebbe effettivamente comportato? Vale la pena provare?
sig. Matt

1
2/3: Nella mia esperienza, Unity non fa un ottimo lavoro nel batch dinamico e il batch statico aumenta le dimensioni della build, quindi ho implementato il batch da solo e ho fatto la mesh combinando il tempo di caricamento. Usando questa tecnica sono riuscito a fare 2500 drawballs per comprimere in circa 300 drawcall che era cruciale per il nostro gioco mobile in cui i drawcall sono importanti. Faceva calcolare un po 'di vertici inutili (fuori schermo) ma ne valeva la pena.
Lasse

2
tfw quando leggi una domanda sulle scarse prestazioni con gli alberi e non si perde una sola parola sul tabellone per le affissioni
Num Lock

13

Ok, quindi il problema era semplicemente che non stavo usando un GI in tempo reale pre-calcolato. L'ho verificato poco fa ma non ha avuto un effetto immediato, quindi l'ho lasciato e me ne sono dimenticato, e anche il tempo di elaborazione dell'illuminazione è stato così lungo. Tuttavia, ha appena finito di elaborarlo, e la mia parola, il mio fps è aumentato di 3x. Quindi per ora, lo lascerò a quello e in futuro assicurerò di usare sempre GI in tempo reale precomputer!

Se c'è ancora qualcos'altro che potrei fare per migliorare ulteriormente le prestazioni, per favore fatemi sapere, sarei molto grato!


2
Usa Occlusion Culling, anche se la tua scena è grande - considera di dividerla in blocchi, ad esempio molti terreni e carica e scarica.
Candid Moon _Max_

Dato che sembra che tu abbia risolto il tuo problema, probabilmente dovresti accettare questa risposta.
Gnemlock
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.