Comment puis-je réduire l'impact sur les performances du rendu des arbres?


24

Je fais un jeu stylisé low poly. J'ai un terrain avec de l'eau et je veux beaucoup, beaucoup d'arbres; J'ai 10 000 arbres placés en masse pour le moment. Chaque arbre ne comprend pas plus de 200 triangles, donc ils ne sont pas trop imposants.

Le principal problème est qu'il y a des lacs et que les lacs sont assez grands. Vous ne pouvez pas vraiment voir d'arbres de l'autre côté du lac, et cela semble vraiment mauvais, surtout lorsque vous y marchez et que des arbres apparaissent soudainement.

Pour résoudre ce problème, je dois augmenter la distance entre les arbres afin que vous puissiez voir une quantité décente d'arbres de l'autre côté du lac, mais cela réduit les performances à 40-50fps, et il n'y a presque rien d'autre dans le jeu pour l'instant. J'utilise une GTX 1080, si cela aide.

Que puis-je faire pour accélérer le jeu avec plus d'arbres?


IIRC, Silent Hill a utilisé du brouillard pour masquer la coupure dans le plan de délimitation éloigné, ce qui leur a permis de commencer à charger dynamiquement des éléments juste au-delà de la coupure du brouillard. Vous pourriez bénéficier d'un changement dans l'atmosphère du jeu.
Cody

Les arbres vous poussent à regarder par la fenêtre, réduisant ainsi vos performances.
mbomb007

Avez-vous essayé d'exécuter le profileur? Si oui, où est le goulot d'étranglement?
Mikael Högström

Faites-vous une sorte d'abattage de tronc?
Krythic

Qu'est-ce que le tri sélectif?
mr-matt

Réponses:


43

