Carlos Calzada Grau L´auteur:
Je suis diplomé en informatique et fou de graphisme depuis mon
premier spectrum . Je suis un fan de Linux et de sa philosophie sur le
développement , et de tout ce qui n'a pas de rapport avec Micro$oft
Sommaire: |
Résumé:
Ceci est le troisième article sur Renderman ( I II ). Cette fois , nous allons voir une des parties les plus importantes : lla possibilité de modéliser et d'animer une scène en "C" ou en "C++".
Notre précédente installation de BMRT (Blue Moon Rendering
Tools) a donné deux nouveaux repertoires lib and include
dans celui ou nous l'avons installé . Ceci contiennent deux fichiers
qui nous intéressent : ri.h qui contient les entêtes
des fonctions "C" et libribout.a qui est la librairie de ces fonctions
. Le fichier d'entête peut être copier dans /usr/local/include
eet libribout.a dans /usr/local/lib (le programmeur expérimenté
peut choisir de les placer ailleurs bien sur) . Après cette petite
installation , nous sommes prêts pour notre premier exemple de programme
.
<
gcc myprogram.c -o myprogram -lribout -lmVoici un exemple de Makefile qui vous fera gagner du temps :
LIBS = -lm -lribout PROGNAME = primero all: $(PROGNAME) $(PROGNAME).o: $(PROGNAME).c gcc -c $(PROGNAME).c $(PROGNAME): $(PROGNAME).o gcc -o $(PROGNAME) $(PROGNAME).o $(LIBS) |
Notre premier exemple construit des axes de coordonnées et une sphère , nous l'appellerons primero.c, dont voici le code:
1 #include <stdio.h> 2 #include <math.h> 3 #include <ri.h> 4 5 void main(void) 6 { 7 int i; 8 int x,y,z; 9 int nf; 10 float slopex,slopey,slopez; 11 12 RtColor Rojo={1,0,0}; 13 RtColor Verde={0,1,0}; 14 RtColor Azul={0,0,1}; 15 RtColor Blanco={1,1,1}; 16 17 RtPoint p1={30,0,10}; /* Position initiale de la sphère */ 18 RtPoint p2={0,20,10}; /* Position final de la sphère */ 19 20 RtPoint from={0,100,100}; /* Direction de la lumière */ 21 RtPoint to={0,0,0}; 22 23 char name[]="primero.tif"; 24 RtFloat fov=45; 25 RtFloat intensity1=0.1; 26 RtFloat intensity2=1.5; 27 RtInt init=0,end=1; 28 29 RiBegin(RI_NULL); 30 RiFormat(320,240,1); 31 RiPixelSamples(2,2); 32 RiShutter(0,1); 33 RiFrameBegin(1); 34 RiDisplay(name,"file","rgb",RI_NULL); 35 name[7]++; 36 RiProjection("perspective","fov",&fov,RI_NULL); 37 RiTranslate(0,-5,60); 38 RiRotate(-120,1,0,0); 39 RiRotate(25,0,0,1); 40 RiWorldBegin(); 41 RiLightSource("ambientlight","intensity",&intensity1,RI_NULL); 42 RiLightSource("distantlight","intensity",&intensity2,"from",from,"to",to,RI_NULL); 43 RiColor(Azul); 44 RiTransformBegin(); 45 RiCylinder(1,0,20,360,RI_NULL); 46 RiTranslate(0,0,20); 47 RiCone(2,2,360,RI_NULL); 48 RiTransformEnd(); 49 RiColor(Verde); 50 RiTransformBegin(); 51 RiRotate(-90,1,0,0); 52 RiCylinder(1,0,20,360,RI_NULL); 53 RiTranslate(0,0,20); 54 RiCone(2,2,360,RI_NULL); 55 RiTransformEnd(); 56 RiColor(Rojo); 57 RiTransformBegin(); 58 RiRotate(90,0,1,0); 59 RiCylinder(1,0,20,360,RI_NULL); 60 RiTranslate(0,0,20); 61 RiCone(2,2,360,RI_NULL); 62 RiTransformEnd(); 63 RiColor(Blanco); 64 RiSphere(5,-5,5,360,RI_NULL); 65 RiWorldEnd(); 66 RiFrameEnd(); 67 RiEnd(); 68 }; |
Les trois premières lignes servent à inclure les fichiers d'entêtes comme ri.h qui contient les prototypes des fonctions de la librairie Renderman . Chaque fonction Renderman à son équivalent en C , comme TransformBegin qui correspond à la fonction C RiTransformBegin(), etc... Créer l'exécutable primero en tapant make . Notre programme peut être appelé pour créer un fichier en sortie par redirection (primero > primero.rib) ou en envoyant l'affichage directement à un autre programme (primero | rendrib) . Dans ce dernier cas , rendrib se charge de générer l'image primero.tif :
Les fonctions appelées de la librairie Renderman doivent être encapsulées entre un RiBegin(RI_NULL) et un RiEnd(). Le paramètre passé à RiBegin est normalement RI_NULL . Pour éviter que l'affichage du script Rib ne se fasse à ll'écran , nous pouvons donner le nom du fichier de sortie ("myfile.rib") ou meme le nom d'un programme (comme rendrib), l'exécutable passera ensuite les commandesRenderman au programme de rendu sans créer un fichier RIB intermédiaire.
Le code source de notre premier exemple contient des instructions C typiques , plus des types et fonctions intrinsèques à l'interface Renderman : le type RtColor est un vecteur de trois réels donnant les composantes rouge , vert et bleu (les valeurs sont comprises entre 0.0 et 1.0) ; RtPoint donne une position dans l'espace ; RtFloat et RtInt sont respectivement de type réel et entier .
La ligne 29 contient un appel à RiBegin(RI_NULL), qui comme nous l'avons vu précédemment , est un appel d'initialisation pour l'interface Renderman . Ensuite , on retrouve les fonctions Renderman habituelles d'un fichier RIB classique . Essayez de lancer le programme et de redirigez l'affichage dans un fichier (./primero > primero.rib) , ce qui devrait donner :
##RenderMan RIB-Structure 1.0 version 3.03 Format 320 240 1 PixelSamples 2 2 Shutter 0 1 FrameBegin 1 Display "camara.tif" "file" "rgb" Projection "perspective" "fov" [45 ] Translate 0 -5 60 Rotate -120 1 0 0 Rotate 25 0 0 1 WorldBegin LightSource "ambientlight" 1 "intensity" [0.1 ] LightSource "distantlight" 2 "intensity" [1.5 ] "from" [0 100 100] "to" [0 0 0] Color [0 0 1] TransformBegin Cylinder 1 0 20 360 Translate 0 0 20 Cone 2 2 360 TransformEnd Color [0 1 0] TransformBegin Rotate -90 1 0 0 Cylinder 1 0 20 360 Translate 0 0 20 Cone 2 2 360 TransformEnd Color [1 0 0] TransformBegin Rotate 90 0 1 0 Cylinder 1 0 20 360 Translate 0 0 20 Cone 2 2 360 TransformEnd Color [1 1 1] Sphere 5 -5 5 360 WorldEnd FrameEnd |
Notre premier exemple n'est pas très utile . Pour générer
une autre scène , nous devons écrire un nouveau programme
qui effectuerait les opérations similaires . La puissance de la
librairie Renderman est vraiment dans la génération d'animations
. Dans ce premier exemple , une seule image a été générée
,, dans le prochain , nous allons faire bouger la sphère .
1 #include <stdio.h> 2 #include <math.h> 3 #include <ri.h> 4 #include "filename.h" 5 6 void main(void) 7 { 8 int i; 9 int x,y,z; 10 int nf; 11 float slopex,slopey,slopez; 12 13 RtColor Rojo={1,0,0}; 14 RtColor Verde={0,1,0}; 15 RtColor Azul={0,0,1}; 16 RtColor Blanco={1,1,1}; 17 18 RtPoint p1={30,0,10}; /* Position initiale de la sphère */ 19 RtPoint p2={0,20,10}; /* Position finale de la shpère */ 20 21 RtPoint from={0,100,100}; /* Direction de la lumière */ 22 RtPoint to={0,0,0}; 23 24 char base[]="camara_"; 25 char ext[]="tif"; 26 char name[50]; 27 RtFloat fov=45; 28 RtFloat intensity1=0.1; 29 RtFloat intensity2=1.5; 30 RtInt init=0,end=1; 31 32 nf=100; /* Nombre de frames (d'image) */ 33 slopex=(p2[0]-p1[0])/nf; 34 slopey=(p2[1]-p1[1])/nf; 35 slopez=(p2[2]-p1[2])/nf; 36 37 RiBegin(RI_NULL); 38 RiFormat(320,240,1); 39 RiPixelSamples(2,2); 40 RiShutter(0,1); 41 for (i=1;i <= nf;i++) 42 { 43 RiFrameBegin(i); 44 filename(base,ext,sizeof(base)+4,i-1,name); 45 RiDisplay(name,"file","rgb",RI_NULL); 46 name[7]++; 47 RiProjection("perspective","fov",&fov,RI_NULL); 48 RiTranslate(0,-5,60); 49 RiRotate(-120,1,0,0); 50 RiRotate(25,0,0,1); 51 RiWorldBegin(); 52 RiLightSource("ambientlight","intensity",&intensity1,RI_NULL); 53 RiLightSource("distantlight","intensity",&intensity2,"from",from,"to",to,RI_NULL); 54 RiColor(Azul); 55 RiTransformBegin(); 56 RiCylinder(1,0,20,360,RI_NULL); 57 RiTranslate(0,0,20); 58 RiCone(2,2,360,RI_NULL); 59 RiTransformEnd(); 60 RiColor(Verde); 61 RiTransformBegin(); 62 RiRotate(-90,1,0,0); 63 RiCylinder(1,0,20,360,RI_NULL); 64 RiTranslate(0,0,20); 65 RiCone(2,2,360,RI_NULL); 66 RiTransformEnd(); 67 RiColor(Rojo); 68 RiTransformBegin(); 69 RiRotate(90,0,1,0); 70 RiCylinder(1,0,20,360,RI_NULL); 71 RiTranslate(0,0,20); 72 RiCone(2,2,360,RI_NULL); 73 RiTransformEnd(); 74 RiColor(Blanco); 75 RiTransformBegin(); 76 RiTranslate(p1[0]+slopex*(i-1),p1[1]+slopey*(i-1),p1[2]+slopez*(i-1)); 77 RiSphere(5,-5,5,360,RI_NULL); 78 RiTransformEnd(); 79 RiWorldEnd(); 80 RiFrameEnd(); 81 } 82 RiEnd(); 83 }; |
Ensuite , essayez cet exemple comme précédemment : compilez-le et exécutez-le en le redirigant vers rendribv , par exemple . C'est une méthode simple pour obtenir un rapide apercude notre aanimation à un rythme acceptable . Pour avoir le script RIB généré , il suffit de rediriger vers un nouveau fichier . On peut voir que la taille de ce fichier est très grande (segundo.rib occupe 70kb) car la même scène est définie 100 fois (une fois par frame) .
Les images suivantes montre quelques frames intermédiaires de l'animation :
Bien sur , on peut animer tous les paramètres que nous souhaitons
: la position des objets , leurs tailles , l'intensité de la lumière,
la caméra (l'oeil de l'observateur) , faire apparaitre et disparaitre
des choses , etc ...
float rebote (int i, int nframes, int max) { float min, z; while (i > nframes) i-=nframes; min=sqrt(max); z=i-((float)nframes/2.0); z=(z*min)/((float)nframes/2.0); z=(float)max - (z*z); return(z); } |
Par quelques calculs simples , on associe à l'équation d'une courbe parabole (y=x²) le nombre de frame et le maximum désiré de l'amplitude . Les images suivantes montre quelques frames générés pendant un rebond par le programme tercero.c:
Je vous donne quelques fichiers GIF pour voir les animations ; bien qu'elles soient lentes (au moins avec Netscape) , avec xanim , vous devriez les voir à une vitesse acceptable :
Le Mouvement Rectiligne : segundo_anim.gif
Le Mouvement Parabolique : tercero_anim.gif
Ce dernier exemple termine notre présentation des rudiments de
l'interfacage du C avec Renderman . Le plus avancé et le plus spectaculaire
des sujets de programmation est le thème des ombrages .
Il donne le controle ultime sur le rendu final d'une scène car cela
permet de controler les textures , l'ilumination , etc ...
Site Web maintenu par l´équipe d´édition LinuxFocus
© Carlos Calzada Grau LinuxFocus 1999 |