Sommaire Index Rechercher Liens A Propos
[LinuxFocus Image]
[Barre de Navigation]
  Nouveautés   Archives

RenderMan

par Carlos Calzada Grau


Introduction

Installation

Premiers pas

Conclusions

Introduction

Qui n'a jamais entendu parler de Pixar?, Qui ne connaît pas le film Toy Story?. Pixar Animation Studios est reconnu depuis longtemps pour son travail d'animation assistée par ordinateur. Luxo Jr. (1986) a été le premier film en images de synthèse nominé pour un Oscar et il a reçu plus de 20 prix dans des festivals cinématographiques internationaux.

En 1987, Red's Dream reçu de nombreux prix au Festival d'Animation de Zagreb et au Festival International du film de San Francisco.

Le premier film d'animation à être récompensé par un Oscar fût Tin Toy (1998), pour lequel Pixar réalisa une modélisation du visage d'un bébé qui comportait plus de 40 muscles contrôlés par l'animateur.

En 1989 Knick Knack sortit de leurs studios, il s'agit de l'histoire d'un bonhomme de neige qui vit à l'intérieur d'une boule de cristal. Ce film a d'abord été réalisé en 3D, mais une version traditionnelle a aussi été distribuée.

Bientôt suivirent un certain nombre de succès dont le film Toy Story. Il s'agit de l'un des premiers longs métrages produit en intégralité sur ordinateur. Sur le site de Pixar vous pourrez trouver des informations supplémentaires, comme la date de sortie prévue pour Toy Story II quelquepart en 1999.

Pixar a développé l'interface Renderman pour séparer le développement des 'modeleurs' et des moteurs de rendu 3D. Le modeleur est l'outil utilisé pour réaliser des scènes, construire des animations, etc. Le seul rôle du moteur de rendu (renderer) est de générer une image à partir de la description du modeleur en calculant tous les détails comme les ombres, les lumières, les textures,etc.

Renderman permet aux infographistes de définir l'image qu'ils vont obtenir, mais pas comment son calcul sera réalisé. Cela signifie que le modeleur n'a pas à se préoccupper du calcul de l'image. De la même façon, un moteur de rendu conforme aux spécifications du standard Renderman peut utiliser les techniques de Z-Buffer, scan-line , lancer de rayon, radiosité ou toute autres méthode pour "dessiner" les objets car cette étape ne dépend pas de la norme. On peut voir l'interface Renderman comme un format pour les descriptions de scènes, de même que Postscript est un format de description de pages. Ce standard est indépendant des matériels et des systèmes d'exploitation.

        
The RenderMan@ Interface Procedures and RIB Protocol are:
Copyright 1988, 1989, Pixar.
All Rights Reserved.
RenderMan@ is a registered trademark of Pixar

L'objectif de cet article est de présenter rapidement l'interface RenderMan, et pour cela nous utiliserons les logiciels Blue Moon Rendering Tools de Larry Gritz. Ce moteur de rendu est librement redistribuable (la version binaire, pour un usage personnel), des versions existent pour de nombreux systèmes dont Linux (en fait il s'agit d'une des premières adaptations réalisées), il exploite le lancer de rayon et la radiosité et n'a que peu à envier à Photorealistic RenderMan (PRMan), le produit commercial de Pixar.

Tout d'abord les systèmes de coordonnées sont les mêmes pour la scène et la caméra, il s'agit du système dit de la main gauche (LHS - Left Hand System, comme pour Pov-Ray), avec lequel l'origine est au centre de l'écran, l'axe des abscisses (X) à droite, l'axe des ordonnées (Y) vers le haut et la quote (Z) dirigée vers l'intérieur de l'écran. L'illustration qui suit montre la caméra utilisée par défaut (l'axe des X est rouge, l'axe des Y vert, et l'axe des Z bleu, cliquer sur l'image pour voir le code source). Le système dit de la main droite (RHS) est identique sauf pour le sens de l'axe des Z qui est inversé.

Avec Pov-Ray le système de coordonnées de la scène est fixe et c'est la caméra et les objets que l'on peut déplacer dans le monde virtuel en utilisant des transformations. Pour Renderman, c'est l'inverse, la caméra est fixe et c'est le système de coordonnées de la scène que l'on modifie pour changer le point d'observation. Un exemple va rendre tout cela plus clair.

