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:
-
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/.
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... :)
|