Performances et limitions de la 3D

Introduction

Godot suit une philosophie de performance équilibrée. Dans le monde de la performance, il y a toujours des compromis à faire, qui consistent à troquer la vitesse contre la facilité d’utilisation et la flexibilité. En voici quelques exemples pratiques :

  • Rendre efficacement des objets en grandes quantités est facile, mais lorsqu’une scène de grande taille doit être rendue, cela peut devenir inefficace. Pour résoudre ce problème, le calcul de visibilité doit être ajouté au rendu, ce qui rend le rendu moins efficace, mais, en même temps, moins d’objets sont rendus, ce qui améliore l’efficacité globale.
  • La configuration des propriétés de chaque matériaux pour chaque objet qui doit être rendu est également lente. Pour résoudre ce problème, les objets sont triés par matériaux afin de réduire les coûts, mais le tri a également un coût.
  • En physique 3D, une situation similaire se produit. Les meilleurs algorithmes pour manipuler de grandes quantités d’objets physiques (tels que SAP) sont lents à l’insertion/retrait d’objets et au ray-casting. Les algorithmes qui permettent une insertion, un retrait et un ray-casting plus rapides, ne seront pas en mesure de traiter autant d’objets actifs.

Et il y a bien d’autres exemples ! Les moteurs de jeu s’efforcent d’être généraliste par nature, donc les algorithmes équilibrés sont toujours préférés aux algorithmes qui peuvent être rapides dans certaines situations et lents dans d’autres… ou aux algorithmes qui sont rapides mais rendent l’utilisation plus difficile.

Godot n’est pas une exception et, bien qu’il soit conçu pour avoir des backends interchangeables pour différents algorithmes, ceux par défaut (ou plutôt les seuls qui sont là pour le moment) privilégient l’équilibre et la flexibilité par rapport à la performance.

Le but de ce tutoriel est d’expliquer comment tirer le maximum de performances de Godot.

Rendu

Le rendu 3D est l’un des domaines les plus difficiles pour obtenir des performances, c’est pourquoi cette section contient une liste de conseils.

Réutilisation des shaders et des matériaux

