Note : Dans ce billet, le mot « rendu » fait référence au rendu temps-réel, sur GPU. On y est pas forcément habitué, alors je préfère le préciser. :reflechi:

Qu’est-ce que la consolidation ?

On va s’éviter un cours sur le fonctionnement d’un GPU, mais en très gros, un GPU ne peut « rendre » qu’un seul matériau à la fois. Quand il y a deux matériaux, il rend deux fois avant d’afficher l’image sur le moniteur. Un rendu est appelé un draw call, il peut donc y avoir plusieurs draw call pour une image affichée.

Dans le cadre d’un GPU, un matériau est à comprendre comme « programme qui calcule un pixel donné » ; souvent la surface d’une géométrie en fonction de sa normale, d’une source de lumière, etc. Le terme technique est shader. Les inputs d’un objet (la normale, les textures) ne font pas partie du shader, ils sont définis à l’objet et sont passés au shader juste avant son exécution, au moment du calcul du pixel. Changer de shader est assez couteux, car il nécessite de redéfinir une bonne partie du pipeline du GPU : On change le programme à exécuter (shader), et les blocs d’entrées et de sortie de ce programme (le terme technique est device state). Ce fonctionnement est spécifique au rasterizer GPU, on pourrait presque parler de contrainte matériel. Ce problème n’existe pas en path tracing (disons qu’on a d’autres problèmes :pasClasse: ).

Ce qu’on appelle la « consolidation », c’est le fait de regrouper le rendu des objets utilisant un même shader, afin d’utiliser le minimum de draw call ; on rend une seule fois beaucoup d’objets.

C’est comme ça que fonctionnent les jeux vidéos : Ils ont assez peu de shaders et chaque objet dispose de ses paramètres propres. L’art du rendu temps-réel consiste à faire le moins de draw call possible en jouant avec les paramètres par objet et les buffers de rendu. Je vous invite à lire la présentation The devil is in the details sur le pipeline de rendu de Doom 2016, qui utilise une centaine de shaders, pas plus. :jdicajdirien:

Maya dans tout ça

Dans ses premières années, avant le Viewport 2.0, Maya affichait chaque nœud de shape indépendamment. Il y avait (quasiment) autant de draw call que de nœud de shape à afficher. C’est pour ça qu’il était facile d’écrire ses propres locators en OpenGL. C’était surtout inefficace, car plus il y avait de nœuds, plus il y avait de draw call, et c’est là qu’intervient le Viewport 2.0, pour unifier (entre autres) l’ordre dans lequel les choses sont affichées.

VP2 fonctionne comme une base de donnée dédié à l’affichage. Fini la belle époque où l’on pouvait afficher n’importe quoi grâce à des appels OpenGL personnalisés. Avec VP2 on met des choses à afficher (appelées Render Items) dans une boite dédiée et il s’occupe du reste ; c’est lui qui contrôle de pipeline d’affichage.

Plus de détails sur VP2

La période de transition entre le « Viewport Legacy » et le « Viewport 2.0 » a été longue, et ce dernier resta longtemps optionnel. Comme vous le devinez, les développeurs de plugins tiers ont dû recoder la partie graphique de leur plugin pour la rendre compatible VP2.

C’est pour les aider qu’Autodesk sortie en 2017 une série de documents « Viewport 2.0 API Porting Guide » :

La première chose qui vient en tête quand on lit la table des matières de ces documents, c’est à quel point ils pourraient vous aider à briller en soirée, entre une citation de Proudhon et Hanouna. Votre serviteur a essayé, ça ne fonctionne pas. Ces documents n’aident en rien, le problème ne vient donc pas de là. :petrus:

Non, ce que je vous propose c’est une traduction partielle d’une section du premier document, qui concerne spécifiquement la consolidation. Section 3.6 : Categorization and Consolidation, sous section Consolidation (page 9) :

Les Render Items sont catégorisés en séries de listes (appelé buckets), suivant qu’ils soient persistants ou transitoires, ainsi que d’autres paramètres d’affichage. […] La catégorisation peut être utilisée pour regrouper les items ayant des propriétés d’affichage similaires, ce qui peut améliorer les performances en évitant des changements de device states inutiles.

