PROJET AUTOBLOG


blog.fevrierdorian.com

source: blog.fevrierdorian.com

⇐ retour index

Fabriquer un reflecteur de flash pour Canon EOS 550D

vendredi 24 juin 2011 à 22:19

IMG_5698_tn.jpgBonjours à tous! Étant l'heureux possesseur d'un Reflex Canon EOS 550D, il m'est souvent arrivé d'avoir à shooter dans des endroits peut éclairé.

Cet appareil est équipé d'un flash mais j'ai toujours trouvé les résultats très décevants (c'est vraiment la lumière "en pleine face", pas super esthétique). Même mon petit compact fait de meilleurs photos avec son flash... Il existe des flashs externes dédiés mais ils sont souvent très cher.

Un jour, j'ai essayé de placer ma mains devant le flash, légèrement penché pour éclairer le plafond et simuler l'effet des flash externes que l'on peu pivoter pour se servir du plafond comme réflecteur de lumière. La lumière créé était très intéressante et j'ai commencé à réfléchir à une façon de diriger ce flash ver le haut et je vous propose une présentation de mon petit bricolage qui marche très bien! :hehe:

Ce qu'il faut

La grande plaque de fer:

IMG_4738.jpg

Le carton et les ciseaux:

IMG_5664.JPG

Le scotch (pour les neuneus qui voient pas ce que c'est... :baffed: ) :

IMG_5696.JPG

Le carton pour prototyper, toujours!

Avant de partir bille en tête il vaut mieux savoir exactement ce qu'on souhaite faire. :reflechi:

Je me suis servi du morceau de carton en le découpant à plusieurs reprises pour trouver une façon de faire tenir le réflecteur sur l’appareil.

Après quelques tests, j'avais quelque chose qui tenait la route et se glissait correctement sur l'appareil.

IMG_5666.JPG

IMG_5667.JPG

IMG_5668.JPG

Cette étape est importante. Prenez le temps qu'il faut et avancez doucement. Ce morceau de carton deviendra le patron de votre pièce finale. :sourit:

IMG_5669.JPG

Le patron

L'idée maintenant est de reporter le découpage du carton sur la plaque de métal.

IMG_5670.JPG

IMG_5671.JPG

Je me suis servi d'un crayon tout ce qu'il y a de plus simple mais on peu utiliser un feutre. :jdicajdirien:

Le découpage

Attention aux mains! Encore une fois, il faut avancer doucement. :redface:

IMG_5672.JPG

IMG_5673.JPG

Une fois la coupe faite, servez vous de la pince pour "réaplatir" certains bords qui sortent un peu trop.

IMG_5674.JPG

A ce stade, vous pouvez vérifier que le tout s'emboite bien.

IMG_5675.JPG

IMG_5676.JPG

IMG_5677.JPG

Vous pouvez éventuellement peaufiner un peu le découpage pour le rendre plus "doux" pour votre appareil (personnellement, j'ai utilisé du scotch, deux épaisseurs, pour éviter de rayer l'appareil au niveau des bords de la plaque de fer).

La pliure

A ce stade, la plaque est trop proche du flash et renverrait la lumière vers l'arrière. :septic:

Il faut donc plier le tout!

IMG_5678.JPG

Tracez un trais pour y voir plus clair.

IMG_5679.JPG

IMG_5680.JPG

Prenez votre pince et commencer à plier sur la ligne.

IMG_5681.JPG

La pliure doit se faire en plusieurs passages et sur toute la longueur pour éviter de casser le métal.

Le "crochet"

Nous allons maintenant nous servir du second chapeau de boite de conserve pour faire une "bande" en métal.

Celle ci servira à "accrocher" le flash de l’appareil pour maintenir la grande plaque.

IMG_5682.JPG

Servez vous de la pince pour aplatir au maximum la bande.

IMG_5683.JPG

IMG_5686.JPG

Récupérez les zones de pliure de la bande en carton.

IMG_5687.JPG

Et placez le tout sur la grande plaque:

IMG_5688.JPG

Important: J'ai utilisé du scotch Chaterton sur la photo car je souhaitait mettre une feuille blanche sur l'intégralité de la plaque. Mais après pas mal de test, il s’avère qu'utiliser directement le métal comme réflecteur du flash est plus efficace. J'ai donc utilisé un scotch transparent pour laisser le métal apparent. :zinzin:

IMG_5690.JPG

IMG_5698.JPG

C'est clairement pas esthétique mais le rapport qualité prix est imbattable! :aupoil:

Amélioration possibles

A ce stade, l'objet me convient mais il peut être grandement amélioré:

Je pense ajouter l'élastique parce que pour le moment, je ne peut pas tourner l'appareil sans que le réflecteur se casse la figure... :jdicajdirien:

Conclusion

J'espère que ce petit article vous aura aidé et éventuellement donnée l’envie d'expérimenter d'autres trucs et de gouter aux joies du "Do It Yourself" (DIY).

En bonus: Voici un liens qui présente 24 façons de fabriquer une softbox à la main. Certaines débordent d'ingéniosité et sont très simple à faire... (Merci Fredo! :hehe: )

A bientôt!

:marioCours:

EDIT 29 Mars 2012: Après presque un an, je l'utilise toujours autant :hehe: . Il m'arrive même de le trimbaler chez des amis. Ducoup, mes photos d’intérieur, le soir ou il y a pas forcement beaucoup de lumière, sont vraiment très bonne. Franchement c'est vraiment quelque chose a avoir.

De plus, ce réflecteur envoi de la lumière un peu partout de manière un peu archaïque ce qui fait qu'on a jamais cette sensation d'avoir un plafond qui illumine.

Je ne regrette pas mon petit bricolage. :aupoil:

Mental ray 3.9: L'Unified Sampling, explications

mardi 10 mai 2011 à 22:36

2011_04_23_Unified_Sampling_tn.pngCe billet est la traduction d'un thread de CGTalk lancé par Bitter ou il explique le principe de la nouvelle technique de sampling utilisé dans mental ray 3.9: L'Unified Samplig.

Cette nouvelle technique est beaucoup plus efficace car elle prend en compte les samples et leur direction, alors que l'ancienne méthode ne se basait que sur le contraste de la couleur des samples dans l'image finale.

Cette technique est plus ou moins déjà utilisé dans Vray (au d'autres raytracers) mais c'est un vrai plaisir de voir cette nouvelle méthode de sampling dans mental ray.

Sommaire

La méthode de Monte Carlo

Avant de commencer, sachez que ce thread aborde la méthode de Quasi Monte Carlo...

Vu que je suis curieux, j'ai cherché un peu et je vous propose une misérable petite explication.

3020447896_c836a6058f_o.jpg

Photo par Harm Rhebergen sous licence Créative by-nc-nd. Merci à lui! :sourit:

Je vais modestement tenter de vous éclaircir un peu sur ce qu'est la méthode de Monte Carlo, ainsi que ses variantes.

Si vous connaissez un site qui parle de la chose de manière clair, sans trop de blah blah mathématique, n'hésitez pas à me laisser un commentaire. Je me ferai un plaisir, si j'arrive à comprendre le truc, à approfondir mon billet. :dentcasse:

D'après ce que j'en ai compris, la méthode de Monte Carlo est un moyen d'obtenir un résultat le plus juste possible en se basant sur des probabilités. Normalement, cette méthode ne fait "que ça".

Dans le cas du sampling, ce qu'on cherche à obtenir ("le résultat") est un endroit ou lancer un sample le plus "utile" possible.

Ce qui fait office de probabilité est "la signature" des samples. (Position+Direction).

Plus cette signature semble aléatoire, plus il faut, à priori, ajouter de sample.

Il existe plusieurs variantes des algorithmes de Monte Carlo (Quasi Monte Carlo, Deterministic Monte Carlo).

La doc officiel sur le DMC Sampler de Vray aborde un peu les différences:

The difference between pure Monte Carlo sampling and deterministic Monte Carlo is that the first uses pseudo-random numbers which are different for each and every evaluation (and so re-rendering a single image will always produce slightly different results in the noise), while deterministic Monte Carlo uses a pre-defined set of samples (possibly optimized to reduce the noise), which allows re-rendering an image to always produce the exact same result.

La doc officiel de Blender tente aussi une petite démystification du principe de QMC.

Si je comprend bien:

Je serais bien incapable de vous donner plus de détails.

Après ce fiasco d'explication (quoi que j'ai personnellement appris pas mal de choses en cherchant), je vous propose de passer à la traduction! :sourit:

Les traductions

Ndt: Ceci est la traduction du premier post de Bitter

L'Unified Sampling de Maya 2012 dans mental ray

L'Unified Sampling est une méthode de sampling se basant sur des calculs de probabilités (QMC pour Quasi-Monte-Carlo) sur "le plan" de l'image (le plan de la camera ou est rendu l'image en fait).

A la différence de l'Anti-Aliasing classique, qui fonctionne sur la base d'une grille (les pixels) et d'un contraste des couleurs sur cette même grille, l'US (Unified Sampling) est basé, par couche, sur une distance optimale entre les samples, qui sont envoyés en se basant sur des modèles de probabilité (de type QMC), et une estimation de l'erreur.

Ce qui veut dire que vous pouvez calculer de la géométrie fine tel que des hairs et des furs en utilisant le raytrace au lieu du rasterizer, tout en conservant une bonne qualité.

L'US samplera de la géométrie plus petite qu'un pixel tout en nécessitant, généralement, moins de samples en interne.

Il résout également les problèmes de noise en générant son propre grain adaptatif.

Maintenant, le DOF et le Motion Blur raytracé est plus doux et plus rapide à calculer.

Vous pouvez rendre du Motion Blur raytracé. Le Motion Blur est maintenant visually adaptive.

En mode US, vous pouvez ignorer les time samples. Les zones avec peu de détails et/ou ayant des couleurs plates recevront le minimum de sample, indépendamment de leur quantité de Motion Blur.

La quantité de mémoire utilisé par le Motion Blur est maintenant minimal comparé à avant.

Les trois contrôleurs principaux

mental_ray_box.png

Photo originale par gwenflickr sous licence Créative by-nc-sa. Merci à lui! :sourit:

samples min = Le nombre minimum de samples utilisé par pixels (les valeurs en dessous de 1 sous-sampleront les pixels). Ces valeurs ne seront pas soumis à des puissance comme l'Anti-Aliasing standard. Ce sont des valeurs absolues.

samples max = Le nombre maximum de samples utilisé par pixel.

samples quality = Le potar principal de l'US. Plus il est grand, meilleur c'est. 1.0 Peut être considéré comme une valeur de production. Il m'arrive de monter ce paramètre plus haut, 2 ou 3, cela dépend de la quantité de noise/petits détails que j'ai. 0.3 est une bonne valeur pour la preview.

Si vous trouvez que le Motion Blur ou le DOF est granuleux, augmenter le samples max.

Mais dans la plupart des cas, vous pouvez augmenter le samples quality et laisser vos valeurs de samples assez large.

Ce potar de qualité est maintenant votre contrôleur de rendu!

Basiquement, la technique consiste à setter un min et un max et à utiliser le potar pour jauger la qualité.

Vous pouvez utiliser les diagnostics pour voir comment/ou vos samples sont envoyés et prendre une décision à partir de là.

Les diagnostiques sont embarquées dans un EXR, dans différents channels (voir plus bas).

Ndt: Le diagnostique joue un role important pour déterminer les valeurs optimales de rendu. On y reviendra.

Autres contrôleurs

sample error cutoff = Défini quand arrêter de sampler. C'est une tolérance de couleur qui commence "par le bas" (couleur noire). Plus la valeur est haute, plus les zones claires sont ignoré. C'est un paramètre très sensible qui est rarement utilisé.

samples per object = Utilise les valeurs de sampling setté "par objet". Au même titre que précédemment, ces valeurs de min et max sample par objet doivent être absolue (et non des puissances de deux).

Noter qu'il est fortement conseillé de désactiver le Scanline afin de ne pas diminuer les performances.

Le Scanline ralenti le rendu et ne devrait pas être activé par défaut dans Maya.

Il y a également trois channels intéressants de diagnostiques dans l'EXR quand vous rendez avec l'option diagnose samples.

Ils sont:

Démonstration (Ndt: C'est moi qui ai fait ces images pour rendre le truc plus évident...):

2011_04_23_Unified_Sampling_009.png

L'image originale (Image HDR de sIBL Archive sous licence Creative by-nc-sa. Merci à eux! :sourit: ).

2011_04_23_Unified_Sampling_001.png

Le fichier en question

2011_04_23_Unified_Sampling_002.png

La liste des channels disponibles.

2011_04_23_Unified_Sampling_003.png

2011_04_23_Unified_Sampling_004.png

Il faut bricoler un peu pour visualiser chaque channel. :hehe:

2011_04_23_Unified_Sampling_006.png

Le nombre de sample au pixel (Le chiffre en bas à droite. Ici: 13 samples)

2011_04_23_Unified_Sampling_007.png

Le temps (en secondes) passer par pixel. (Le chiffre en bas à droite. Ici: 0.03 sec). Notez qu'on voit la forme de la bounding box. :sourit:

Note: Les points blancs sont surement due à la granularité du temps.

2011_04_23_Unified_Sampling_008.png

L'error color estimé. (Encore un truc de Monte Carlo d'mes fesses :baffed: ).

Voici la ligne MEL pour créer les string options:

select miDefaultOptions;
int $idx = `getAttr -size miDefaultOptions.stringOptions`;
setAttr -type "string" miDefaultOptions.stringOptions[$idx].name "unified sampling";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].value "on";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].type "boolean";
$idx = `getAttr -size miDefaultOptions.stringOptions`;
setAttr -type "string" miDefaultOptions.stringOptions[$idx].name "samples min";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].value "1.";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].type "float";
$idx = `getAttr -size miDefaultOptions.stringOptions`;
setAttr -type "string" miDefaultOptions.stringOptions[$idx].name "samples max";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].value "64.";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].type "float";
$idx = `getAttr -size miDefaultOptions.stringOptions`;
setAttr -type "string" miDefaultOptions.stringOptions[$idx].name "samples quality";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].value "0.5";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].type "scalar";
$idx = `getAttr -size miDefaultOptions.stringOptions`;
setAttr -type "string" miDefaultOptions.stringOptions[$idx].name "sample error cutoff";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].value "0 0 0";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].type "color";
$idx = `getAttr -size miDefaultOptions.stringOptions`;
setAttr -type "string" miDefaultOptions.stringOptions[$idx].name "samples per object";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].value "off";
setAttr -type "string" miDefaultOptions.stringOptions[$idx].type "boolean";

