La variation, un concept flou

S’il y a bien un truc difficile à exprimer correctement en production, c’est le concept de « variation ». J’ai tendance à éviter d’utiliser ce mot en réunion, car il dispose d’un pouvoir de confusion assez important (au prorata du nombre de personnes dans la discussion). Et si la confusion n’est pas instantanée (chacun comprenant ce qu’il veut) elle le devient dès que le mécanisme entre concrètement dans le pipeline et que les départements commencent à interagir avec lui. C’est à ce moment-là que tout le monde comprend que personne ne voyait la même chose. :tuComprendRien:

Mais pourquoi ? D’où vient le problème ? :reflexionIntense:

Chacun peut y aller de sa petite théorie, la mienne étant qu’il y a un écart énorme entre l’idée de « variations », qui est un concept très large, et sa réalité en production qui est contrainte par des choses très concrètes, elles-mêmes dépendante de ce qu’on cherche à faire varier. :redface:

Intégrer un concept de variation nécessite de se poser pas-mal de questions. En vrac :

Si j’ai « toto » et sa variation « sale ». Est-ce que « sale » est une surcouche/override (et donc dépends) de « toto » ? Si oui, quelles sont les implications pour « toto » ? Sa hiérarchie, ses attributs, ses tags, etc. Et si ces choses sont modifiées, comment réagit la variation ? N’est-ce pas à la variation de s’ajuster à « toto » et non l’inverse ? Y a-t-il un risque, une fois en production qu’un plan soit fait avec une version de « toto » et de « sale », mais que la nouvelle version de « toto » casse la variation ? Comment gérer ça ? Dois-je bloquer les versions une fois un plan commencé ? OK, mais si la gestion du blocage des versions au plan est trop chronophage pour les gens qui doivent maintenant constamment mettre des choses à jours des choses, car on est en flux tendu, alors qu’avant, ils ne se posaient pas la question, est-ce que le coût de gestion des variations n’est pas en trains de beaucoup trop complexifier le pipeline ?

Finalement, pourquoi s’embêter à gérer « toto » et « sale » de façon indépendante, ne serait-il pas plus simple de combiner « toto » et « sale » pour avoir un asset « toto_sale » et en faire ce que je veux ? Mais si les UVs de base de « toto » changent avec sa texture, ai-je un mécanisme de propagation des modifications ? Mais est-ce que ce n’est pas trop lourd si j’ai une variation « propre » qui apparaît…

Il est impossible de trouver un système qui permet de résoudre tous ces problèmes d’un coup, et ce n’est pas le but. :cayMal:

Ce qu’il faut comprendre, c’est que si vous n’êtes pas au clair sur ce que le système que vous mettez en place pourra faire ou non, vous prenez le risque de mettre des gens en difficulté (en imposant un suivi supplémentaire aux équipes). :triste:

Mon humble conseil est donc de ne jamais utiliser le terme « variation » sans y coller un terme caractérisant « son implémentation technique » (une expression pompeuse pour dire « la méthode utilisée dans le logiciel »), par exemple :

  • Variation par tag.
  • Variation par set.
  • Variation par groupe.
  • Variation par attribut.
  • Variation par PrimVar.
  • Variation par tag d’asset.
  • Variation par namespace.
  • etc.

Vous remarquez qu’il n’y a pas un, mais des mécanismes de variations. En utilisant de tels termes, vous imposerez implicitement à tout le monde de s’accorder sur la méthode et vous simplifierez pas-mal de discussions avec et entre les superviseurs. :titille:

Gardez à l’esprit qu’il n’est pas utile que tout le monde comprenne toutes les subtilités de ces mécanismes, juste que les gens communiquent avec des termes différents pour désigner des choses différentes.

Fini le pâté de texte, maintenant on rentre dans le vif du sujet ! :enerve:

Présentation de la méthode par tag

C’est sûrement la plus simple, et celle que vous avez instinctivement en tête quand vous utilisez Guerilla, tant les tags y sont omniprésents. Pourtant, vous allez voir que même dans ce cas il y a plusieurs façons de les utiliser. :joue:

À l’intérieur du RenderGraph

Vous pouvez embrancher votre lookdev directement dans le RenderGraph de lookdev, via l’utilisation d’un tag :

Variation par tag dans un RenderGraph Guerilla

Ici, « var1 » et « var2 » applique un override sur le shader « Surface2 ».

Via un RenderGraph dédié

L’idée est d’avoir un RenderGraph s’appliquant après celui du lookdev (attribut order plus élevé) et dédié à l’override d’attributs propres à cette variation :

Variation par RenderGraph dans Guerilla