RenderMan possède de nombreuses primitives, pour définir des objets, des sources de lumières, ... nous allons voir maintenant le format des quadriques, mais il y en a d'autres aussi fameuses (par exemple les patches de bézier, les polygones,...)

   Disque    hauteur    rayon    thetamax 

    Disque     5            10            300 

    Cône    hauteur    rayon    thetamax 

    Cône    15            10            300 

Cylindre    rayon    zmin    zmax    thetamax 

    Cylindre    10            -5        10        300 

 Sphère    rayons    zmin    zmax    thetamax 

    Sphère     10        -4            8            300 

Tore    major rad    min rad    phimin    phimax    thetamax 

    Tore    10                    4                90            320            300 

Paraboloïde    rayon    zmin    zmax    thetamax 

    Paraboloïde     10            4            15        300 

   Hyperboloïde    point1            point2        thetamax 

    Hyperboloid    0 10 -5        10 5 15        300 

Le lecteur a peut être déjà remarqué que le format de certaines de ces primitives n'est pas particulièrement simple, mais si l'on considère que le fichier RIB est généré par un modeleur, le format s'avère adapté par sa concision et sa puissance.

Installation

Commençons par visiter la page des Blue Moon Rendering Tools et téléchargeons le programme. A l'heure où j'écris, la version courante est la 2.3.6 et pour la décompresser on procède comme habituellement :
rabit:~/$ gzip -d BMRT2.3.6.linux.tar.gz
rabit:~/$ tar xvf BMRT2.3.6.linux.tar

Après la décompression et le désarchivage on obtient un nouveau répertoire nommé BMRT 2.3.6. Il contient les exécutables (dans bin/), les exemples (dans examples/) et la documentation en format PostScript et HTML (sous doc/), il y a aussi un fichier README qui contient des informations additionnelles sur le programme. Suivez la procédure d'installation décrite dans le fichier README, elle est simple et ne devrait pas poser de problème.

Premiers pas

Familiarisons nous avec le langage de RenderMan en examinant un exemple typique (../../common/May1998/disptest.rib). L'image est générée par la commande rendrib -v ../../common/May1998/disptest.rib (cliquer sur l'image pour la visualiser au format 1024x768 et avec l' anti-aliasing 2x2).

Ce fichier fait partie des nombreux exemples que l'on peut trouver dans le sous-répertoire examples/ de BMRT (Blue Moon Rendering Tools) et l'on peut remarquer que le fichier source n'est pas très long (lorsque l'on passera aux animations vous verrez les fichiers grossir considérablement)

Il y a plusieurs exécutables sous bin/: rendrib, rendribv et rgl. Rendrib est le programme de rendu à proprement parler, rendribv permet de calculer les scènes en mode fil de fer, et rgl en mode polygone. Les deux derniers programmes sont utilisés pour prévisualiser les objets et les animations en cours d'élaboration, mais le rendu final doit toujours être réalisé avec rendrib.

Le format des fichiers RIB (Renderman Interface ByteStream) est très simple, ce qui ne l'empêche pas d'être puissant. Il s'agit de fichiers texte (exactement comme Pov-Ray). Un fichier RIB bien écrit doit contenir:

  1. Options globales pour toutes les images (frames) (résolution, anti-aliasing, etc.)
  2. FrameBegin
  3. Initialisation du contexte graphique d'une image (nom de fichier, niveau de détail,etc )
  4. Attributs du contexte graphique pour l'image (par exemple, les lumières, le type de projection,etc )
  5. WorldBegin
  6. Modification du contexte graphique et définition des objets de la scène à calculer.
  7. WorldEnd. Qui implique les conséquences suivantes : L'image est calculée et sauvegardée, tous les objets et les sources de lumières déclarés au (6) sont détruits, et le contexte graphique redevient ce qu'il était en (5).
  8. FrameEnd. Le contexte graphique est restauré à son état du (2).
  9. Les étapes (2) à (8) sont répétées si plusieurs frames sont définies.

Le contexte graphique contient toute l'information nécessaire pour calculer l'apparence d'une primitive. Il se divise en deux parties : une section globale qui reste constante d'une primitive à l'autre et un contexte courant qui change avec les primitives. Les paramètres du contexte global sont appelés des options et les contextes courants des attributs .

Pour mieux comprendre ces options et attributs, et pour se faire une idée de la façon dont on décrit une scène avec RenderMan, suivons ligne par ligne l'exemple précédent. Cela constituera un bon tutoriel qui montrera ce que l'on peut faire et comment on le fait.

 1.-  ##RenderMan RIB-Structure 1.0   
 2.-  version 3.03   
 3.-   
 4.-  ###########################################################################   
 5.-  #   
 6.-  # This RIB file demonstrates some more complex procedural textures.   
 7.-  # Two spheres show the use of "stucco" and "dented" displacement shaders.   
 8.-  # The floor shows the gmarbtile_polish shader, which is polised green   
 9.-  # marble tiles.  Note that the reflection is accomplished by the shader   
 10.- # actually calling the trace() function, rather than reflection mapping.   
 11.- #   
 12.- ###########################################################################   
 13.-   
 14.- Option "searchpath" "shader" [".:../shaders:&"]   
 15.- Display "balls2.tif" "file" "rgb"   
 16.- Format 400 300 -1   
 17.- PixelSamples 1 1   
 18.-   
 19.- Declare "prmanspecular" "integer"   
 20.- Option "render" "prmanspecular" [0]   
 21.- Projection "perspective" "fov" 35   
 22.- Translate 0 -0.55 8   
 23.- Rotate -110 1 0 0   
 24.-   
 25.-   
 26.- WorldBegin   
 27.-   
 28.- LightSource "ambientlight" 1 "intensity" 0.02   
 29.-   
 30.- Declare "shadows" "string"   
 31.- Attribute "light" "shadows" "on"   
 32.- LightSource "distantlight" 1 "from" [0 1.5 4] "to" [0 0 0] "intensity" 0.6   
 33.-   
 34.- AttributeBegin   
 35.-   Declare "txtscale" "float"   
 36.-   Declare "Kr" "float"   
 37.-   Declare "darkcolor" "color"   
 38.-   Declare "lightcolor" "color"   
 39.-   Declare "veincolor" "color"   
 40.-   Surface "gmarbtile_polish" "Ka" 1 "txtscale" 0.5 "Kr" .25 "Kd" 0.3 "Ks" 0.2 "roughness" 0.02   
 41.-   Patch "bilinear" "P"  [ -5 -5 0 5 -5 0 -5 5 0 5 5 0  ]   
 42.- AttributeEnd   
 43.-   
 44.- AttributeBegin   
 45.-   Color  [ .6 .6 .6 ]   
 46.-   Translate -1.5 0 1   
 47.-   Surface "matte"   
 48.-   Declare "frequency" "float"   
 49.-   Declare "Km" "float"   
 50.-   Displacement "stucco" "frequency" 20 "Km" 0.3   
 51.-   Sphere 1 -1 1 360   
 52.- AttributeEnd   
 53.-   
 54.- AttributeBegin   
 55.-   Translate 1.5 0 1   
 56.-   Color 1 .45 .05   
 57.-   Declare "Kr" "float"   
 58.-   Declare "Km" "float"   
 59.-   Surface "shiny" "Kd" 0 "Kr" 0.25 "roughness" 0.15 "specularcolor" [1 .5 .06]   
 60.-   Displacement "dented" "Km" 0.5   
 61.-   Sphere 1 -1 1 360   
 62.- AttributeEnd   
 63.-   
 64.- WorldEnd   

Les commentaires commencent par le caractère #, comme à la ligne 1 et de 4 à 12. Les caractères # peuvent être placés n'importe où dans le fichier et le reste de la ligne est alors ignoré (comme pour // en C++). Les commentaires sont très utiles lorsque l'on édite des scènes à la main car ils nous aident à comprendre les détails de la description.

La ligne montre un exemple de la directive version. Elle déclare la version de l'interface utilisée (3.03); La version la plus récente est la 3.1 qui date de Septembre 1989 (Oui, vous avez bien lu, 1989), mais il y a des revisions de Mai 1995.

Les directives searchpath et shader à la ligne 14 définissent le chemin pour les "shaders", les modules dont le moteur de rendu se sert pour calculer l'apparence d'une matière particulière (matière plastique, transparente,...) Il s'agit d'une des fonctionnalités qui rendent l'interface très puissante puisque les textures des objets fonctionnent comme des Plug-Ins, et qu'il est facile de créer de nouvelles textures, effets... sans attendre une nouvelle version plus puissante du logiciel. En général, on peut utiliser la variable d'environnement SHADER pour indiquer l'emplacement de ces fichiers, et il n'est alors plus nécessaire de le déclarer explicitement.

L'option Display est utilisée ligne 15. Elle définit le nom du fichier de sortie "balls2.tiff" et son format, ici RGB avec "file" "rgb".

A la ligne 16, nous choisissons la résolution (la taille) de l'image à calculer, à la suite de l'option Display. Dans cet exemple, la résolution demandée est 400x300, et le -1 correspond au format (aspect ratio) du pixel (en fait ce devrait être +1, je ne sais pas pourquoi on trouve -1 ici).

Ensuite vient l'échantillonnage horizontal et vertical réalisé pour chaque pixel, c'est à dire le nombre de rayons lancés pour calculer la couleur d'un pixel. La directive PixelSamples 2 2 provoque le lancer de 4 rayons pour chaque pixel, ce qui permet d'obtenir une image de bonne qualité (avec de l'anti-aliasing), mais également des temps de calculs plus longs. Dans notre cas, un échantillonnage de 1 x 1 = 1 accélère les calculs en ne lançant qu'un rayon par pixel.

La ligne 19 déclare la variable entière prmanspecular, ou plutôt prmanspecular est défini comme un mot clé et à chaque fois que l'analyseur syntaxique rencontrera ce mot clé, il considérera le nombre qui suit comme étant de type entier.


Puis on trouve le choix de la projection dans l'espace, cet exemple spécifie une projection en perspective avec la directive "perspective" et une angle de vue ("fov" = field of view) de 35 degrés.

La caméra est positionnée aux lignes 22 et 23. On trouve d'abord une translation, suivie par une rotation, mais comme toutes les transformations sont réalisées en vidant une pile, la première transformation réalisée est en fait la dernière définie, et la rotation précède la translation ( dans ce cas toutes les transformations sont exécutées lorsque RenderMan rencontre la directive WorldBegin ). Dans l'exemple, on effectue une rotation de -100 degrés autour de l'axe X ( pour tourner autour de l'axe Y, il faut écrire Rotate 45 0 1 0), puis ont translate de -0.55 unités le long de l'axe Y et de 8 unités le long de l'axe Z. Rappelez vous que ces transformations (rotation et translation) s'appliquent au centre des coordonnées de l'espace plutôt qu'à la caméra. (note du traducteur anglais: OpenGL utilise la même convention pour les transformations). Les images suivantes illustrent les différentes étapes de l'application des deux transformations.

Après les préliminaires précédents, on trouve la scène elle-même (c'est à dire les déclarations des objets, des éclairages...). Toutes les scènes doivent commencer par WorldBegin et finir par WorldEnd (que l'on trouve ici respectivement aux lignes 26 et 64). Les premières lignes (28 à 32) de notre exemple définissent les sources de lumières; chaque source de la scène doit être numérotée de façon unique, la première étant la source de lumière ambiante sont l'intensité est ici de 0.02. Ensuite la variable shadows est déclarée comme une chaine de caractères et l'option de calcul des ombres est activée. La ligne 32 crée une source de lumière de type distantlight (une source de lumière située à une distance infinie comme le soleil) en réutilisant le numéro 1; comme nous l'avons vu précédemment, ce nombre devrait être différent, cela fonctionne tout de même ici car BMRT semble ignorer la numérotation des sources de lumières, mais pour assurer la compatibilité (par exemple avec PRMan de Pixar), il faut respecter strictement l'interface. L'intensité de la seconde source de lumière est la même que pour la première (ce sont des attributs communs) et le vecteur direction défini par les champs from et to, génère des rayons parallèles, comme dans le cas de la source distante.