Le moteur de rendu Godot est un peu différent de ce qu’y existe ailleurs. Il est conçu pour minimiser autant que possible les changements d’état du GPU. :ref:`class_SpatialMaterial” fait un bon travail pour réutiliser les matériaux qui nécessitent des shaders similaires mais, si des shaders personnalisés sont utilisés, assurez-vous de les réutiliser autant que possible. Les priorités de Godot seront comme cela :

  • Réutilisation des matériaux : Moins il y a de matériaux différents dans la scène, plus le rendu sera rapide. Si une scène a une quantité énorme d’objets (des centaines ou des milliers), essayez de réutiliser les matériaux ou dans le pire des cas, utilisez des atlas.
  • Reusing Shaders : Si les matériaux ne peuvent pas être réutilisés, essayez au moins de réutiliser les shaders (ou des SpatialMaterials avec des paramètres différents mais avec la même configuration).

Si une scène a, par exemple, 20.000 objets avec 20.000 matériaux différents chacun, le rendu sera lent. Si la même scène contient 20.000 objets, mais n’utilise que 100 matériaux, le rendu sera d’une rapidité fulgurante.

Coût en pixel contre coût en sommet

Il est communément admis que plus le nombre de polygones d’un modèle est faible, plus il sera rendu rapidement. Ceci est vraiment relatif et dépend de nombreux facteurs.

Sur un PC et une console modernes, le coût du sommet est faible. A l’origine, les GPU ne rendaient que des triangles, donc tous les sommets :

  1. A dû être transformé par le CPU (y compris le clipping).
  2. Doit être envoyé à la mémoire du GPU depuis la RAM principale.

De nos jours, tout cela est géré à l’intérieur du GPU, donc les performances sont extrêmement élevées. Les artistes 3D ont généralement le mauvais sentiment au sujet de la performance polycount parce que les DCC 3D (tels que Blender, Max, etc.) ont besoin de garder la géométrie dans la mémoire CPU pour qu’elle puisse être éditée, réduisant ainsi la performance réelle. La vérité est qu’un modèle rendu par un moteur 3D est beaucoup plus optimal que la façon dont les DCC 3D les affichent.

Sur les appareils mobiles, l’histoire est différente. Les GPU PC et Console sont des monstres de force brute qui peuvent tirer autant d’électricité qu’ils en ont besoin du réseau électrique. Les GPU mobiles sont limités à une minuscule batterie, ils doivent donc être beaucoup plus économes en énergie.

Pour être plus efficaces, les GPU mobiles tentent d’éviter les overdraw. Cela signifie que le même pixel à l’écran est rendu plus d’une fois (comme avec le calcul de l’éclairage, etc.). Imaginez une ville avec plusieurs bâtiments, les GPU ne savent pas ce qui est visible et ce qui est caché jusqu’à ce qu’ils le dessinent. Une maison peut être dessinée, puis une autre maison devant elle (le rendu a eu lieu deux fois pour le même pixel !). Les GPU PC ne s’en soucient normalement pas beaucoup et se contentent d’ajouter des processeurs de pixels au hardware pour augmenter les performances (mais cela augmente aussi la consommation d’énergie).

Sur mobile, tirer plus de puissance n’est pas une option, donc une technique appelée « Tile Based Rendering » est utilisée (presque chaque hardware mobile en utilise une variante), qui divise l’écran en grille. Chaque cellule conserve la liste des triangles qui y sont dessinés et les trie par profondeur pour minimiser l”overdraw. Cette technique améliore les performances et réduit la consommation d’énergie, mais a un impact sur les performances des sommets. Par conséquent, moins de sommets et de triangles peuvent être traités pour le dessin.

Généralement, ce n’est pas si mal, mais il y a un cas important sur mobile qui doit être évité, qui est d’avoir de petits objets avec beaucoup de géométrie dans une petite partie de l’écran. Cela oblige les GPU mobiles à mettre beaucoup de pression sur une seule cellule de l’écran, ce qui diminue considérablement les performances (car toutes les autres cellules doivent attendre qu’elle soit terminée pour pouvoir afficher la trame).

Pour faire court, ne vous inquiétez pas trop des sommets sur mobile, mais évitez de concentrer les sommets sur de petites parties de l’écran. Si, par exemple, un personnage, un PNJ, un véhicule, etc. est éloigné (donc il semble minuscule), utilisez plutôt un modèle à plus petit niveau de détail (LOD).

Une situation supplémentaire où le coût du vertex doit être pris en compte est celle des objets qui ont un traitement supplémentaire par vertex, tels que :

  • Skinning (animation squelettique)
  • Morphs (clés de forme)
  • Objets éclairés par les sommets (communs sur mobile)

Compression de texture

Godot propose de compresser les textures des modèles 3D lors de l’importation (compression VRAM). La compression de la RAM vidéo n’est pas aussi efficace en taille que le PNG ou le JPG lorsqu’elle est stockée, mais augmente considérablement les performances lors du dessin.

En effet, l’objectif principal de la compression de texture est la réduction de la bande passante entre la mémoire et le GPU.

En 3D, les formes des objets dépendent plus de la géométrie que de la texture, la compression n’est donc généralement pas perceptible. En 2D, la compression dépend davantage des formes à l’intérieur des textures, de sorte que les artefacts résultant de la compression 2D sont plus visibles.

En guise d’avertissement, la plupart des appareils Android ne prennent pas en charge la compression de texture des textures avec transparence (seulement opaque), gardez ceci à l’esprit.

Objets transparents

Comme mentionné précédemment, Godot trie les objets par matériau et par shader pour améliorer les performances. Toutefois, cela ne peut pas être fait sur des objets transparents. Les objets transparents sont rendus de l’arrière vers l’avant pour se fondre avec ce qui se trouve derrière. Par conséquent, essayez de réduire au minimum les objets transparents ! Si un objet a une petite section avec transparence, essayez de faire de cette section un matériau séparé.

Niveau de détail (LOD)

Comme mentionné précédemment, l’utilisation d’objets avec moins de sommets peut améliorer les performances dans certains cas. Godot a un système simple pour changer le niveau de détail, GeometryInstance les objets basés ont une plage de visibilité qui peut être définie. Avoir plusieurs objets GeometryInstance dans différentes plages fonctionne comme LOD.

Utiliser l’instanciation (MultiMesh)

Si plusieurs objets identiques doivent être dessinés au même endroit ou à proximité, essayez d’utiliser MultiMesh. MultiMesh permet de dessiner des dizaines de milliers d’objets à très faible coût de performance, ce qui le rend idéal pour les troupeaux, l’herbe, les particules, etc.

Préparation de l’éclairage

Les petites lumières ne sont généralement pas un problème de performance. Les ombres un peu plus. En général, si plusieurs lumières doivent affecter une scène, il est idéal de les préparer (Baked lightmaps). La préparation peut également améliorer la qualité de la scène en ajoutant des rebonds de lumière indirecte.

Si vous travaillez sur mobile, il est recommandé de préparer la texture, car cette méthode est encore plus rapide.