======Générer un matériau======
Je n'explique pas ici la création de matériaux dans Maya, il faudrait beaucoup plus de pages et beaucoup plus de temps, je donne seulement les informations à mon sens nécessaire à la bonne compréhension de la procédure. Avant de se lancer tête baissée dans des lignes de code, il est nécessaire de comprendre certaines notions et comment fonctionne Maya.
=====Matériau? Shader? Node?=====
Ouvrons l'hypershade en allant dans //Window -> Rendering Editor -> Hypershade// ou en cliquant sur son icône située à gauche{{:tutos:python:generer_materiau:hypershade_button.png}}, et créons un matériau blinn en cliquant sur "Blinn" dans la liste de gauche. Deux boites "blinn1" apparaissent, une dans //Materials// l'autre dans //Work Area// :
[{{ articles:mel-python:generer_materiau:hypershade_blinn.png?510 |Création d'un Blinn dans l'Hypershade}}]
En cliquant sur le bouton {{:tutos:python:generer_materiau:inout_button.png}} après avoir sélectionné "blinn1" nous affichons plus de détails dans l'espace de travail :
[{{ articles:mel-python:generer_materiau:hypershade_blinnHierarchy.png?510 |Le matériau au complet}}]
Ces boites sont ce que l'on appelle des "nodes", ou "nœuds" : elles représentent des objets ou fonctions précises de Maya, pouvant transformer un signal. En d'autres termes, chaque node permet de faire une action précise : inverse ça, réduis ça, crée une image... Ces boites contiennent donc un certain nombre de paramètres que l'on peut modifier : ce sont les attributs, que l'on voit en ouvrant l'//Attribute Editor// (//Ctrl+A//).
Ce qui est superbe, c'est que toutes ces petites boites peuvent se connecter et ainsi combiner leurs effets : ici le premier node est relié au second. L'hypergraphe se lit généralement de gauche à droite : le signal part du premier node à gauche et se modifie au fil des connexions en suivant les flèches.
Les deux nodes que nous avons sous les yeux sont très importants : ils sont la base nécessaire à la création d'un matériau.
* Le premier est le //shading node//, basé sur un [[wp>Shader]] : un shader est un algorithme qui permet de simuler la manière dont un matériau se comporte à la lumière. Il définit ainsi les propriétés physiques du matériau : sa couleur, sa transparence, son spéculaire, etc... Il existe différents algorithmes de shaders, dont les principaux sont : [[wp>Phong_shading|le Phong]], [[wp>Blinn|le Blinn]] et [[wp>Lambertian_reflectance|le Lambert]] (ils portent tous le nom de leur mathématicien de père). Le Blinn étant une amélioration du Phong, lui-même grosso-modo une amélioration du Lambert, n'hésitez pas à l'utiliser plutôt qu'un autre.
* Le second est le shading group: c'est un simple groupe contenant le Shading Node. Il est nécessaire car sert à appliquer le matériau à un objet 3D : un objet lié à ce groupe utilisera son matériau.
Le matériau est définis techniquement par l'ensemble des nodes qui le composent, et visuellement par le résultat de ces nodes. Un matériau n'existe que grâce à un shader, qui est le nœud central : shader et matériau sont intrinsèquement liés.
Exemple simple :
[{{ articles:mel-python:generer_materiau:nodes_simples.png |Un matériau simple}}]
Ici le premier node est une image procédurale : une image générée par une fonction (procédure) mathématique. Ce node fabrique ainsi une image aléatoire selon une procédure fractale, ce qui donne cet aspect typique. Il existe d'autres procédures, d'autres algorithmes listés à gauche dans //2D textures// pouvant générer des choses très différentes, allant du bruit au tissus. Ce node est relié à notre shader : la couleur générée est envoyée dans la couleur du shader. Le matériau est donc simplement une surface ayant pour couleur cette image fractale.
[{{ articles:mel-python:generer_materiau:nodes_complex.png?510 |Un matériau un peu plus complexe}}]
* Un //node// est une fonction permettant de créer ou de transformer des données. Il est représenté par une petite boite dans l'espace de travail de l'Hypershade.
* Un //shader// est un algorithme calculant l'effet de la lumière sur une surface.
* Un //shading node// est un node basé sur un shader, rassemblant toutes les propriétés d'une surface.
* Un //shading group// regroupe le Shading Node et les objet auxquels il s'applique. Il permet d'appliquer le matériau à un/des objet.
* Un //matériau// est visuellement le résultat d'un réseau de nodes, techniquement le réseau de nodes lui-même.
=====Codons=====
Nous allons dans un premier temps créer un matériau de base, basé sur un shader Blinn.
====Créons====
Comme on l'a vu précédemment un matériau fonctionnel contiens au minimum un Shading Node et un Shading Group.
Pour créer un Shading Group, rien de plus simple :
import maya.cmds as mel
mel.sets(name='tomateShaderSG', renderable=True, empty=True ) #crée un Shading Group vide
Faites attention à bien nommer tout ce que vous créez de manière reconnaissable : par exemple pour le Shading Group, Maya ajoute "SG" au nom du shader. De mon côté je procède ainsi : je prévois d'avoir un objet "tomate", son Shading Node sera "tomateShader" et son Shading Group "tomateShaderSG". Cela permet, dans le cas ou tout est variable, de s'y retrouver facilement.
Créons maintenant notre Shading Node :
import maya.cmds as mel
mel.sets(name='tomateShaderSG', renderable=True, empty=True ) #crée un Shading Group vide
mel.shadingNode('blinn', name='tomateShader', asShader=True ) # crée un Shading Node de type Blinn
Il ne nous reste plus qu'à les relier :
import maya.cmds as mel
mel.sets(name='tomateShaderSG', renderable=True, empty=True ) #crée un Shading Group vide
mel.shadingNode('blinn', name='tomateShader', asShader=True ) # crée un Shading Node de type Blinn
mel.surfaceShaderList('tomateShader', add='tomateShaderSG' ) #ajoute le Node au Shading Group
Nous pouvons lancer le script et constater la création de notre matériau dans l'Hypershade.
====Assignons====
Pour assigner notre super matériau à un objet, là aussi rien de plus simple.
Créons d'abord notre objet :
mel.polySphere(name='tomate') #création d'une sphère
Puis lions notre objet au Shading Group (pas au Shading Node !) :
mel.polySphere(name='tomate') #création d'une sphère
sets('tomate', forceElement='tomateShaderSG') #attribuer le Shading Group à un objet
Ce qui donne :
import maya.cmds as mel
#création du shader (node et group)
mel.sets(name='tomateShaderSG', renderable=True, empty=True )
mel.shadingNode('blinn', name='tomateShader', asShader=True )
mel.surfaceShaderList('tomateShader', add='tomateShaderSG' )
#attribution à un objet
mel.polySphere(name='tomate')
mel.sets('tomate', forceElement='tomateShaderSG')
[{{ articles:mel-python:generer_materiau:tomateShader_base.png |Notre "tomateShader" dans l'Hypershade}}]
====Modifions====
Tout comme la position d'un objet ou sa taille sont des attributs de l'objet, les paramètres des nodes sont des attributs, et on les manipule de la même manière : avec //setAttr()//.
Modifions l'attribut diffuse (cf. [[wp>Diffuse reflection]]) :
import maya.cmds as mel
#création du shader (node et group)
mel.sets(name='tomateShaderSG', renderable=True, empty=True )
mel.shadingNode('blinn', name='tomateShader', asShader=True )
mel.surfaceShaderList('tomateShader', add='tomateShaderSG' )
#modification du shader
mel.setAttr('tomateShader.diffuse', 0.4) #met l'attribut diffuse à 0.4
#attribution à un objet
mel.polySphere(name='tomate')
mel.sets('tomate', forceElement='tomateShaderSG')
Nous pouvons placer cette ligne, donc modifier notre matériau, n'importe ou __après__ la création du Shading Node : avant de l'assigner à un objet, après...
[{{ articles:mel-python:generer_materiau:tomateShader_diffuse.png? |Notre "tomateShader" avec une réflexion diffuse réduite}}]
Notre matériau semble beaucoup plus foncé : normal, nous venons de réduire sa réflexion diffuse. Qui dit moins de réflexion dis moins de lumière renvoyée jusqu'à notre œil et donc un objet plus sombre.
Essayons de changer sa couleur.
Nous venons de modifier un attribut simple, demandant une seule valeur. Hors un très grand nombre d'attributs sont définis par une couleur, donc trois valeurs : R, G, B. La syntaxe change donc un peu dans ce cas :
import maya.cmds as mel
#création du shader (node et group)
mel.sets(name='tomateShaderSG', renderable=True, empty=True )
mel.shadingNode('blinn', name='tomateShader', asShader=True )
mel.surfaceShaderList('tomateShader', add='tomateShaderSG' )
#modification du shader
mel.setAttr('tomateShader.color', 1, 0, 0, type='double3') #change la couleur à (1,0,0) donc rouge
#attribution à un objet
mel.polySphere(name='tomate')
mel.sets('tomate', forceElement='tomateShaderSG')
Nous faisons donc suivre le nom de l'attribut par trois valeurs et lui précisons qu'il doit bien en récupérer trois.
[{{ articles:mel-python:generer_materiau:tomateShader_color.png |Notre "tomateShader" avec une couleur différente}}]
Modification d'un attribut "nombre" :
mel.setAttr('nomShader.attribut', valeur)
Modification d'un attribut "couleur" :
mel.setAttr('nomShader.attribut', R, G, B, type='double3')
---------------
Si vous avez des questions, des remarques, des suggestions, n'hésitez pas à m'en faire part.
~~DISCUSSION~~