La consolidation est une fonctionnalité de VP2 utilisée pour diminuer le « problème des petits paquets » (small batch problem) : C’est-à-dire lorsque le coût des appels systèmes requis par la préparation et l’envoi d’énormément de petits paquets de géométries entraîne des pertes de performances importantes. Pour aider à résoudre ce problème, les Render Items peuvent être consolidés (fusionnés). Notez que, par conséquent, les Render Items originellement créés peuvent ne pas être ceux utilisés au rendu. Par défaut, VP2 utilise un mode hybride, combinant la consolidation statique traditionnelle et la consolidation multi-draw.

  • La consolidation statique traditionnelle améliore la vitesse du rendu des shapes totallement statiques.
  • La consolidation multi-draw améliore la vitesse du rendu des shapes pour les animations matricielles (c-à-d. les translation/rotation/scale) et statiques, cependant, il nécessite OpenGL Core Profile et des pilotes récents. […]
  • Le mode hybride permet à certains Render Items de basculer dynamiquement entre les deux modes. Par exemple, lorsqu’une shape statique démarre une animation matricielle, ses Render Items seront sortis de la consolidation statique traditionnelle et reconsidérés, pour une consolidation multi-draw.

Note : Le multi-draw, c’est le fait de dessiner un même objet plusieurs fois, mais avec des transforms différents, en un seul rendu.

Je m’arrête ici, le document continue, et nécessite une compréhension un peu plus poussée de ce qu’est un Render Item.

Ce qu’en dit la documentation

Comparé aux documents dédiés aux développeurs, la documentation n’entre pas énormément dans les détails, mais donne une idée du problème que l’option Consolidate World cherche à résoudre. Voici la traduction :

Cette option essaie de combiner les caches de géométries des shapes utilisant des matériaux identiques. Cela peut drastiquement améliorer les performances de nombreuses scènes, en échange d’une utilisation mémoire plus importante.

Quand il combine les géométries, Consolidate World déplace les vertices de plusieurs objets dans un nouvel espace local (object-space) partagé. Donc si votre shader de plug-in s’appuie sur les coordonnées locales d’un objet, Consolidate World cassera ces coordonnées et votre shader risque de ne pas s’afficher correctement (Ndt : Plus d’informations sur la page Troubleshoot working with CgFX shaders, le tuto GLSL, ainsi que celle sur la sémantique des shaders).

Pour utiliser cette fonction, les normales des vertices doivent être renormalisées. Par conséquent, les matériaux n’utilisant pas de normales de longueur unitaire ne sont pas compatibles avec Consolidate World.

Quand un objet change/est déformé, il est non-consolidé. Il est ensuite reconsolidé s’il reste inchangé pendant quelques frames. L’option Consolidate World peut donc être à l’origine d’un objet s’affichant différemment dans le viewport peu de temps après avoir été modifié ou désélectionné. Si cela vous gêne, désactiver cette option.

Astuce : Si votre Maya devient instable, essayez de désactiver cette option.

Important : Certaines opérations subissent de légers retards quand cette option est activée.

Voilà pour la seconde traduction. On note une confiance assez relative dans leur feature. :seSentCon:

La section Optimize Viewport 2.0 de la documentation ajoute des informations intéressantes :

L’option Consolidate World améliore les performances en combinant les géométries de tous les objets dans le champ de la caméra afin de réduire le nombre d’appels au GPU. Cette option est activée par défaut.

Pour profiter au maximum de Consolidate World, mutualisez les shaders autant que possible, en particulier sur les petits objets statiques. Vous pouvez le faire en sélectionnant File > Optimize Scene Size et activer l’option Remove duplicate: Shading networks. Pour ne visualiser qu’un seul matériau dans votre viewport et ainsi bénéficier au maximum de Consolidate World, vous pouvez activer Shading > Use Default Material dans le menu Panel. Si les matériaux ne sont pas nécessaires à votre workflow, cela améliore considérablement les performances dans les scènes lentes.

Remarque : L’activation de Consolidate World augmente l’utilisation mémoire du GPU. Voir Manage GPU memory for Viewport 2.0 pour plus d’informations.

C’était la dernière traduction de ce billet ! :redface:

Notez que le frustrum de la caméra semble être pris en compte par la consolidation.

Résumé

S’il fallait résumer très brièvement, la consolidation c’est le fait d’assembler toutes les géométries pouvant être rendu ensemble, en une seule fois, afin de générer le minimum de draw call.

Par exemple, en admettant que nous ayons deux objets statiques (des plans), utilisant le même matériau :

