| IntroductionQui 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.
 
 
InstallationCommenç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 pasFamiliarisons 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:
 
Options globales pour toutes les images (frames)
(résolution, anti-aliasing, etc.)
FrameBegin
Initialisation du contexte graphique d'une image (nom de fichier, 
niveau de détail,etc )
Attributs du contexte graphique pour l'image (par exemple, 
 les lumières, le type de projection,etc )
WorldBegin
Modification du contexte graphique et définition des objets de la scène
 à calculer. 
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).
FrameEnd. Le contexte graphique est restauré à son état du (2).
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/.
 
ConclusionsL'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... :)
 |