Ndt: Pour vous simplifier la vie, je vous invite à utiliser mon outil: enjoyMentalRayStringOptions

Techniquement, sample quality est une couleur. Mais pour pas mal de raisons, on préfèrera combiner les trois valeurs en une seule.

A noter: Il s'agit d'une première implémentation et je trouve qu'elle est bonne sur pas mal de points. Vous remarquerez que les hards edges ne sont pas définies du mieux possible (surtout en Arch Viz). C'est un point à améliorer qui a déjà été mentionné. Tout comme le reste, je suppose que cette feature s’améliora dans le temps.

Error Control

Ndt: Ceci est la traduction d'un autre post de Bitter

Voici une explication plus clair de l'error control de l'Unified Sampling

Les images qui suivent ont été générées via des paramètres de qualité graduel: 0.25 -> 0.75 -> 1.5

Vous remarquerez comment l'erreur perçu diminue à chaque valeur. Les zones ayant le plus d'erreurs sont les plus colorées. Vous pouvez voir les erreurs de chaque couleur en regardant chaque channel (RGB).

0.25 quality0250.jpg

0.75 quality0750.jpg

1.5 quality15.jpg

Vous trouverez le fichier de diagnostic du rendu de qualité 1.5 ici:

diagnostic.exr

Elle contient les 4 layers de diagnostique. Vous pouvez l'ouvrir avec imf_disp pour voir ces layers.

Pour le layer samples, vous serez amené à ramener l'exposition à -5.0 pour voir l'image. Placez ensuite votre curseur sur les pixels pour récupérer différentes valeurs.

Le rendu prend tout juste 11 minutes en 1280x720 à une qualité de 1.5 (sans compter le calcul du final gather).

J'utilise des shader BSDF avec du glossiness (visible sur les bureaux).

quality15beauty.jpg

RC   0.3  info : rendering statistics
RC   0.3  info :   type                           number   per eye ray
RC   0.3  info :   eye rays                      4618306          1.00
RC   0.3  info :   transparent rays                63490          0.01
RC   0.3  info :   reflection rays              30493569          6.60
RC   0.3  info :   shadow rays                 335052362         72.55
RC   0.3  info :   fg points interpolated       33898517          7.34
RC   0.3  info : on average 65.38 finalgather points used per interpolation
RC   0.3  info : wallclock  0:10:30.95 for rendering
RC   0.3  info : allocated 124 MB, max resident 166 MB
GAPM 0.3  info : triangle count (including retessellation) :      247606

Le truc qui prend le plus de temps à calculer c'est les shadow rays. 72.55 rayons "eye ray" (Ndt: Sample?)

J'ai des portal lights sur les fenètres avec un High Samples seulement à 16. Cela dit, j'ai un rendu clean. J'ai quelques artefacts de final gather mais ils ne serait pas difficile de s'en occuper.