En haut, il y a deux tableaux de points (S0 et S1) pour deux objets. Ils sont donc affichés séparément, où, au mieux, en multi-draw. Si on combine ces deux objets en un seul tableau de points (S0) on peut afficher les surfaces en un seul rendu, comme s’il n’y avait bien qu’un seul objet.

Le schéma ci-dessus ne montre que les indices des points, mais cette réévaluation doit se faire également pour le tableau de positions, UVs, normales, etc. ; c’est un nouvel objet qui est créé dans le buffer du GPU.

Ça c’est pour la théorie. :dentcasse:

Le vrai monde

On imagine facilement que ce genre de mécanisme fonctionne assez bien en jeu vidéo, qui détermine à l’avance si les objets sont statiques ou non. :gne:

En pratique, la liberté laissée par notre logiciel chéri peut mettre à mal ce mécanisme qui peut se retrouver sur-sollicité, en particulier en animation ; plusieurs personnages animés en blocking + translate, caméra et objets qui bougent, puis s’arrêtent, etc. On comprend assez vite que l’approche consistant à organiser le rendu du GPU suivant qu’un objet est statique, transformé ou déformé peut être mise en défaut avec le travail d’animation, où le contenu de la scène est réévalué à chaque frame.

Le réindexage en blocs de rendu peut être constant si bien que, malgré que Consolidate World devrait en principe toujours fonctionner (il est activé par défaut), il n’est pas rare qu’il se retrouve être à l’origine de nombreux crash. Parfois c’est le pilote qui est responsable, parfois c’est Maya. J’imagine que le multithreading et l’asynchronie rendent cette feature complexe à maintenir dans un logiciel comme Maya.

Comme vous l’avez remarqué plus haut, la situation est telle que la documentation recommande carrément de la désactiver « en cas d’instabilité ». :bete:

Le doute

À ce stade, il est difficile d’affirmer quoi que ce soit sur les crashs rencontrés en animation. En effet il n’est pas simple de déterminer la raison exacte d’un crash, en particulier ceux liés à l’affichage. Ces derniers sont assez difficiles à isoler. Quand ils le sont, ils peuvent être corrigés sur une version, puis un autre problème apparait, et il suffit, une fois encore de désactiver Consolidate World pour que le problème disparaisse…

Je reviens sur mon hypothèse celons laquelle cette feature est complexe à maintenir correctement dans un logiciel comme Maya, dont une partie de l’affichage est gérée de façon asynchrone. Je pense que Consolidate World restera une option dont le fonctionnement sera aléatoire en animation, d’où mon conseil de la désactiver en production ; en particulier en animation, où le temps de l’animateur est précieux.

Voici quelques exemples trouvés ici et là qui laissent entendre que Consolidate World est la raison de leur problème. Si on ne peut pas affirmer que la consolidation effectivement est l’origine du problème, l’accumulation des cas fait peser des doutes sur la stabilité de cette option.

Matthew's Animation Antics - Software Problems :

As the rigs got more complex throughout the animation process it became more apparent that more had to be done to speed up the scenes. Natasha found that turning off “consolidate world” option in the Viewport 2.0 options prevented any further crashes.

Reddit - disappearing texture problem

Even though you fixed the problem, good chance it has something to do with Viewport 2.0's "Consolidate World" feature. Sometimes I get texture issues in the Viewport and I've narrowed it down in the past to that.

Change-log Maya 2018 :

- Consolidate World breaks geometry override with custom resource handles
[…]
- Crash when selecting node with custom resource handles with consolidate world on

My bet is one the performance options in the Viewport 2 option dialog, such as Vertex Cache and Consolidate World. I suspect there might be some refreshing going on.

Malcolm 2.0 Public Version :

Next try: Viewport, Renderer>Viewport 2.0 Options, Turn off Consolidate World.

My scene has crashed 5 times in the last hour, anything i could look to troubleshoot it?

Meanwhile, one of our Rigger found a surprising workaround : In the VP2 performance settings, disable the "Consolidate World" option

Mimic :

In Maya 2018, consolidation is disabled to facilitate this shader. It shouldn't affect anything of value, you probably don't even know what it is. But if you'd rather it didn't do that, untick the "Maya 2018 Consolidate World Fix" in the Ragdoll Preferences and reload the plug-in or restart Maya.

Conclusion

Si vous avez des crashs en animation, désactivez Consolidate World et croisez les doigts.

:marioCours: