Sommaire

:longBar:

A savoir

Comme d'habitude avec TotoDesk, c'est mal implémenté, caché, etc... Cette solution n'est donc pas à privilégier sur de la prod pour l'instant (m'est d'avis).

Je vous invite à aller voir ce billet sur CGTalk pour voir comment il a fallu "déterrer" (c'est presque le bon mot) ces nodes.

Pour résumé, la dll est disponible dans les dossiers de mental ray:

C:\Program Files\Autodesk\Maya2012\mentalray\lib

mental_ray_3_9_Les_User_Data_Shaders_001.png

Mais il ne sont pas définit dans les .mi (fichiers qui sont les déclarations des shaders pour que mental ray sache ce qu'il y a dans la dll).

Donc il faut les ajouter à la mains. :baffed:

Ne vous embêtez pas, Je vous donne mon fichier.

Télécharger userdata.zip

Placez le fichier userData.mi dans:

C:\Program Files\Autodesk\Maya2012\mentalray\include

Et lancez Maya 2012.

Allez dans le Shader Manager:

mental_ray_3_9_Les_User_Data_Shaders_002.png

Vous voyez votre userData.mi

mental_ray_3_9_Les_User_Data_Shaders_003.png

Cliquez sur le "i" vert:

mental_ray_3_9_Les_User_Data_Shaders_004.png

Ça en fait des nodes!

Rassurez vous, dans la pratique on en utilise assez peu. :sourit:

Autodesk corrigera surement ce soucis lors de son prochain service pack. Il vaudra mieux supprimer ce fichier (userData.mi) avant d'installer la mise à jour. :)

:longBar:

La feature

Voici une courte description qui résume bien le principe:

New Shader Package

A new shader package userdata is now part of mental ray. It supports special workflows with large scene, where dynamic attributes attached to scene elements can indirectly drive parameters of the assigned shader(s).

Si vous en voulez plus, je vous invite à aller directement lire les quelques lignes de la doc:

http://docs.autodesk.com/MENTALRAY/...

En gros, on met un attribut spécial sur un objet de la scène et le shader de cet objet utilisera cet attribut dans ses paramètres. Un peu comme les overrides des render layers de Maya, mais à l'échelle d'un objet au niveau de son shader. :hehe:

:longBar:

La limitation

Vous allez voir qu'elle est de taille! :sourit:

Si vous venez juste d'ouvrir Maya, ouvrez votre script editor:

// parsing C:/Program Files/Autodesk/Maya2012/mentalray/include/userdata.mi
// loading C:/Program Files/Autodesk/Maya2012/mentalray/lib/userdata.dll
// Warning: (Mayatomr.Nodes) : Node "mib_data_bool" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_int" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_scalar" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_vector" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_color" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_string" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_texture" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_shader" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_bool_array" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_int_array" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_scalar_array" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_vector_array" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_color_array" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_string_array" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_texture_array" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_shader_array" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_bool" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_int" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_scalar" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_vector" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_color" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_string" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_texture" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_shader" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_shader_bool" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_shader_int" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_shader_scalar" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_shader_vector" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). // 
// Warning: (Mayatomr.Nodes) : Node "mib_data_get_shader_color" has no ID, assigning a temporary ID. Scene should be saved as .ma (ASCII). //

Qu'est ce que ça veut dire tout ça? :reflechi:

Et bien tout simplement que les nodes en question n'ont pas "d'identifiants internes". Ce code binaire qui est donné à un node quand on sauvegarde sa scène en .mb. D’où la "demande" de Maya qui vous incite à sauvegarder votre scène en .ma. Le .ma, comme vous le savez surement est un fichier texte. Le type du node y est écrit en dur donc pas besoin d'identifiants.

D'après Rachid, ce n'est pas un problème. En effet, après tests j'ai pu rouvrir une scène en .mb contenant quelques uns de ces nodes.

A vous de voir. Personnellement je n'ai pas encore super confiance (mais je suis du genre méfiant :redface: ). Faut voir à l'usage. :)

:longBar:

Scripts d'exemples

Voici quelques scripts d'exemples à lancer dans le script editor avec un mental ray chargé dans votre session Maya.

Script 1: Overrider une valeur

(Et oui, c'est du MEL... :siffle: )

// Creation d'une nouvelle scene
file -f -new;
 
/* On cree trois spheres.
Les deux premières auront chacune un paramètre qui leur est spécifique,
la troiseme n'aura aucun parametre.*/
polySphere;	// pSphere1
polySphere;	// pSphere2
move -r -2.341048 0.785068 1.752246 ;
polySphere;	// pSphere3 default sphere
move -r 2.341048 0.785068 -1.752246 ;
 
// place la cam
setAttr "persp.translateX" 8.053;
setAttr "persp.translateY" 6.607;
setAttr "persp.translateZ" 8.083;
setAttr "persp.rotateX" -27.938;
setAttr "persp.rotateY" 45;
 
/* ajoute l'attribut special: "miData" sur les deux spheres a modifier,
celles qui recevront une valeur custom */
addAttr -ln "miData" -at message pSphere1;
addAttr -ln "miData" -at message pSphere2;
 
// Cree les deux nodes qui contiendront les valeurs customs que le shader recuperera
createNode mib_data_scalar;
createNode mib_data_scalar;
 
/* Important: Un "name" commun doit etre donne pour faire la relation
entre les attributs (voir plus loin)
Ici c'es SCALAR qui est utilise */
setAttr -type "string" mib_data_scalar1.name "SCALAR";
setAttr -type "string" mib_data_scalar2.name "SCALAR";
 
// On leur definit ensuite une valeur custom
setAttr "mib_data_scalar1.value" 0.1;
setAttr "mib_data_scalar2.value" 1.0;
 
// On connecte les deux nodes contenant les valeurs customs aux spheres
connectAttr mib_data_scalar1.message pSphere1.miData;
connectAttr mib_data_scalar2.message pSphere2.miData;
 
 
// Le shader maintenant
 
// On cree le node qui recuperera les valeurs customs
createNode mib_data_get_scalar;
 
/* Pour faire la relation avec les nodes précédents, on lui assigne aussi le "name" SCALAR
Et surtout, une valeur par défaut */
setAttr -type "string" mib_data_get_scalar1.name "SCALAR";
setAttr mib_data_get_scalar1.default 0.5;
 
// On cree le shader
mrCreateCustomNode -asShader "" mia_material_x;
 
// On selectionne les trois spheres et on leurs assigne le shader
select pSphere1 pSphere2 pSphere3;
hyperShade -assign mia_material_x1;
 
// L'etape final, on connecte le node de get (celui qui recupere les valeurs customs) sur l'attribut a modifier
connectAttr mib_data_get_scalar1.outValue mia_material_x1.diffuse_weight;

Lisez bien les commentaires pour voir un peu ce qu'il fait (dsl, je n'ai pas mis d'accents ni rien pour éviter les syntax error :aupoil: ).

Lancez le rendu:

mental_ray_3_9_Les_User_Data_Shaders_005.png

  • La sphère du centre est la sphère 1 (valeur: 0.1)
  • Celle de gauche est la sphère 2 (valeur: 1.0)
  • Celle de droite est la sphère 3 (valeur: 0.5)

En général, c'est là qu'on commence à tilter.

Pas convaincu? Mettons un peu de couleur la dedans. :hehe:

Script 2: Overrider une couleur

Un autre avec les colors (Je n'ai mis les commentaires que là ou c'était différent de l'exemple précédent):

file -f -new;
 
// Sphères
polySphere;
polySphere;
move -r -2.341048 0.785068 1.752246 ;
polySphere;	// default sphere
move -r 2.341048 0.785068 -1.752246 ;
 
// Camera
setAttr "persp.translateX" 8.053;
setAttr "persp.translateY" 6.607;
setAttr "persp.translateZ" 8.083;
setAttr "persp.rotateX" -27.938;
setAttr "persp.rotateY" 45;
 
// Attributs
addAttr -ln "miData" -at message pSphere1;
addAttr -ln "miData" -at message pSphere2;
 
// Cree deux nodes de color
createNode mib_data_color;
createNode mib_data_color;
 
// Leur donne le name
setAttr -type "string" mib_data_color1.name "COLOR";
setAttr -type "string" mib_data_color2.name "COLOR";
 
// Ainsi que des valeurs de couleur (rouge, vert)
setAttr "mib_data_color1.value" -type double3 0 1 0 ;
setAttr "mib_data_color2.value" -type double3 1 0 0 ;
 
// On les connectes aux spheres
connectAttr mib_data_color1.message pSphere1.miData;
connectAttr mib_data_color2.message pSphere2.miData;
 
// Le shader
 
// Cree le node qui va recuperer les informations de couleurs des objets
createNode mib_data_get_color;
 
// Set le name ainsi que sa valeur par defaut (bleu)
setAttr -type "string" mib_data_get_color1.name "COLOR";
setAttr "mib_data_get_color1.default" -type double3 0 0 1 ;
 
// Cree le shader et l'assigne au trois spheres
mrCreateCustomNode -asShader "" mia_material_x;
 
select pSphere1 pSphere2 pSphere3;
hyperShade -assign mia_material_x1;
 
// Connecte le node de get (celui qui recupere les valeurs customs) sur le shader
connectAttr mib_data_get_color1.outValue mia_material_x1.diffuse;

Lancez le rendu:

mental_ray_3_9_Les_User_Data_Shaders_006.png

Tadaa!

Bon, si vous continuez avec le node de color, la première chose que vous allez vouloir faire est de lui connecter d'autres nodes Maya (a priori des textures mais ici, nous utiliseront de simples multiplyDivides qui renvoient des couleurs différentes):

mental_ray_3_9_Les_User_Data_Shaders_007.png

Tatataaaaa... :nannan:

Et non, ça ce passe pas comme ça! Je ne vais pas rentrer dans les détails mais en gros, n'importe quel autre node de Maya est considéré comme un "shader" par mental ray. Et non comme une couleur.

Voyons voir comment s'en sortir:

Script 3: Overrider un "shader"

file -f -new;
 
// Sphere
polySphere;
polySphere;
move -r -2.341048 0.785068 1.752246 ;
polySphere;	// default sphere
move -r 2.341048 0.785068 -1.752246 ;
 
// Camera
setAttr "persp.translateX" 8.053;
setAttr "persp.translateY" 6.607;
setAttr "persp.translateZ" 8.083;
setAttr "persp.rotateX" -27.938;
setAttr "persp.rotateY" 45;
 
// Attributs
addAttr -ln "miData" -at message pSphere1;
addAttr -ln "miData" -at message pSphere2;
 
// On cree les nodes de multiply divide auquels on donne une couleur
createNode multiplyDivide;
createNode multiplyDivide;
createNode multiplyDivide;
 
setAttr "multiplyDivide1.input1X" 1;	// red
setAttr "multiplyDivide1.input1Y" 0;
setAttr "multiplyDivide1.input1Z" 0;
 
setAttr "multiplyDivide2.input1X" 0;	// green
setAttr "multiplyDivide2.input1Y" 1;
setAttr "multiplyDivide2.input1Z" 0;
 
setAttr "multiplyDivide3.input1X" 0;	// blue
setAttr "multiplyDivide3.input1Y" 0;
setAttr "multiplyDivide3.input1Z" 1;
 
 
// On cree un mib_data_SHADER cette fois
createNode mib_data_shader;
createNode mib_data_shader;
 
setAttr -type "string" mib_data_shader1.name "COLOR";
setAttr -type "string" mib_data_shader2.name "COLOR";
 
connectAttr multiplyDivide1.output mib_data_shader1.value;
connectAttr multiplyDivide2.output mib_data_shader2.value;
 
// Connection
connectAttr mib_data_shader1.message pSphere1.miData;
connectAttr mib_data_shader2.message pSphere2.miData;
 
// Le material
// On cree le node qui recuperera les shaders par objet
createNode mib_data_get_shader_color;
 
setAttr -type "string" mib_data_get_shader_color1.name "COLOR";
 
// valeur par defaut: bleu
connectAttr multiplyDivide3.output mib_data_get_shader_color1.default;
 
// Cree le material et assigne aux sphere
mrCreateCustomNode -asShader "" mia_material_x;
 
select pSphere1 pSphere2 pSphere3;
hyperShade -assign mia_material_x1;
 
// Connection final du node de get au shader
connectAttr mib_data_get_shader_color1.outValue mia_material_x1.diffuse;

Finalement c'est assez proche du script précédent sauf qu'on utilise un mip_data_shader au lieu d'un mip_data_color:

mental_ray_3_9_Les_User_Data_Shaders_008.png

Ce qui fait qu'on peut entrer n'importe quel node Maya, mental ray le prendra bien.

Les textures

Et oui, c'est quasiment la finalité de ce genre d'outils.

Ça peut paraitre simple mais en fait pas du tout! :sourit:

Le bon sens voudrait qu'on les connecte au mip_data_shader comme on le ferait pour le multiplyDivide...

Haha, pauvre naïf! Pas assez compliqué mon fils...

Je me suis pas mal arraché les cheveux là dessus en bricolant avec une bonne partie des nodes alors que finalement la réponse était toute simple:

If you're talking about what I think you're talking about, there's a translation issue with textures.

They need to pass through another node like a multiply/divide. Just be sure to multiply by 1.

Tu m'étonne que j'y ai pas pensé... C'est à la fois tellement évident et tellement n'importe quoi... :pasClasse:

En gros, pour faire joujou avec les textures, il faut les passer dans un autre node (J'entend les Vray users qui glousse au fond... Ils ont bien raison :septic: ).

Il ne faut donc pas connecter directement les node de file Maya au mip_data_shader mais au multiplyDivide (par exemple) avec une multiplicateur à 1.0...

Voilà grossièrement ce que ça donne:

mental_ray_3_9_Les_User_Data_Shaders_009.png

Pas de commentaires svp... :seSentCon:

Et le rendu:

mental_ray_3_9_Les_User_Data_Shaders_010.png

Et tout ça avec un seul shader dans la scène:

mental_ray_3_9_Les_User_Data_Shaders_011.png

Votre hypershade vous dit merci! :laClasse:
:longBar:

Overrider plusieurs paramètres

C'est bien joli. Mais quand on souhaite overrider plusieurs paramètres on fait comment? :reflechi:

En effet, il n'y a, qu'un attribut miData par objet. Donc à priori on ne peut overrider qu'un seul paramètre.

Qu'à cela de tienne, il suffit que l'attribut miData soit de type multi. :hehe:

addAttr -ln "miData" -at message -multi pSphere1;

Et on assigne avec:

connectAttr mib_data_shader1.message pSphere1.miData[x];

Ou x est le numéro dans le tableau.

Le code complet:

file -f -new;
 
// Sphères
polySphere;
polySphere;
move -r -2.341048 0.785068 1.752246 ;
polySphere;	// default sphere
move -r 2.341048 0.785068 -1.752246 ;
 
// Cameras
setAttr "persp.translateX" 8.053;
setAttr "persp.translateY" 6.607;
setAttr "persp.translateZ" 8.083;
setAttr "persp.rotateX" -27.938;
setAttr "persp.rotateY" 45;
 
/* Vous remarquez la présence du flag "multi" qui créé
l'attribut comme un tableau */
addAttr -ln "miData" -at message -multi pSphere1;
addAttr -ln "miData" -at message -multi pSphere2;
 
// On cree les nodes de multiply divide auquels on donne une couleur
createNode multiplyDivide;
createNode multiplyDivide;
createNode multiplyDivide;
 
setAttr "multiplyDivide1.input1X" 1;	// red
setAttr "multiplyDivide1.input1Y" 0;
setAttr "multiplyDivide1.input1Z" 0;
 
setAttr "multiplyDivide2.input1X" 0;	// green
setAttr "multiplyDivide2.input1Y" 1;
setAttr "multiplyDivide2.input1Z" 0;
 
setAttr "multiplyDivide3.input1X" 0;	// blue
setAttr "multiplyDivide3.input1Y" 0;
setAttr "multiplyDivide3.input1Z" 1;
 
 
 
// On cree un mib_data_shader
createNode mib_data_shader;
createNode mib_data_shader;
 
setAttr -type "string" mib_data_shader1.name "COLOR";
setAttr -type "string" mib_data_shader2.name "COLOR";
 
// Connect la couleur au node d'override
connectAttr multiplyDivide1.output mib_data_shader1.value;
connectAttr multiplyDivide2.output mib_data_shader2.value;
 
/* Et on connecte les nodes d'override au premier élément
du tableau des attributs de l'objet */
connectAttr mib_data_shader1.message pSphere1.miData[0];
connectAttr mib_data_shader2.message pSphere2.miData[0];
 
 
/* On créé les deux nodes d'override suivant
et on leur assigne une valeur */
createNode mib_data_scalar;
createNode mib_data_scalar;
 
setAttr -type "string" mib_data_scalar1.name "SCALAR";
setAttr -type "string" mib_data_scalar2.name "SCALAR";
 
setAttr "mib_data_scalar1.value" 0.15;
setAttr "mib_data_scalar2.value" 0.25;
 
/* Puis on connecte les nodes d'override au second élément
du tableau des attributs de l'objet */
connectAttr mib_data_scalar1.message pSphere1.miData[1];
connectAttr mib_data_scalar2.message pSphere2.miData[1];
 
 
// Le material
/* On cree le node qui récupérera
les shaders de couleurs par objet */
createNode mib_data_get_shader_color;
 
setAttr -type "string" mib_data_get_shader_color1.name "COLOR";
 
// Connect la valeur par défaut: bleu
connectAttr multiplyDivide3.output mib_data_get_shader_color1.default;
 
 
/* On cree le node qui récupérera
les valeurs scalaire par objet */
createNode mib_data_get_scalar;
 
setAttr -type "string" mib_data_get_scalar1.name "SCALAR";
setAttr mib_data_get_scalar1.default 0;
 
 
// Cree le material et assigne aux sphères
mrCreateCustomNode -asShader "" mia_material_x;
 
select pSphere1 pSphere2 pSphere3;
hyperShade -assign mia_material_x1;
 
// On met l'anisotropy à 0.1 pour voir l'effet
setAttr "mia_material_x1.anisotropy" 0.1;
 
// Connection final des nodes de get au shader
connectAttr mib_data_get_shader_color1.outValue mia_material_x1.diffuse;
connectAttr mib_data_get_scalar1.outValue mia_material_x1.anisotropy_rotation;

Et le rendu:

mental_ray_3_9_Les_User_Data_Shaders_012.png

Remarquez comment chaque objet a une rotation de l'anisotropy différente

Et on peut faire ça sur tous les paramètres. :sourit:

:longBar:

Bonus

Voici quelques images que j'avais posté sur CGTalk en montrant les connections. C'est le genre de references à avoir sous la mains.

Le système "de base" (color):

test_shaderAttrOverride001.png

test_shaderAttrOverride002.png

test_shaderAttrOverride003.png

Les multi attritbutes miData:

test_shaderAttrOverride004.png

test_shaderAttrOverride005.png

:longBar:

Conclusion

J'espère que vous aurez apprécié ce speed billet (pas si speed que ça en fait...). Et que vous saurez maintenant qu'il existe une astuce qui peut vous dépanner (voir plus si intelligemment utilisé).

Il faudra que j'éssai de voir si ça tiens la charge... :gniarkgniark:

Autodesk nous a habitué au fil de ses releases à devoir bidouiller comme un porc pour avoir accès à certaines fonctionnalités de mental ray.

Maya 2012 ne déroge pas à la règle et la nouveauté "User Data Shaders" est sans doute LA feature de sur lesquels des nerds (moi?) peuvent se brosser en se disant "Cool! Il ne m'a fallu que deux soirées pour pouvoir l'utiliser" pendant que d'autres seront en train de faire des images, des vrais avec également les dernières features de leur package de rendu favoris... Sans douleurs ni rien...

Ouai... Faut aimer se faire du mal pour utiliser mental ray dans Maya. :smileFou:

Pourtant, j'adore! :siffle:

N'hésitez pas à me signaler si un code fournit ne fonctionne pas. :mechantCrash:

Pour info. Il y a peut être un espoir que mental image récupère l'intégration de mental ray dans Maya. Mais rien n'est moins sûr et si ça se fait, ça ne sera pas pour tout de suite...

:marioCours:

MAJ 2011-05-11: Je viens d'installer Le Hotfix de Maya 2012 et toujours aucune trace des userData dans un quelconque .mi...