Undersampling

Ndt: Ceci est la traduction d'un autre post de Bitter

samples min 0.1
samples max 1.
samples quality 0.1

Vous pouvez jouer avec comme il vous plait.

Mon paramètre de samples min sample maintenant tout les 10 pixels avec un max de 1 sample par pixel. Je pourrai augmenter le maximum mais ça utilisera plus de samples si ma quality augmente aussi.

undersample.jpg

Conclusion

J'espère que vous aurez apprécié ces traductions qui m'ont personnelement pas mal éclairées sur le sujet.

C'est toujours interessant de savoir comment fonctionne une "nouvelle" technique (je met des guillemets car mental ray est surement un des derniers raytracer "high end" qui intègre cette méthode de sampling. Enfin bon... :pasClasse: ).

A bientôt!

Dorian

EDIT 2011 - 11 - 19: Il semble que je n'ai pas bien abordé la theorie qui entour le DMC sampler. Voici ma traduction sur le DMC sampler de Vray. C'est beaucoup plus précis (par un ancien de chez Blur).

:marioCours:

Mental ray 3.9: Les User Data Shaders (ou Shader Package)

samedi 16 avril 2011 à 17:20

mental_ray_3_9_Les_User_Data_Shaders_tn.pngComme vous le savez tous, Maya 2012 est sorti. Et comme chaque nouvelle version de Maya, mental ray est mis à jour (v3.9.1.36). Dans ce billet, je ne ferai pas le tour des nouvelles features. Elles sont présentées ici (page officielle). Je m'attarderai en revanche sur l'une d'elle que je trouve très intéressante: Les shaders packages.