Vous pouvez effectuer plusieurs actions pour augmenter les performances de dessin.

  1. Vous avez dit qu'ils étaient assez loin. Vous pouvez utiliser LOD pour diminuer le nombre de sommets de ces arbres, et ainsi diminuer le temps nécessaire pour parcourir tous les sommets en cours de tracé. Même si ce n'est probablement pas le problème à portée de main (GTX1080 avec seulement 10k arbres avec 200 tris chacun, des nombres chétifs pour le GPU), je l'ai toujours inclus. Le panneau d'affichage est un outil efficace pour le niveau de LOD le plus bas, car il s'agit essentiellement d'un plan plat toujours face à la caméra avec une image rendue de l'arbre. Il perd le sens de la profondeur, c'est pourquoi il est bon pour le niveau le plus bas car le joueur ne remarquera probablement pas la différence.

  2. Avez-vous activé le traitement par lots ? La mise en lot dynamique est généralement effectuée automatiquement si le nombre de sommets des mailles est assez faible. Le traitement par lots statique peut également être essayé en rendant les arbres statiques en cochant la case dans l'éditeur d'unité sur l'objet de jeu parent. Cela ne fonctionne pas bien avec les objets animés. Vous avez besoin que les objets partagent du matériel pour que cela fonctionne.

  3. Le traitement par lots personnalisé vous permet de contrôler le rendu en générant vous-même les blocs au lieu de laisser l'unité le gérer, et il permet également le traitement par lots pour les maillages plus volumineux. Cela se fait facilement par Mesh.CombineMeshes . Cela ne fonctionne pas non plus correctement avec les objets animés. Vous avez besoin que les objets partagent du matériel pour que cela fonctionne. Vous voulez probablement diviser votre monde en une sorte de morceaux et en créer des lots. La façon dont ces morceaux doivent être générés dépend vraiment de la façon dont votre caméra se déplace dans le monde.

  4. Activez l' instanciation sur les shaders. L'instanciation permet au moteur de dessiner plusieurs objets (avec le même maillage) avec un seul appel de dessin. Pour que cela fonctionne, les objets doivent avoir un maillage partagé et un shader partagé. Le matériau peut varier, mais le shader doit supporter toutes les différentes propriétés variables.

    Pour que le moteur crée mieux des lots de rendu instanciés, vous souhaiterez probablement regrouper les mêmes maillages dans la scène. Jouer également avec la file d'attente de rendu des matériaux vous donnera de bons résultats si un maillage a toujours le même matériau. Pendant le développement du jeu mobile sur lequel je travaille actuellement, je l'ai utilisé pour réduire de plus de moitié les appels dans ma scène de test. Aussi depuis Unity 5.6 assurez-vous de cocher la Enable Instancingcase dans le matériau.

  5. Gardez vos appels et vos appels SetPass en général. Ce sont les appels bruts pour que votre GPU dessine des trucs, et ils ont une surcharge importante. La réduction des appels (ce que font le traitement par lots et l'instanciation) augmentera les performances globales de votre processeur, car il est nécessaire de faire beaucoup moins d'attente. Les appels SetPass sont des modifications apportées à vos shaders actuels, donc si vous avez de nombreux matériaux différents, vous aurez plusieurs appels SetPass, qui font également attendre le processeur un peu.

  6. Si votre scène est énorme et que votre temps processeur passe à parcourir tous les objets de la scène, essayez de réduire les objets de la scène. Regroupez certains arbres au lieu de les placer de manière individuelle et disposez-les comme un seul objet. Assurez-vous également que vous ne déplacez pas les arbres ou les objets parents, car cela oblige Unity à supprimer les transformations mises en cache et à recalculer l'arborescence de la scène entière.

  7. Si votre scène est énorme et que votre temps processeur va toujours principalement à Unity parcourant l'arborescence de la scène pour créer des listes pour rendre tous les objets, une chose que vous pourriez faire est de ne pas laisser Unity gérer le rendu. Si vous avez une meilleure façon de suivre les objets dessinables, vous pouvez utiliser CommandBuffer.DrawMeshInstanced ou Graphics.DrawMeshInstanced pour les dessiner à la main. Je n'entrerai pas dans les détails à ce sujet, car il est beaucoup plus avancé et implique l'élimination des objets vous-même et ainsi de suite.

Dans le cas où le traitement par lots statique ou dynamique ne fonctionne pas correctement (ce que vous pouvez voir en vérifiant le débogueur de trame), vous devez vous assurer que vous utilisez bien du matériel partagé et ne faites pas de copies du matériel par accident lors de l'appel meshRenderer.material. Appeler le .materialfera des copies de vos documents et rompra le traitement par lots. Utilisez .sharedMaterialplutôt.

Depuis Unity 5.6, vous pouvez utiliser le débogueur de trames pour déterminer pourquoi certains appels ne sont pas groupés avec les appels précédents. Cela sera très utile tout en essayant de réduire les appels de votre jeu.

L'instanciation présente les avantages suivants par rapport au traitement par lots statique / dynamique / personnalisé:

  • Utilise moins de mémoire car le maillage n'a pas besoin d'être dupliqué en mémoire
  • Peut utiliser plusieurs matériaux, seul un shader partagé est requis
  • Les objets peuvent être animés

De plus, il s'agit plutôt d'une nouveauté dans Unity et peut-être un peu instable. De plus, les GPU des appareils plus anciens ou mobiles ne prennent pas nécessairement en charge l'instanciation.


1. Oui, j'ai essayé les niveaux de détail, et à ma grande surprise, cela a en fait empiré. J'ai eu 3 variations des arbres chacune avec un nombre de sommets légèrement inférieur et un plan plat avec une image rendue de l'arbre dessus.
mr-matt

2. Tous mes arbres sont marqués comme statiques. Pour autant que je sache, cela permet le traitement par lots? Est-ce exact? Et quand vous parlez de matériel partagé, voulez-vous simplement dire que les arbres ont le même matériel?
mr-matt

3. Quelle sorte d'amélioration des performances cela apporterait-il réellement? Vaut-il la peine d'essayer?
mr-matt

1
2/3: D'après mon expérience, Unity ne fait pas très bien le batching dynamique et le batch statique augmente la taille de build, j'ai donc implémenté le batching moi-même et fait le maillage en combinant le temps de chargement. En utilisant cette technique, j'ai réussi à faire 2500 drawcalls pour les compresser en environ 300 drawcalls, ce qui était crucial pour notre jeu mobile où les drawcalls sont importants. Cela faisait peu de sommets inutiles à calculer (hors écran) mais ça valait le coup.
Lasse

2
tfw lorsque vous lisez une question sur les mauvaises performances avec les arbres et pas un seul mot sur le panneau d'affichage n'est perdu
Verrouillage numérique

13

Ok, donc le problème était simplement que je n'utilisais pas de GI en temps réel pré-calculé. Je l'ai vérifié il y a un petit moment, mais cela n'a pas eu d'effet immédiat, je l'ai donc laissé et oublié, et le temps de traitement de l'éclairage était si long aussi. Cependant, il vient de terminer le traitement, et ma parole, mon fps a augmenté de 3 fois. Donc pour l'instant, je vais en rester là et à l'avenir, assurez-vous que j'utilise toujours GI en temps réel pré-ordinateur!

S'il y a encore quelque chose que je pourrais faire pour améliorer davantage les performances, faites-le moi savoir, je vous en serais très reconnaissant!


2
Utilisez la suppression d'occlusion, même si votre scène est grande - envisagez de la diviser en morceaux, par exemple de nombreux terrains, et chargez-les et déchargez-les.
Candid Moon _Max_

Étant donné que vous semblez avoir résolu votre problème, vous devriez probablement accepter cette réponse.
Gnemlock
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.