Maintenant nous rencontrons les trois objets élémentaires qui constituent la scène, chaque objet est séparé par une paireAttributeBegin AttributeEnd car chacun d'eux a ses propres caractéristiques de position et d'apparence. Si la seule caractéristique différente entre les objets était la position, on aurait pu déclarer la texture à l'extérieur et déclarer les objets avec TransformBegin et TransformEnd. Le premier objet (lignes 34 à 42) est un patch et un patch peut être : uniforme ou non uniforme, rationnel ou non rationnel, bilinéaire ou bicubique (ce qui conduit aux patches de Bézier et aux Bsplines... (Tout bon livre d'infographie. aidera à comprendre ces primitives). Dans l'exemple nous avons un patch bilinéaire composé de quatre points : Il est défini avec la directive "P" suivie des coordonnées (x,y,z) des points. La texture de l'objet est spécifiée par la directive Surface, dont le premier argument est un fichier shader et les arguments suivants dépendent du shader choisi. L'image ci-dessous présente l'image que l'on obtient :

Les lignes 44 à 52 ajoutent d'autres objets à la scène : Une sphère (ligne 51) dont la couleur est déterminée par la directive Color [R G B]. Cette sphère est translatée et on lui donne ici pour type de surface matte. Puis vient la fonction la plus importante de BMRT, les shaders de déplacements. Leur effet est comparable aux bump-maps de Pov-Ray sauf que BMRT ne simule pas ces "bosses" qui sont bien réelles ! Enfin le dernier effet rend la surface et les bordures de la sphère irréguliers. Les shaders de déplacements s'utilisent comme les shaders de textures, en faisant suivre leur nom de leurs paramètres. La description de la sphère est un peu étrange : On trouve d'abord le rayon, puis zmin et zmax qui délimitent (clipping) la sphère le long de l'axe Z (par exemple avec les valeurs -1 et 1 on ne modifierait pas la sphère mais avec 0 et 1 on la couperait en 2), et le dernier paramètre définit l'angle "occuppé" par la sphère (360 pour la sphère complète, 180 pour une demi,...). Voici une image de la sphère de l'exemple :

L'objet suivant ressemble au premier, seuls la texture et la position diffèrent, et comme je ne vais pas répeter les mêmes explications, lançons le calcul et regardons ce que nous obtenons :

Nous avons atteint la fin du fichier. Maintenant, on peut dire que le développement de scènes n'est pas difficile, mais une scène complexe ou une animation nécessitent des fichiers très gros. Ce problème peut être contourné en utilisant un modeleur qui supporte RenderMan (tous les bons modeleurs peuvent exporter au format RIB) ou alors programmer une animation en C. La distribution de BMRT est fournie avec un répertoire include qui contient tous les bibliothèques nécessaires. Celles-ci contiennent des fonctions qui écrivent des directives RIB sur la sortie standard. Les deux méthodes se ressemblent : A WorldBegin du fichier RIB correspondra une fonction RiWorldBegin() dans votre programme C (Si vous êtes interssé, lisez RenderMan for Poets, document fourni dans le répertoire doc/.

Conclusions

L'interface RenderMan est très puissante et Toy Story a vraiment été réalisé avec elle (en utilisant le modeleur marionet). Sur le site www.toystory.com, on peut trouver diverses informations sur le film. La spécification de l'interface est disponible sur giga.cps.unizar.es. En plus des spécifications,on peut y trouver le manuel de PRMan (Le Produit de Pixar) et aussi quelques exemples.

Dans le prochain article nous modelliserons un petit objet, et nous utiliserons la bibliothèque C pour apprendre à l'exploiter et également pour faciliter le passage à l'animation par la suite. Le petit objet de l'animation pourrait être le pingouin de Linux ou peut-être Bill Gates (ou même les deux ensemble si nous faisions désintégrer le deuxième par le pingouin... :)


Traduit par Cyril M. Hansen

Pour en savoir plus:

 

© 1998 Carlos Calzada Grau
This web site is maintained by Miguel A Sepulveda.