Concrètement, cela consiste à appliquer un attribut spécifique à un élément de la scène pour que son shader puisse utiliser la valeur donné dans l'attribut.

Un exemple: Si vous avez un shader sur des objets et que la seule chose qui change en fonction de ses objets est la texture, il est dommage de dupliquer tout le shader pour ça, et, en cas de modifications de devoir l'appliquer sur tous les shaders dupliqués de la scène... Sur des grosses scènes ça devient vite ingérable... :redface:

Je vous propose ici un billet rapide sur le principe ainsi que des bouts de script, un peu en vrac, que vous pourrez essayer. :sourit:

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

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...

Petite astuce pour filtrer les nodes par attributs via la commande ls de Maya

vendredi 15 avril 2011 à 22:59

pythonVsMaya_tn150.pngBillet express: Je viens de découvrir une façon d'utiliser la commande ls que je ne connaissais pas. C'était pourtant évidant. :casseTeteMur:

La technique consiste à utiliser * dans le nom de l'objet...

Bon, ça je le savais déjà. Mais là ou ça devient intéressant, c'est quand il s'agit de récupérer tous les objets ayant un attribut bien spécifique.

Cela évite d'avoir à utiliser une boucle! :sauteJoie:

Je vous propose de voir quelques cas d'utilisation.

Exemples

Récupérer tous les objets de la scène ayant l'attribut "message":

cmds.ls( "*.message" )
# Result: [u'node1.message', u'node2.message', u'node3.message', u'node4.message' ]

Masquer les noms des attributs dans les valeurs renvoyées:

cmds.ls( "*.message", objectsOnly=True )
# Result: [u'node1', u'node2', u'node3', u'node4' ]

