De la texture plate au matériau intelligent
Le point de départ : une texture plate
Dans le studio, chaque matériau commençait par un nom et une couleur. La bibliothèque tenait une liste de presets — pierre, bois, métal, eau, énergie — chacun avec sa teinte et sa rugosité, choisis à la main, une fois pour toutes. C'est cohérent : tous les bâtiments partagent la même palette. Mais c'est figé : pour changer l'ambiance d'une scène, il fallait repasser sur chaque matériau un par un, ou écrire un nouveau preset.
Le vrai problème n'était pas la couleur, c'était le lien. Un prompt du genre « une forge sombre » parlait à la géométrie — bâtir, dimensionner, poser un toit — mais jamais aux murs eux-mêmes. Le matériau était une étiquette posée à la fin, pas une réponse à la demande.
Deux articles qui ont changé ma façon de voir
J'ai lu deux articles Blender, et je les ai conservés parce qu'ils disaient
chacun une moitié de la vérité. Le premier, Coding Blender Materials with
Nodes & Python de Jeremy Behreandt, montre comment les nœuds intégrés
de Blender se laissent grouper dans des fonctions utilitaires : comparaisons,
portes logiques, fract, smoothstep,
quantize, motifs en tuiles, shapers — et une fonction
arrange_nodes qui dispose le graphe en colonnes propres. Le
second, Beginner Blender : Materials & Shape Keys de Jared
Nielsen, ouvre une autre porte : attribuer des matériaux, puis animer des
objets simples avec des shape keys.
La leçon commune tient en une phrase : un matériau peut être un programme, pas une étiquette. Une couleur n'a pas de mémoire ; un motif construit réagit à ce qu'on lui demande.
Comment le prompt a gagné le droit de designer
Le studio partait déjà d'une phrase française : la demande passe par un
générateur de spec qui reconnaît les matériaux et les traits
(bois sombre, pierre vieillie, toit pentu). Si une phrase décidait déjà de la
forme, pourquoi pas du design ? On a ajouté une couche
(design_engine) qui lit les mêmes phrases et en tire une
direction : « sombre » → tonalité sombre, « runes qui
luisent » → émission, « métal brillant » → surface polie,
« damier » → motif en grille.
• « Un donjon sombre… avec des runes qui luisent en cyan » → tonalité
dark, emissive ≥ 0.6 ;
• « Une forge avec du métal brillant et des braises de feu, palette orange » →
roughness ≤ 0.3, metallic ≥ 0.6,
emissive ≥ 0.75 ;
• « Une maison claire ensoleillée avec un damier sur la façade » →
bright, motif grid.
Règle importante : la couche ne modifie que ce que la phrase décrit réellement. Le reste hérite de la direction en cours. Dire « plus sombre » ne change pas la palette qu'on n'a pas nommée.
Le chemin de la phrase jusqu'à l'écran
Pour qu'une phrase fasse naître un objet, tout suit le même chemin, comme une commande qui traverse une cuisine :
- la phrase (le prompt) devient une spec — une recette précise : la forme, les dimensions, les matériaux, et maintenant le design ;
- Blender lit la recette et sculpte la forme 3D, murs, toit, fenêtres ;
- l'export produit un GLB, le fichier que le jeu affiche, plus une photo d'aperçu pour montrer le résultat sans ouvrir Blender ;
- un pont (bridge) fait la navette entre la fenêtre où l'on tape sa phrase et la cuisine — il prend la commande, la porte, et rapporte le plat.
La lecture de la phrase se fait de deux façons : sur place, par des règles locales qui ne sortent jamais rien d'inventé ; ou, si une clé de modèle de langage est posée, par le modèle. Dans les deux cas, la phrase passe par la même spec, la même cuisine, le même plat — et on peut toujours rejouer la même commande pour obtenir la même chose.
Une section « design » qui vit dans la spec
Le résultat s'appelle la section design, et elle tient dans un
jeu de cases : ton, motif, palette, émission, rugosité, métal, détail.
Chaque case est bornée entre 0 et 1. Cette section persiste dans la spec :
le même prompt donne le même design — la reproductibilité est le contrat du
studio — et elle survit à la validation et au va-et-vient des
métadonnées. Ce qu'on a construit une fois est réutilisable.
node_lib : le matériau comme programme
Il restait à faire le pont vers Blender. La bibliothèque
(node_lib) est bâtie en deux couches. La première est pure : un
graphe descriptif de nœuds, sérialisable, qu'on teste sans avoir besoin de
Blender — plus des fonctions mathématiques réelles (fract, quantize,
smoothstep, distance de Minkowski) et un moteur de motifs qui dessine
anneaux, grille, vagues, points ou bruit. La seconde couche matérialise ce
graphe en un vrai matériau, sous Blender, quand on construit l'asset.
Quand la phrase demande un motif, le constructeur régénère les murs avec
cette bibliothèque au lieu de poser la couleur plate. Et la disposition des
nœuds reprend l'idée d'arrange_nodes de l'article : chaque nœud
reçoit sa colonne et sa ligne, de quoi lire le graphe comme un schéma et non
comme une pelote.
Ce qu'on n'a pas laissé faire : deviner
Une phrase écrite par un humain restera toujours partiellement ambiguë. La
règle du studio est restée la même que partout ailleurs : ne jamais
deviner. Ce que le prompt n'explique pas reste à sa valeur par défaut,
documentée. La vision à la demande se refuse à agir sans sa clé plutôt que
de simuler. Et chaque fonction est couverte par un test —
verifie(), une batterie maison — qui compte ses échecs et
n'accepte que zéro. L'automatisation n'est pas une excuse pour l'à-peu-près.
La limite que l'export nous rappelle
Toute l'histoire bute sur une frontière honnête. L'exporteur glTF ne peut pas cuire les nœuds procéduraux : un matériau construit arriverait blanc dans le moteur de rendu — une leçon déjà apprise ici. La bibliothèque contourne donc en générant une vraie texture image du motif, embarquée dans le fichier. Les groupes de nœuds complets, eux, demanderaient un bake, ou des shaders écrits directement côté moteur (Three.js). On sait où s'arrête la magie, et on le dit.
Et ensuite
Le second article garde une porte ouverte : les shape keys. Un bâtiment qui s'anime, une porte qui répond au vent — c'est la même méthode que d'habitude : une phrase, des paramètres bornés, et des tests qui prouvent. On peut aussi imaginer un transfert de style à partir d'une image — jamais pour remplacer la lecture, toujours pour l'alimenter.
Comment le vérifier vous-même
Le projet vit en local, et le test se lance en une ligne :
python3 world_builder/tests/test_unit.py. Il répond
« 0 échec(s) » ou il ne répond rien de bon. Si vous voulez voir un
monde 3D dont les murs changent d'âme selon la phrase qu'on lui souffle,
demandez la démonstration.