Come rendere in modo efficiente una mesh di terreno di grandi dimensioni?


10

Recentemente sono stato bloccato su un problema pensando al modo migliore per generare un terreno nel mio gioco. In altri progetti normalmente utilizzavo le mappe di altezza, quindi tutto il lavoro di base era basato sul motore utilizzato, ma ora non è possibile farlo perché il terreno ha milioni di poligoni specifici che devono essere disegnati con precisione. Inoltre, molti di essi non possono essere analizzati dal vettore Y (a causa di poligoni nascosti sotto), ovvero una mappa di altezza non è utile qui. In questo caso ho dovuto usare un oggetto COLLADA.

Qualcuno mi ha detto di dividere manualmente il modello all'interno di un software come Blender, ma sfortunatamente anche questo non è possibile perché questi terreni sono creati in blocchi in un altro software e caricati dopo nel gioco (questa è l'idea). Pertanto questo sarebbe un grande lavoro essere obbligato a tagliarli manualmente ogni volta.

Pertanto, da una settimana ho studiato come posso risolvere questo problema e caricare in modo procedurale questa mesh, il terreno, in base alla frustrazione della telecamera, risparmiando quante più prestazioni possibili. Mi sono imbattuto in molti documenti sulla generazione di mesh procedurali e penso che il mio problema potesse essere risolto mappando la mesh in ocre. Questo è un grande lavoro, almeno per me, ed è per questo che sono qui, perché non voglio rischiare di prendere la strada sbagliata senza prima avere notizie di persone esperte.

In breve, ho milioni di vertici e indici che insieme formano il terreno, ma per ovvie ragioni non riesco a disegnarli contemporaneamente. È necessaria una sorta di procedura. Qual è il modo migliore per farlo, per trattare una grande maglia come un terreno? C'è qualche libro specifico a riguardo? C'è un modo migliore per implementarlo?

Ci scusiamo per qualsiasi tipo di errore, sono molto alle prime armi in questo settore.

Risposte:


12

Il chunking di base è un buon modo per iniziare. Se necessario, puoi passare a strutture di dati più sofisticate come ocre dopo. Per ora, dividi semplicemente il tuo terreno in blocchi di dimensioni specifiche quando carichi il modello dal disco.

A seconda dei tuoi dati, potresti voler dividere il terreno in pilastri su un piano che si estende per l'intera altezza o in cubi nello spazio. Il codice non è completo (fmod, inizializzazione vettoriale, indici, ...) ma dovrebbe darti un inizio.

// Load vertices from disk
struct point { double x, y, z; };    
vector<point> vertices;

// Create container for chunks
typedef pair<int, int> key;
unordered_map<key, vector<point>> chunks;
const int chunksize = 10;

// For each vertex
for (int i = 0; i < vertices.size(); ++i) {
    // Fetch global coordinates
    int x = vertices[i].x,
        y = vertices[i].y,
        z = vertices[i].z;

    // Find containing chunk
    key k;
    k.first  = x / chunksize;
    k.second = z / chunksize;

    // Calculate local coordinates
    point p;
    p.x = x % chunksize;
    p.y = y;
    p.z = z % chunksize;

    // Add to chunk
    chunks[k].push_back(p);
}

// Create separate buffers for each chunk
// ...

Poiché ora hai diviso la mesh, puoi eseguire LOD e tecniche di abbattimento su di essa per saltare il rendering di blocchi nascosti.

  • La distanza di visualizzazione è da dove inizi. Renderesti i blocchi solo entro una determinata distanza, ad esempio la distanza di visualizzazione della tua fotocamera. Minore è la distanza di visualizzazione, maggiore sarà la prestazione poiché è necessario disegnare meno blocchi del terreno.

  • L'abbattimento del frustum è una tecnica comune per il rendering solo di mesh che si intersecano con il frustum della telecamera. Molto probabilmente questo ti darà il più grande guadagno in termini di prestazioni.

Sperimenta con le dimensioni del pezzo e visualizza la distanza per ottenere i migliori risultati. La dimensione del pezzo è un compromesso tra l'abbattimento accurato e il calcolo semplice. Per ottimizzare ulteriormente, puoi dare un'occhiata a queste ottimizzazioni più avanzate.

  • L'abbattimento dell'occlusione può essere eseguito eseguendo il rendering delle mesh sulla CPU a una risoluzione molto bassa. Ciò consente di rilevare in anticipo mesh nascoste dietro altre. Non devono essere inviati alla GPU, quindi si salvano molte esecuzioni di shader di vertici che altrimenti sarebbero state eseguite prima di rifiutare i triangoli.

  • Il livello di dettaglio significa che calcoli le mesh a bassa risoluzione dei tuoi blocchi. In base alla distanza dalla fotocamera, scegli una delle maglie da disegnare. Ciò consente di ridurre il numero di vertici poiché i blocchi lontani non richiedono così tanti dettagli. Questo approccio si adatta bene alle ocre perché è possibile unire più cubi in una mesh a bassa risoluzione per aree molto distanti dalla fotocamera. Tuttavia, non è banale unire perfettamente i bordi tra due pezzi di una risoluzione diversa.

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.