Vous remarquerez peut être que ces deux exemples ne renvoient aucun objet dans un namespace.

Pour également vérifier les objets dans les namespaces:

cmds.ls( "*.message", objectsOnly=True, recursive=True )
# Result: [u'ns1:node1', u'ns2:node1', u'node2', u'node3' ]

Et voilà!

Conclusion

J'espère que ce petit billet vous aura appris un truc.

Personnellement, depuis, je n'utilise plus que ça! :banaeyouhou:

A bientôt!

Dorian

:marioCours:

Récupérer rapidement la position des vertices d'un mesh Maya

mercredi 30 mars 2011 à 22:40

recuperer_Position_Vertex_Rapidement_tn.pngSi vous avez déjà été amené à récupérer la position dans l'espace de tous les vertices d'un objet, vous avez surement dû vous heurter à la commande xform et à sa lenteur légendaire. :baffed:

Dans ce billet, je vous propose un petit bout de script Python utilisant l'API Maya en Python qui permet de récupérer, plus rapidement, la liste de toutes les positions des vertices d'un objet.

Principalement didactique, ces codes, pourront intéresser les personnes qui souhaitent regarder un peu plus profondément comment utiliser l'API tout en ayant un cas concret d'application. :laClasse:

En utilisant xform

Voici la version du script qui utilise la commande xform:

def getVtxPos( shapeNode ) :
 
	vtxWorldPosition = []    # contiendra les positions dans l'espace de tout les vertex de l'objet
 
	vtxIndexList = cmds.getAttr( shapeNode+".vrts", multiIndices=True )
 
	for i in vtxIndexList :
		curPointPosition = cmds.xform( str(shapeNode)+".pnts["+str(i)+"]", query=True, translation=True, worldSpace=True )    # [1.1269192869360154, 4.5408735275268555, 1.3387055339628269]
		vtxWorldPosition.append( curPointPosition )
 
	return vtxWorldPosition

La version avec l'API Maya

Alternative à xform.

import maya.OpenMaya as OpenMaya
 
def particleFillSelection(  ):
 
	# get the active selection
	selection = OpenMaya.MSelectionList()
	OpenMaya.MGlobal.getActiveSelectionList( selection )
	iterSel = OpenMaya.MItSelectionList(selection, OpenMaya.MFn.kMesh)
 
	# go througt selection
	while not iterSel.isDone():
 
		# get dagPath
		dagPath = OpenMaya.MDagPath()
		iterSel.getDagPath( dagPath )
 
		# create empty point array
		inMeshMPointArray = OpenMaya.MPointArray()
 
		# create function set and get points in world space
		currentInMeshMFnMesh = OpenMaya.MFnMesh(dagPath)
		currentInMeshMFnMesh.getPoints(inMeshMPointArray, OpenMaya.MSpace.kWorld)
 
		# put each point to a list
		pointList = []
 
		for i in range( inMeshMPointArray.length() ) :
 
			pointList.append( [inMeshMPointArray[i][0], inMeshMPointArray[i][1], inMeshMPointArray[i][2]] )
 
		return pointList

Note j'ai pensé qu'en spécifiant la taille de la liste dès le départ on gagnerait encore du temps mais ça ne change rien. Il semblerait que Python gère ça bien. Du coup, j'ai appris un nouveau dicton: Premature optimization is the root of all evil. :gniarkgniark:

Les temps

Bon, c'est bien beau de dire que c'est plus rapide. Mais de combien? :reflexionIntense:

Voici les temps que j’obtiens pour une pSphere 50x50 smoothée 4 (soit 633602 vertices):

10x plus rapide mine de rien. Ça me donnerait presque envie de le coder en C++, juste pour voir! :grenadelauncher:

Conclusion

Bon, et bien maintenant c'est à vous de voir quoi en tirer.

Vous pouvez essayer d'optimiser l’algorithme de Djelloul et me faire part de vos résultats! :sourit:

Toujours est t'il que personnellement, je ne pourrais plus me passer de l'API si j'ai à récupérer la position des vertices d'un mesh c'est beaucoup plus rapide! Moyennant une complexité supérieur, je veux bien l'avouer, mais quand on a ce bout de code, on le garde et on le ressort au bon moment! :aupoil:

A bientôt!

:marioCours: