Le mappage en mémoire des textures dans Mental Ray expliqué (Memory-mapped textures).
Par Narann le vendredi, 27 novembre 2009, 23:22 - Infographie 3D - Boulot - Lien permanent
Bonjours à tous. Dans ce billet je vais vous parler d'une spécificité de mental ray à savoir le mappage en mémoire des textures (ou, en anglais, textures memory mapped). Nous parlerons du fonctionnement de ses maps ainsi que des différentes façons de les utiliser. Cette technique permet de ne pas mettre en mémoire les textures de vos scènes mais de les lires directement sur le disque dur. Permettant ainsi d'économiser de la RAM et de diminuer les limitations de taille de texture.
Sommaire
- Memory-Mapped Textures: Traduction de la documentation officiel
- Mais comment qu'on fait?
- imf_copy
- imf_copy: Traduction de la documentation officiel
- Convertir nos textures en .map
- Suite?
Memory-Mapped Textures: Traduction de la documentation officiel
Avant de commencer, je me suis "amusé" à traduire la documentation mental ray qui y fait référence...
Memory-Mapped Textures
Mental Ray supporte le mappage en mémoire des textures sur les systèmes UNIX et NT.
Le mappage des textures consiste à ne pas charger la texture en mémoire mais à y accéder directement depuis le disque quand le shader en a besoin.
Il n'y a pas d'options spéciales pour en profiter: Si une texture est "mappable en mémoire", mental ray la reconnaîtra et l'utilisera automatiquement.
Seul les fichiers images peuvent être converti en textures "mappable en mémoire" (l'extension de base est .map. Cela dis, les fichiers "mappable en mémoire" sont reconnu même si ils ont une extension différente de .map). Voir la liste des "Output Shaders" (Ndt: dans la doc mental ray) pour une liste des formats de fichier supporté.
Remarquez que le mappage en mémoire est basé sur le principe que les informations sur le disque ne demande pas de décodage ou de conversion, mais sont accessibles dans le format exact que mental ray utilise en interne durant le rendu.
Normalement, mental ray essai de convertir automatiquement les fichiers images qu'il lit en son format d'image interne; Par exemple, si un fichier image est utilisé dans un shader, mental ray va silencieusement convertir les pixels de couleurs en valeur scalaire (0-1).
Du coup, une grande quantité de données (pixel) est converti en un autres type de données (scalaire).
Cela n'est pas le cas pour textures mappé en mémoire, et ce n'est pas le but. Cela s'applique également à l'ordre des octets (Ndt: Dernière phrase technique propre à l'organisation des octets dans la mémoire "Big et Little Endian", pour dire qu'une map converti sur une machine utilisant du big endian ne sera pas compatible avec une machine utilisant du little endian. Mais dans la mesure ou on travail pratiquement que sur station x86 et x64, on s'en fout).
Le mappage en mémoire nécessite plusieurs étapes de préparation:
- La texture doit être convertit au format .map en utilisant un utilitaire comme le imf_copy de mental image. Les chemins de fichier de la scène doit être changé pour aller chercher la nouvelle texture. Remarquez que mental ray reconnait les textures memory mapped mêmé si elles ont une extension différente de .map. Ceci peut être utile pour utiliser les anciens noms de fichiers images avec la "mauvaise" extension, et ce, afin d'éviter à ouvrir et modifier les chemin des fichiers images de la scène. (Ndt: Personnellement, je ne vous conseil pas cette technique)
Lors de l'utilisation de imf_copy, l'option -p est fortement recommandé pour créer une texture en pyramide dans le fichier .map.
- les textures mappé en mémoire sont automatiquement considéré comme étant en local par mental ray, comme si l'option "local" avait été utilisé dans le fichier scène. Cela signifie que si la scène est rendu sur plusieurs machine, chacune d'elle va essayer d'accéder au chemin de l'image donné au lieu de transférer la texture a travers le réseau, ce qui irait à l'encontre du but du mappage en mémoire des textures. Le chemin donné doit être valide sur toute les machine qui participe au rendu. Mental ray support également les textures mappé en "non local": La texture (mappé) est sur le serveur, mais récupérés à travers le réseau par les "esclaves", ce qui simplifie la distribution des scène (Ndt: En rendu) mais peu induire des surcharges réseau inacceptable. (Ndt: En gros, vu que mental ray fait des accès aussi fréquent que si la texture était en mémoire, il pas très conseillé de pointer vers des textures placé en réseau mais plutôt de les avoirs en local, sur chaque machine dédié au rendu. Pour avoir pratiqué le rendu "via le réseau", cela ne pose en fait pas trop de soucis si le réseau en un peu robuste et que le serveur est capable d'encaisser beaucoups d'entrées-sorties.)
- La texture ne dois pas être sur la partition d'un disque utilisant un système de fichier de type NFS (en réseau). Bien que cela évite que les textures doivent exister sur toute les machines, les transferts réseaux réduisent l'efficacité et peuvent facilement rendre le mappage en mémoire plus lent que l'utilisation de textures "tel quel".
- Le mappage en mémoire fonctionne mieux si il s'agit de textures très grandes qui contiennent beaucoup de pixels non utilisés car le fichier de la texture n'est jamais chargé en entier dans la mémoire.
- Une texture mappé en mémoire doit être créé sur une machine avec le même "byte order" que sur la machine qui sera utilisé, où il sera utilisé. Mental ray ne "memorymapera" pas les textures utilisant un byte order incompatible, au lieu de ça, il lira la totalité de la texture placé en mémoire et la convertira. Ce n'est pas efficace et doit être évitée (Ndt: Encore une histoire de little endian et de big endian). Si les textures et la scène sont grandes au point qu'elles ne rentrent pas dans la mémoire physique, et bien le fait de charger une texture revient à:
- Charger le fichier en mémoire
- Le décompresser
- Le copier dans le swap ((Ndt: Sur Unix) Le swap est une partition de disque qui agit comme une extension de la mémoire physique mais sur le disque dur. La vitesse de transfère y est ridicule). (Ndt: Sur windows, c'est le pagefile, la mémoire virtuelle)Dès lors, l'accès à une texture signifie l'accès au swap, et donc, au disque dur, ce qui fait "ramer" l'ordinateur.
Le mappage en mémoire élimine les étapes de "lecture-décompression-écriture-dans-la-mémoire" et accède à la texture depuis le système de fichiers au lieu du swap.
Cela a pour effet que moins d'espace de swap est nécessaire.
Si la texture et la scène ne sont pas énorme et "rentre" dans la mémoire, et si la texture est fréquemment consultée, les textures memory mapped se révèles légèrement plus lentes que les textures "classiques" (Lire sur le disque est plus long que de lire directement dans la mémoire). Mais pour les grandes textures, le memory mapping est une manière bien plus efficace de charger des textures. Ceci est particulièrement important pour mental ray, qui gère la mémoire comme un cache. Les textures qui ne sont pas memory mapped sont une perte énorme sur le cache, car ils ont tendance à prendre une grandes partie de la mémoire cache. Mental ray a un gestionnaire de cache virtuel séparé qui charge et décharge les textures memory-mapped de manière efficace sans bloquer le cache principal.
Je vous accorde que balancé comme ça, c'est un peu indigeste... :baffed: Mais si j'ai fait cette traduction, c'est parce que j'ai du passer sur cette documentation une bonne dizaine de fois et que malgré qu'elle soit imbuvable, elle est nécessaire à la compréhension du memory mapping dans mental ray...
Donc lisez bien cette version traduite puis lisez ensuite la version anglaise (si vous voulez comprendre les quelques subtilités que j'ai eu du mal à traduire):
Vous connaissez maintenant le principe des "map" (c'est comme ça qu'on les appellera). Avec cette technique, Mental Ray est techniquement capable de manger des textures de taille infini (j'ai essayé 80000x80000, ça passe! :aupoil: ).
Mais comment qu'on fait?
En gros le principe va être de convertir les textures de votre projet en .map et de pointer les textures de vos scène vers ses fichiers nouvellement créés. Et pis c'est tout! En effet, une fois cela fait, mental ray se débrouille très bien tout seul et va reconnaitre les .map et les utiliser comme il se doit. C'est transparent pour l'utilisateur. Sauf que vos barrettes de mémoires vous diront merci (et vos disques dur vont faire la gueule :septic: ).
imf_copy
Comme expliqué dans la documentation, il faut utiliser un utilitaire en ligne de commande: imf_copy. :RTFM:
Il est situé dans:
C:\Program Files\Autodesk\Maya2010\bin\imf_copy.exe
Pour avoir la documentation de ce petit outil, dans Maya, tapez F1 puis naviguez dans:
mental ray -> mental ray for Maya reference -> Apendix (en bas de la page) -> Command Line Interface -> Image Copy: imf_copy
Sinon, le lien complet:
C:\Program Files\Autodesk\Maya2010\docs\Maya2010\en_US\mr\manual\node249.html
C'est le genre de page que je vous invite à placer en favoris :sourit:
imf_copy: Traduction de la documentation officiel
Une fois de plus, je me suis "amusé" à traduire la documentation de cet utilitaire: :baffed:
Image Copy: imf_copy
L'utilitaire de copie et de conversion d'image imf_copy s'utilise de la façon suivante:
imf_copy [options] fichierSource fichierSorti [type de fichier de sorti]
Le fichier "fichierSource" sera copié vers "fichierSorti". Le "type de fichier de sorti" spécifie le format de fichier de "fichierSorti". Si aucun type n'est indiqué, il sera choisi en fonction de l'extension de "fichierSorti". Voir la page "picformats" (Ndt: Dans la documentation mental ray) pour une list des formats supportés. Le format "map" est particulièrement utilisé pour créer des textures "mappable en mémoire". Les options suivantes sont supportés:
-h
Affiche un bref résumé des options.
-p
Créé une texture pyramidale contenant différentes "versions" de la texture. Chaque version est en fait la texture de la version précédente divisé par deux. Le tout est contenu dans un seul fichier. Cette technique (Ndt: très utilisé dans le jeu vidéo, cf: Mipmapping) permet d'obtenir un meilleur anti-aliasing. Voir la page "imfcopyp" (Ndt: Dans la documentation mental ray) pour plus d'informations. Une version de plus en plus petite de l'image est créé a partir de la version précédente (plus grande) en utilsant un filtre de type "box" sur environs 4 pixels.
-v
Verbose. Affiche ce que fait imf_copy quand il est exécuté ainsi que sa version.
-g gamma
Effectue une correction du gamma avec le facteur donné. La valeur par défaut est 1.0.
-q quality
Quand on écrit un fichier JPEG, ce paramettre défini la qualité sur un écart de 1 à 100. La valeur par défaut est 75.
-f filter
Utile uniquement si le fichier de sorti est un .map. La valeur du filter est sauvé dans la texture. Les fichiers de textures "mappable en mémoire" utiliseront cette valeur même si une autre valeur est déclaré dans le .mi ou avec la fonction mi_api_texture_set_filter. (Ndt: Compris que la moitié mais on s'en fout, on ne l'utilise jamais)
-e
Si on souhaite redimensionner une image d'un certain format à un autre format avec moins de bit par pixel, cette option effectue une erreur de diffusion au lieu d'une "troncature" (Ndt: Pas bien compris non plus mais je suppose que c'est quelque chose qui à été ajouté à la suite pour éviter les arrêts du programme sur un problème de conversion de format de pixel. Je ne l'ai jamais utilisé).
-L
Quand on écrit un fichier .map "memorymapped", cette option utilise ordre de byte "little-endian". Pour être efficace le fichiers .map doivent avoir l'ordre des bytes identique à la machine qui les utiliseront (Ndt: sinon elle passeront par l'étape d'ouverture, lecture, écriture sur le swap). Les processeurs de type Alpha et x86 sont de type "little-endian"; La plupart des autres sont de type "big-endian".
-B
Quand on écrit un fichier .map "memorymapped", cette option utilise l'ordre de byte "big-endian".
-r
Quand on écrit un fichier .map "memorymapped", cette option organise les pixels en rectangle au lieu de l'ordre habituel "a la queu-leu-leu". Ceci augmente l'efficacité du cache et réduit l'utilisation de la mémoire pendant le rendu. Les fichiers créés de cette façon ne peuvent être rendu qu'avec mental ray 3.2 et suivant, c'est pourquoi cette option n'est pas activé par défaut. (Ndt: A la lecture de la documentation, on comprend bien que si c'était possible, cette option serait activé par défaut. Utilisez la donc par défaut.)
-c
Quand on écrit un fichier .map "memorymapped", cette option rassemble jusqu'à 20 fichiers donnés pour former une pyramide d'images, mipmap (Ndt: Nous verrons dans un futur billet l'intérêt de cette commande qui nous permettra de fabriquer une "map de debug"). Cette option permet donc de "contrôler" la création de notre .map d'images pyramidales comparé à l'option -p qui créé automatiquement chaque niveau de la pyramide à la moitié de la résolution du niveau précédent en utilisant un filtre de type "box". La première image donnée devra avoir la plus haute résolution, la seconde environs la moitié, la suivante le quart, etc... Les fichiers créés avec cette option peuvent être lu avec n'importe quelle version de mental ray 3.x.
-x N
Extrait le niveau N du .map pyramidale. Le premier (et plus grand) niveau est 0; Le plus élevé est le 19. Cette opération peut être considéré comme l'inverse de l'option -c, mais elle marche également avec des .map pyramidales créés avec -p.
-k K
Quand on écrit un fichier OpenEXR, K définie la methode de compression, ou K peut prendre les valeurs suivantes: none, piz, zip, rle, pxr24. La valeur par défaut est rle.
Convertir nos textures en .map
A la suite de cette traduction, nous somme capable de trouver facilement la ligne de commande à utiliser pour convertir nos textures:
imf_copy -p -r myTexture.png myTexture.map
"easy as one-two-three" :laClasse: Il ne vous reste plus qu'a ouvrir votre scènes et à pointer vers vos nouvelles textures ".map" et mental ray se chargera tout seul du reste.
Suite?
Ce billet introduit quelques autres billets que je compte faire (un jour :siffle2: ). Voici un aperçu:
- Script qui génère automatiquement les versions .map des fichiers images en comparant leurs ages. Et ce, dans toute la hiérarchie d'un dossier donné (récursif).
- Création d'un fichier .map de debug qui affiche une image différente à chaque niveau de la texture pyramidale.
- Analyse et optimisation du fonctionnement de "mental ray for Maya" grâce à la map de debug que nous auront créé.
- Surement d'autres trucs...
Voila, j'espère que ce billet en aidera quelques uns d'entre vous. N'hésitez pas à me faire remarqué si je n'ai pas été assez clair ou si vous pensez que certains points méritent quelques éclaircissements.
A bientôt!
Commentaires
je m'en servais (des .map) sans comprendre vraiment comment ça marche .... merci pour tes explications .
Très content que ça puisse servir :)
Très instructif, merci pour ces précisions!
Qu'en est-il des textures en séquences d'images .map? Quelqu'un a tenté? Y gagne-t-on vraiment?
Dans le cas très particulier des textures en séquence d'image, il faut savoir que mental ray décharge les textures dont il n'a plus besoins.
En gros, la charge mémoire ne doit pas augmenter à cause de ça.
A priori, si il peut supporter une des textures (en non .map) de la séquence d'image, il peut toute les supportés. Et rendre l'animation sans problème. (Exception fait du motion blur qui peut réclamer plusieurs images de la séquence, à vérifier).
Dans la pratique, ormis si la texture (en séquence d'image) est vraiment grosse, l'intérêt de convertir la séquence en .map est discutable...
A cette échelle, ça devient plus une contrainte qu'un vrai gain de temps, je ne le conseillerait donc pas (pour une utilisation "standard").
Bon courage! ;-)
Oups, désolé de ne pas avoir répondu plus tot!
Donc, après de plus amples tests, il s'avère que mes scènes bénéficient beaucoup du format .map, en séquences d'images ou non. En effet, ces scènes sont très gourmandes en ram (beaucoup de géométrie et de textures, parfois grandes, rendu en hd1080), et je suis contraint de travailler sur un WinXP 32 bits (argh!), donc la moindre "aide" est la bienvenue, je pense surtout au coté pyramidal des .map. Même si je suppose que dans la plupart des cas la séquence .map doit etre un fardeau plus qu'autre chose.
Merci beaucoup pour toutes ces informations, ce blog est un plaisir à lire!
Merci :)
Un truc que j'ai du mal à saisir, c'est comment importer les fichiers MAP ensuite ?
Si je tente de remplacer mes JPG, PNG, etc, .... je me rend compte que l'extension .MAP n'est pas reconnue....
N'ayant jamais utilisé les fichiers MAP, je ne sais pas comment les importer..... :(
Je n'ai pas bien compris ce que tu entendais par "importer". :-(
Dans Maya, il suffit de pointer un node "File" sur le fichier .map et il l'utilisera automatiquement lors du rendu.
Un fichier .map n'a pas pour objectif d'être ouvert par autre chose que mental ray. Donc n'essais pas de l'ouvrir (si c'est sa ta question).
Considère un fichier .map comme une sorte de copie de ton jpg ou png, spécialement fait pour mental ray. :)
bonjour à tous je sais que ce post ça fait déjà un petit moment j'adore super bien expliqué mieux que dans des beaucoup des sites juste une chose je sais pas si c'est moi je relue plusieur fois et jai pas compris comment convertir ou mettre "imf_copy -p -r myTexture.png myTexture.map" je sais pas si je l'ecrit dans maya si je créer un .bat enfin je suis plus tellement désolé!
je fait double clic sur imf_copy.exe c la fenetre cmd qui se ferme de tout suite ....enfin c peut etre moi jai tout compris mais comment exécuter hehehe je suis désolé mais jarrete pas de tante un tas des trucs et maniere mes jarrive toujour pas...jarrive à change dans maya les preference convertir en map mais je peut pas gérer les option gerns p- ou r- ....voilà merci pour les info
J'ai hésité avant de répondre mais là je ne peut pas ne rien dire. :neutral:
D'une parce j'essaie de toujours répondre aux commentaires.
De deux parce que ton commentaire est assez illisible, très mal écrit et sans ponctuation.
Mes billets ne sont pas des références en terme d'orthographe et de conjugaison mais pour le coup aider quelqu'un qui ne prend pas forcément soin de bien poser sa question n'est pas super motivant. :pasClasse:
Je t'invite donc à reformuler ton problème correctement, avec de la ponctuation et des phrases corrects et je me ferais un plaisir de répondre! :sourit:
Pour plus d'informations:
http://fr.wikipedia.org/wiki/Nétiq...
Salut Dorian !
Il se trouve que je passe souvent sur ton blog, et cette page m'avait déjà interpellée par le passé.
J'utilise mentalRay (wouuuuu il est pas sur vray) pour un projet dans l'espace, j'ai stitché 2048maps de 512k (pas à la main hein) pour une sortie finale de 32k*16k. Cà me fait une jolie map de nuages !
Ensuite, vient la phase de conversion en .map.
Et bien au dessus de 30k, imf_copy ne veut plus rien savoir, et te fais un joli <access violation>
Du coup, je me suis dis "mais Dorian, il a dit qu'il avait fait un test à 80k, comment il a fait ?".
Donc ma question est la suivante => comment t'as fait ???
Pour l'instant, ma solution, c'est de faire une map en 29k, là çà passe nikel (mais je suis triste...)
Puisse ta lumière éclairer le chemin brumeux de ma connaissance.
Hello Kern!
Bon, ben écoute tu m'a collé. Pour être honnête, le souvenir du 80k c'était en deuxième année de mes études d'infographie. Ça fait un baille donc.
J'ai tout de même le souvenir que ça avait pris du temps sur mon ordi à l'époque. Après, en y repensant, ça fait énorme quand même...
J'ai essayé avec du tiff là mais je me suis rendu compte qu'il y avait une limitation de taille:
http://verylargeimages.blogspot.com...
37K
En plus c'est le double fail car imf_copy supporte pas le tiff...
Donc de ce que je me rappel, j'avais créé un fichier photoshop blanc vide sauvé en jpeg (ou bête bmp...) et converti avec imf_copy...
Ton imf_copy, il est en 64bits? Utilise tu bien le flag -r pour tiler la map?
Sinon, la solution de secours serait de convertir en plusieurs maps: Si ta map fait 32k*16k, sort en plusieurs de 16k*8k. :D
Bref, tiens moi au courant. Je vais essayer de voir de mon coté mais soit pas trop pressé de ma réponse... ^^'
Salut Dorian !
Merci de ta réponse rapide !
Très intéressant ce blog sur les "very large images", pleins d'infos utiles.
Pour mon petit problème, je me suis contenté de "seulement" 30k, pas trop le temps de fouiller pour trouver la soluce.
Je suppose que mon imf_copy est en 64bits, j'ai testé avec celui de de maya 2011 et 2012, les deux en x64.
Et oui j'utilise bien le flag -r.
J'ai aussi essayé depuis nuke de sortir un tif de 64k compressé, mais une fois que le fichier atteint les 6Go, la machine arrête le calcul (testé sur 2 bécanes), la ram sature (12Go).
Je referais un test le mois prochain quand j'aurais mes 64Go de Ram :D et en réfléchissant mieux au workflow.
Je viendrais donner des news sur cette page.
A + et merci !
Ok d'acc! ^^'
Sinon encore une fois, découpe en plusieurs morceaux! :hehe:
Salut! Merci beaucoup pour ce billet fort intéressant,juste pour une petite précision,je suis sous Maya 2014,et j'utilise des .map convertis avec le imf_copy de la version 2012,j'ai checké les renderlogs par curiosité et là quelle ne fût pas ma surprise de voir affiché que mon fichier .map était obsolète,y a t il eu des évolutions et des changements (désolé si j'ai mal compris un truc,c'était juste par curiosité ^^)
Hello! :)
Le billet date de 2009, maintenant il est conseille d'utiliser des exr tiled/mipmapped.
Regarde ici pour plus d'infos.
Le principe reste le même cela dit. :)
Merci beaucoup pour la rapidité de ta réponse,et pour la qualité de tes billets,étant prof généraliste avec maya cela m'aide beaucoup :)
:sourit:
Bonjour Dorian,
J'avais peur que 2014 soit trop tard mais heureusement lune a déterré le billet. ^^
Mon soucis est que j'aimerai convertir une .map en .jpg
J'ai reçu des textures en .map, et voulant modifier les UVs je suis "eu" vu que les .map ne s'ouvre pas.
Je suis sur que c'est possible vu que certaines options comme -x ou -q prouvent que l'on peux convertir un .map en autre chose. J'ai donc créé mon p'tit .bat avec ça :
imf_copy -x 0 -q 100 toto.map toto.jpg
...et malheur : ça ne marche pas ! Damn ! Du coup je farfouille le net mais à part toi (et des forums de GPS qui utilisent des .map, mais pas vraiment les mêmes... ^^) pas beaucoup de monde cherche à extraire des jpgs ou png de .map :/
Du coup, si t'as une idée, vu une grosse faute dans ma ligne ou une suggestion, je t'en serai énormément reconnaissant !
Merci d'avance ;)
Mathieu
Re, avant de publier mon post, j'ai trouvé mon erreur :
En fait le imf_copy avait du mal avec 2 choses :
Le .jpg qu'il n'arrivait pas à créer à cause du rgba to rgb -> j'ai pas trop compris, donc j'ai mis un png à la place sans trop chercher à comprendre.
Le -x 0 ou -x 1 qui me faisait l'erreur "fatal 101500". J'ai tenté avec un -x 5 et j'ai eu mon png de 2048x2048 ! Donc -x 1 devait être trop grand :)
Du coup me voilà content ^^
Merci encore pour ton blog, c'est fou à chaque fois que je rencontre des soucis ou des questionnements sur maya, Google me remmène sur ton blog et 9 fois sur 10 un de tes articles résout mon problème !
T'es génial mec ;)
Hehe ravis de voir que tu a trouve la solution tout seul (et surtout que tu la partage ici). :)
Et content que mon blog te plaise.
A bientot! :)