Comment rendre efficacement un grand maillage de terrain?

10

Récemment, je suis coincé sur un problème en pensant à la meilleure façon de générer un terrain dans mon jeu. Dans d'autres projets, j'utilisais normalement des cartes d'altitude, donc tout le travail de base était basé sur le moteur utilisé, mais maintenant cela ne peut pas être fait car le terrain a des millions de polygones spécifiques qui doivent être dessinés avec précision. De plus, beaucoup d'entre eux ne peuvent pas être analysés à partir du vecteur Y (à cause des polygones cachés en dessous), c'est-à-dire qu'une carte de hauteur n'est pas utile ici. Dans ce cas, j'ai dû utiliser un objet COLLADA.

Quelqu'un m'a dit de diviser manuellement le modèle dans un logiciel comme Blender, mais malheureusement ce n'est pas possible non plus car ces terrains sont créés en morceaux dans un autre logiciel et chargés ensuite dans le jeu (c'est l'idée). Ce serait donc un gros travail que d'être obligé de les découper manuellement à chaque fois.

Ainsi, depuis une semaine, j'étudie comment résoudre ce problème et charger de manière procédurale ce maillage, le terrain, en fonction de la frustration de la caméra, en économisant autant de performances que possible. Je suis tombé sur de nombreux documents sur la génération de maillage procédural et je pense que mon problème pourrait être résolu en mappant le maillage en octets. C'est un GRAND travail, au moins pour moi, et c'est pourquoi je suis ici, car je ne veux pas risquer de prendre le mauvais chemin sans avoir à entendre des gens expérimentés.

En bref, j'ai des millions de sommets et d'indices qui forment ensemble le terrain, mais pour des raisons évidentes, je ne peux pas les dessiner en même temps. Il fallait une sorte de procédure. Quelle est la meilleure façon de le faire, de traiter un gros maillage comme un terrain? Y a-t-il un livre spécifique à ce sujet? Existe-t-il un meilleur moyen de le mettre en œuvre?

Désolé pour toute sorte d'erreur, je suis très novice dans ce domaine.

Karl Marny
la source

Réponses:

12

Le découpage de base est une bonne façon de commencer. Vous pouvez passer à des structures de données plus sophistiquées comme des octrois plus tard, si vous en avez besoin. Pour l'instant, divisez simplement votre terrain en morceaux de dimensions données lors du chargement du modèle à partir du disque.

Selon vos données, vous souhaiterez peut-être diviser votre terrain en piliers sur un plan couvrant toute la hauteur, ou en cubes dans l'espace. Le code n'est pas complet (fmod, initialisation vectorielle, indices, ...) mais devrait vous donner un début.

// 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
// ...

Étant donné que vous avez divisé le maillage maintenant, vous pouvez effectuer des techniques de LOD et d'élimination sur celui-ci pour ignorer le rendu des morceaux cachés.

  • La distance d'affichage est l'endroit où vous commencez. Vous ne rendriez que des morceaux à une distance donnée, par exemple la distance de vue de votre caméra. Plus la distance de vue est petite, plus vous obtenez de performances, car moins de morceaux de terrain doivent être dessinés.

  • Le tri sélectif est une technique courante pour ne rendre que les maillages qui se croisent avec le point de vue de la caméra. Cela vous donnera probablement le gain de performances le plus important.

Expérimentez avec la taille du morceau et la distance de vue pour obtenir les meilleurs résultats. La taille des morceaux est un compromis entre une élimination précise et un calcul facile. Pour optimiser davantage, vous pouvez jeter un œil à ces optimisations plus avancées.

  • L'abattage d'occlusion peut être effectué en rendant les maillages sur le processeur à très basse résolution. Cela vous permet de détecter rapidement les maillages cachés derrière les autres. Ils ne doivent pas être envoyés au GPU, vous économisez donc beaucoup d'exécutions de vertex shaders qui auraient autrement été effectuées avant de rejeter les triangles.

  • Le niveau de détail signifie que vous calculez des maillages de résolution inférieure de vos morceaux. En fonction de la distance à la caméra, vous choisissez l'un des maillages à dessiner. Cela vous permet de réduire le nombre de sommets car les morceaux éloignés n'ont pas besoin de beaucoup de détails. Cette approche fonctionne bien avec les octets car vous pouvez fusionner plusieurs cubes en un seul maillage basse résolution pour les zones éloignées de la caméra. Cependant, il n'est pas trivial de fusionner de façon transparente les bords entre deux morceaux d'une résolution différente.

danijar
la source