Come ottenere i blocchi visti dal giocatore?


15

Sto scrivendo un gioco simile a Minecraft usando il motore Ogre e ho un problema. Devo ottimizzare il mio gioco, perché quando provo a disegnare 10000 blocchi, ho 2 FPS ... Quindi, ho avuto l'idea che blocca la visualizzazione dell'aereo e nasconde i blocchi invisibili. Ma ho un problema: come faccio a sapere quali blocchi alla volta sono visibili al giocatore?

E - se conosci altri metodi di ottimizzazione per un gioco del genere, scrivi cosa e come usarli in Ogre.

Risposte:


16

Bene, Ogre implementa già l'abbattimento del frustum (che fondamentalmente non disegna nulla che non potesse essere visto dalla telecamera) ma penso che il tuo problema sia diverso.

Non dovresti davvero visualizzare 10000 blocchi, ciò che è comunemente fatto (o almeno, nei pochi minecraft basati su Ogre3d come i cloni che ho visto (di cui ne sto facendo uno anch'io), e nell'originale) sta creando una mesh ( di alcune regioni NxNxN di blocchi) che presenta le facce esterne dei cubi. Cioè, quando metti 2 cubi fianco a fianco, le 2 facce che toccano non possono essere viste e quindi non devono essere disegnate.

Queste facce dovrebbero anche essere disegnate in qualcosa del genere: http://www.ogre3d.org/tikiwiki/tiki-index.php?page=DynamicGrowingBuffers poiché le moderne schede video preferiscono una mesh di 100000 poligoni rispetto a 1000 mesh di 100 poligoni.


10

Ci sono un paio di aspetti di questo problema. Innanzitutto, come stai disegnando i tuoi 10000 blocchi? Li stai effettivamente disegnando come 10000 oggetti separati? Se è così, questo è quasi sicuramente il collo della bottiglia, non la mancanza di abbattimento dell'occlusione. Dovresti raggruppare questi blocchi in un numero minore di mesh (forse qualche migliaio per mesh) al fine di ridurre le chiamate di disegno.

Per quanto riguarda la tua vera domanda, ci sono tre tipi di abbattimento dell'occlusione che mi vengono in mente.

1) Blocchi all'esterno del frustum della vista. Ciò significa blocchi che sono dietro di te o due sul lato. Ogre li rimuove già attraverso l'abbattimento della frustum vista.

2) Blocchi che sono "sotterranei" o completamente circondati da altri blocchi in modo che non possano mai essere visti da nessuna angolazione. Puoi identificarli osservando i blocchi adiacenti. Se sono tutti solidi, il blocco è nascosto. La GPU non dovrebbe mai nemmeno sapere di questi blocchi: dovrebbero essere saltati quando si crea la mesh che rappresenta la superficie.

3) Blocchi che sono in superficie e possono essere visti da alcune posizioni nel livello, ma che sono attualmente nascosti da una collina (o qualcosa del genere). Questo è il caso più difficile che non ho affrontato da solo, ma c'è una buona probabilità che le query sull'occlusione hardware possano essere utilizzate per questo caso.

È una spina spudorata, ma ho una libreria abbastanza matura che molte persone usano per sviluppare cloni di Minecraft, inclusi alcuni che usano Ogre. Definisci il contenuto del volume e genera la mesh di superficie che puoi quindi renderizzare. Ecco la home page:

http://www.thermite3d.org/

Ed ecco un video del progetto di qualcun altro che lo sta usando:

http://www.youtube.com/watch?v=Jju6WRPEK7o


4

È possibile utilizzare l'abbattimento della faccia posteriore per eliminare i vertici e i pixel associati che non sono rivolti al lettore. Il buffering di profondità dovrebbe occuparsi del resto. I blocchi da 10k in realtà non sono molti, il mio 5770 può eseguire il rendering di 100k verts a 1500fps. Penso che tu stia facendo qualcos'altro piuttosto male.


Sono d'accordo. Questo è probabilmente un problema con qualsiasi altra cosa.
Notabene,

1

Se hai 10000 oggetti separati, il collo di bottiglia è probabilmente il conteggio primitivo, non vertice, poligono o riempimento. Cuocia i tuoi oggetti in un numero inferiore di oggetti poligonali più alti per la velocità.

Minecraft ha un concetto di blocchi di cubi, ma al momento non riesco a trovare il riferimento.

Ecco anche i miei esperimenti sul disegno di tonnellate di cubi con varie tecniche. Non include la cottura (ancora).


0

Quello che faccio è che dopo aver creato il mio array di blocchi, ma prima di creare i vertici, eseguo un sub chiamato UpdateBlockVisiblility.

Il sub controlla semplicemente i vicini al blocco e aggiorna di conseguenza il valore booleano relativo ai blocchi.

#define BLOCKFACE_NORTH 0

#define BLOCKFACE_SOUTH 1 

etc etc etc

if(IsBlockAt(NorthOfBlock))
  Blocks[Whatever].facevisible[BLOCKFACE_NORTH] = false;

Quindi creo i vertici per il viso solo se è visibile! Semplice :)

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.