Remarquez comme on a juste découpé le RenderGraph précédent.

Ensuite, on configure les deux RenderGraph (de droite) pour qu’ils s’appliquent sur leur tag respectif (et un order suivant celui du RenderGraph de base) :

Au passage, en faisant ceci, c’est le RenderGraph qui défini le tag sur lequel il s’applique (« var1 » sur l’image), il est donc inutile d’utiliser un nœud de tag (« var1 » ou « var2 ») à l’intérieur du RenderGraph.

S’arrêter à ce stade pose pas mal de problèmes :

Ici, j’assigne uniquement le tag de variation (« var1 ») au RenderGraph, mais ça veut dire que si deux assets ont ce tag, ils passeront tous les deux dans ce RenderGraph. Ça veut dire ce RenderGraph devra gérer la « var1 » d’assets très différents (chaise, maison, personnages, montagnes) et que ça fonctionne tout le temps. Même si cela peut être une méthode en soit (si on souhaite utiliser cette méthode de façon générale, sur son pipeline) il y a peu de chance que ce soit vraiment ce que vous souhaitiez faire. En effet, overrider globalement des attributs artistique de lookdev, c’est le risque de se retrouver avec une chaîne de RenderGraphs qui applique trop des choses. :perplex:

Au lieu d’assigner un seul tag « var1 » à ce RenderGraph, on peut également lui coller un second tag, lié à l’asset. Dans le cas de l’asset chaise, on aurait : « asset_chaise, var1 ». Faire cela résout notre problème d’assignation trop « large », mais implique que le reste de votre pipeline passe par l’assignation par tag. Si c’est ce que vous voulez, tant mieux. Mais sachez que vous n’aurez pas toujours cette option (si votre pipeline utilise « prefix » où « reference », par exemple).

La première méthode (À l’intérieur du RenderGraph) à l’avantage de supporter toutes les méthodes d’assignation de RenderGraph :laClasse: , mais peut devenir limitante si vos variations sont importantes.

Un nœud SetTags, pour les chambouler tous !

J’en profite pour dire qu’il existe un nœud SetTags qui permet d’assigner dynamiquement des tags à des objets (via des regex dans des Path, par exemple). La seule contrainte étant que ce nœud doit être dans un RenderGraph précédent le RenderGraph utilisant le tag :

Si un RenderGraph « A » utilise le nœud SetTags pour appliquer le tag « toto » sur des objets, ce tag ne pourra être utilisé que dans RendreGraph « B », dont l’attribut order est plus grand que celui de « A ». On aurait donc une chaîne de RenderGraph ressemblant à ça :

L’ubiquité des tags dans Guerilla fait qu’un tel nœud offre des possibilités intéressantes, mais gardez à l’esprit que trouver une méthode qui fonctionne, ce n’est que 50 % de la réflexion. Il vous faut identifier ce que vous ne pouvez pas faire et estimer si c’est pénalisant. :neutral:

Ce besoin de passer par deux RenderGraph n’est pas une contrainte négligeable, en particulier quand plusieurs départements relatifs au rendu (lookdev, lighting, compo) veulent aussi pouvoir le faire.

La limitation de la méthode par tag

Nous avons vu plusieurs façons d’utiliser les tags pour faire des variations de lookdev. L’objectif n’était pas tant de vous apprendre des choses sous Guerilla que de vous ouvrir aux questions que pose l’organisation d’un workflow de variations. :bete:

Ces mécanismes de gestion des tags ont en commun de s’appuyer sur le SceneGraph (la Node List), c.-à-d. sur les nœuds de la scène. Si c’est cette particularité qui donne de la flexibilité au système (en permettant des modifications directement dans Guerilla), cela devient limitant quand on cherche à travailler « sous » l’objet. Par exemple, pour un système de particule dont on souhaite faire varier les instances et leur lookdev.

Cela pourra faire l’objet d’un billet dédié… :jdicajdirien:

Les petits malins, adeptes de Houdini, pourraient être tentés de sortir autant de fichier Alembic qu’il y a de variation, chaque Alembic ne contenant que les objets d’une seule variation et d’appliquer un tag sur chacune des références. Ça fonctionne (je confirme ! :aupoil: ), mais c’est un cas classique de « contorsion du pipeline » : Ont fait rentrer un nouveau type de problèmes en se servant d’un mécanisme existant et fiable, mais de façon peu élégante. Ce genre de bricolage peut être courant sur des gros pipelines de production (avec parfois, des outils dédiés !).

En espérant vous avoir donné des éléments de réflexion sur le sujet. :youplaBoum:

À bientôt !

:marioCours: