:longBar:

Sommaire

:longBar:

Le format OpenEXR

Features (yeah yeah!)

Le format OpenEXR, qui existe depuis quelques années maintenant, s'est imposé petit à petit pour devenir le format d'image CG de référence.

Ses avantages sont indéniables:

  • Open Source (sans ça il n'aurait clairement jamais décollé) :siffle: .
  • Plusieurs précisions de pixel possibles.
  • Un grand nombre de formats de compression.
  • Multichannels de différents types.
  • Images en scanline ou "tile" (c'est ce qui va nous intéresser).
  • Mipmap ou Ripmap.
  • etc... (pour plus d'informations, je vous invite à lire le pdf Technical Introduction to OpenEXR)

Mais sa capacité à "tout" faire, peut le rendre complexe d'un point de vue utilisateur.

Eux y(x) sert à tout faire!

J'suis mort avec rire avec mon minable jeu de mot là! :baffed:

Oui, le format EXR n'a pas pour seul objectif d'être utilisé pour des images rendues. Il peut aussi être utilisé en tant que texture. C'est précisément pour cette raison qu'il dispose de fonctionnalités tel que mipmap et "tile".

Je ne réexplique pas à quoi sert les mipmap, je l'ai déjà fait dans un billet précédent.

En revanche, je ne crois pas avoir donné de précisions sur le "tile". Je vais donc rapidement expliquer le principe.

:longBar:

Le tile

Explication

Le principe du tile est de sauver les images par petits paquets (des buckets). Si vous avez lu mes billets sur les maps mental ray vous devriez comprendre assez vite l’intérêt.

Le plus simple pour comprendre la raison d'être du "tile" est par l'exemple.

Supposons que vous fassiez des textures en 8192x8192 et que vous en ayez des centaines dans votre scène. :grenadelauncher:

Imaginez ensuite que dans votre scène, vous ayez un mur en gros plan qui utilise un material composé de 5-6 textures (bump, specu tout çà):

camera_mur_exemple001.png

Même avec les mipmaps, si votre mur est en gros plan, cela veut dire qu'il va devoir charger le niveau le plus haut de la map (8192x8192) pour chaque texture a utiliser (bump, specu...), et ce, même si on ne voit qu'une petite partie de la texture.

L'idée ici est de bien comprendre qu'on ne va pas les mettre dans la ram...

Et bien la solution est de découper l'image (ou dans le cas des mipmaps, chaque niveau des mipmaps) en petits bucket (en général 64x64) qui seront chargés indépendament du reste de l'image (ou du "niveau" dans le cas des mipmaps).

Dans notre exemple du mur, il ne chargera que les paquets de pixels à utiliser. Evitant ainsi de charger tout le niveau de la mipmap.

Cette méthode permet de s'affranchir des limites de taille des textures dans les logiciels de rendus (Vous pouvez essayer, en mental ray, de faire des maps de 80000x80000, je l'ai fait, ça marche impec! :baffed: ).

V-Ray, qui supporte très bien cette feature offre une petite explication aussi ainsi qu'un outil pour convertir des images en EXR tiled.

Mental ray supporte également cette feature depuis longtemps. Et, avec le fichier .exr depuis Maya 8.5.

Maya Station, un blog maintenu par certains développeurs de Maya en parle un peu.

Le problème du tile

Bon, c'est cool ça mais on s'en fout, on veut calculer des images et les mettre dans un logiciel de compo et que ce soit rapide. :pasClasse:

Oui, sauf que le soucis est qu'il est impossible de sortir des images EXR en scanline des moteurs de rendu. La majorité écrivant dans leur buffer en tile justement (petite explication pour V-Ray ici).

La seule solution est de repasser ses images en scanline (les pixels sont à la queue leu leu) une fois le rendu terminé.

Et là, malheureusement, pas de recette miracle... Il y a très peu d'outils "faciles" qui vous permettent de bien gérer la conversion des images EXR. Pourtant, les méthodes "compliqués" ne manquent pas. :baffed:

:longBar:

Solutions

126062425745.jpg

OpenImageIO

oiioLogo.png

Une lib C++ codé par Larry Gritz (un mec pas connu...). Je vous invite à lire la page 3 du PDF de documentation qui donne toute les raisons historiques (et c'est une sacrés histoire).

Le site ne propose aucun "build" (fichier exécutable). Que des sources:

https://github.com/OpenImageIO/oiio

Cela dit, compiler la lib ainsi que ses petits utilitaires (notamment iconvert qui permet de passer facilement un exr en scanline) est très (très) simple sous linux. Il y a pas mal de dépendances mais ce n'est pas un soucis sur l'OS du manchot!

On récupère les sources, make et hop! C'est bon! :aupoil:

Sous Windows c'est une vraie tanné. :pafOrdi: Pourtant la page d'explication est clair. Mais une fois sur le terrain c'est une autre paire de manche(ot). :tux001:

Au début j'ai voulu faire les choses proprement en compilant le projet en 64bits. Mais il faut avouer que le nombre de dépendances n'aide pas et les binaires précompilés pour Windows ne sont disponible qu'en 32bits (notamment Boost qui n'est pas un truc particulièrement facile à compiler en 64bits sous Windows).

Bref, après quelques heures, j'ai compris que je n'y arriverai pas rapidement. J'ai donc laissé tombé et ai compilé en 32bits. Et ça a marché! :laClasse:

Je vous propose de télécharger les exécutables Win32 compilé par mes soins: OpenImageIO_bin.7z

N'hésitez pas à tester chacune des applications. Elles vous rendront surement de fiers services en prod.

Passer un EXR tiled en scanline

C'est assez simple:

iconvert.exe -v --scanline monExrTile.exr monExrScan.exer

Et voilà! :sourit:

Les compressions

En fouillant un peu dans le code (que je trouve très clair au passage) et dans la doc (qui ne semble pas complétement à jour), page 84, on peut trouver les paramètres de compressions suivants:

  • none: Aucune compression.
  • zip: Compression zlib, par blocs de 16 scanlines.
  • zips: Compression zlib, par blocs d'une seule scanline.
  • rle: Compression "Run Length Encoding"
  • piz: Piz-based wavelet compression.
  • pxr24: Compression (avec perte) en 24bit flottant.
  • b44: Compression (avec perte) par blocs de 4x4 pixels. Taux de compression fixe.
  • b44a: Compression (avec perte) par blocs de 4x4 pixels. Les blocs ayant peu de variations sont mieux compressés.

Ainsi, il suffit d'utiliser:

iconvert.exe -v --compression zips --scanline monExrTile.exr monExrScan.exr

Pour avoir un exr en scanline et compressé. :)

Je n'ai pas testé avec des exr multicouche mais je pense qu'il doit le gérer.

Cette solution est pour moi la meilleur. :marioCours:

Batcher le logiciel de compo

La plupart des logiciels de compo (Nuke, Fusion, etc...) sont capable d'exporter correctement des EXR avec plusieurs channels et une compression correcte, en scanline.

Il n'y a pas de secret, il faut tester et voir si tout ce qu'on souhaite garder est bien présent dans le fichier. Une fois que vous avez une méthode qui tient la route, gardez là! :D

Si vous vous débrouillez bien, vous pouvez scripter chacun de ces softs pour qu'il réenregistre automatiquement vos images exportées de votre moteur de rendu en des EXR scanline. Ainsi vous pouvez lancer la conversion de tout les EXR d'un dossier en ligne de commande directement après la sortie des images. Bien qu'un peu lourde à mettre en place, c'est une solution très efficace et assez utilisé en prod. :sourit:

La grosse contrainte est qu'elle nécessite une licence de votre logiciel de compo par batch (ça fait chère la licence du "converter").

Vray

vray_logo.gif

Je vous ai parlé de l'outil tools_img2tiledexr qui permet de convertir des image en EXR tilé, principalement pour les textures.

Mais il existe également un outil qui permet de convertir des vrimg (le format d'image de Vray) en EXR scanline: tools_vrimg2exr

:longBar:

Conclusion

Si vous trouvez vos fichiers EXR lents dans vos logiciels de compo, "passez les à la moulinette"! :joue:

Je compte enrichir ce billet au fur et à mesure si je trouve des choses plus précises (script, méthode, applications...).

Donc n'hésitez pas à laisser un commentaire si vous savez quelque chose qu'il pourrait être intéressant d'ajouter! :seSentCon:

:longBar:

Liens utiles