Google+
3DVF Network :
ico_magazine
Magazine
ico_boutique
Boutique
ico_cgjobs
Portail Emploi
ico_upload
Hébergement d'image
blogs
Blogs
ico_progiss
Progiss
ico_social
Social
Login
space
space

Accueil / Magazine / Didacticiels / Convertir un shader Renderman en shader MentalRay

space

Convertir un shader Renderman en shader MentalRay

Publié le 13 février 2009 par lieo
space


Par Yannick Puech


 

 

 

 

2) Les différences et quelques apports de Renderman

 

 

 

 

a) Les différences entre le RSL et Mental Ray

 


Il y a des différences entre le RSL et Mental Ray surtout au niveau de l’écriture du code et des fonctions fournies par les deux moteurs de rendus.


• Différences au niveau de l’écriture du code

Tout d’abord, en RSL on peut faire :

 

 

 


/* Déclaration des 2 couleurs */
color black = 0; /* Initialisation impossible en Mental Ray */
color c ;

c = black 0.5; /* Addition impossible en Mental Ray */

 

 


En Mental Ray, un tel code devient (il existe d’autres manières mais celle-ci est la plus lisible) :

 

 

 

/* Déclaration des 2 couleurs */
miColor black, c;

black.r = black.g = black.b = 0.0f; /* Initialisation des 3 composants à la volée */

/* Addition composant par composant */
c.r = black.r 0.5f;
c.g = black.g 0.5f;
c.b = black.b 0.5f;


 

 


En RSL, on peut assigner un nombre à une couleur, additionner une couleur et un nombre, un point et un nombre etc.. car le RSL est un langage à part entière, compilé avec un automate dédié. Cela permet de raccourcir le code, mais réduit la lisibilité du code.

Par contre, avec l’API de Mental Ray, on programme directement en C ou C . Or, ces 2 langages sont très stricts au niveau du typage des variables. On peut trouver des fonctions telles que mi_vector_mul() ou mi_vector_add() permettant de remédier à cela.


 

 


• Différences au niveau des fonctions


Dans le RSL, il existe une fonction très utilisée pour le bump mapping et le displacement, il s’agit de la fonction calculatenormal(). Malheureusement, cette routine n’est pas présente dans l’API de Mental Ray. De plus, son code (disponible dans la documentation de Renderman) est très difficile à traduire en Mental Ray.
Une façon d’y remédier est de créer deux shaders distincts : un de type texture et l’autre de type displacement. Mais cela n’est pas tout le temps possible et bien souvent, le résultat obtenu n’est pas celui escompté.

Egalement, la fonction spline() est souvent utilisée. Son appel diffère un peu avec celui de mi_spline() de l’API de Mental Ray. Tout d’abord, mi_spline() renvoie une valeur de type miScalar tandis que spline() peut renvoyer des valeurs de types différents.
Avec une spline, on peut dessiner une courbe. Cette courbe est créée à partir de points de contrôles et est calculée à une altitude donnée.

La portion de code suivant montre du code RSL utilisant spline() :


 

 


#define BROWN color (0.1307,0.0609,0.0355)

#define BLACK color (0,0,0)

color C ;
float altitude ;

/* Calcul de l’altitude de la spline */
altitude = … ;

/* Création de la spline */
C = spline(altitude, BROWN, …, BLACK); /* Ici, spline renvoie une couleur */

 

 

 

En Mental Ray, on peut traduire ce code comme suit :

 

 

 


#define BROWN_R 0.1307f
#define BROWN_G 0.0609f
#define BROWN_B 0.0355f

#define BLACK_R 0.0f
#define BLACK_G 0.0f
#define BLACK_B 0.0f

/* Il faut donner le nombre de point de contrôles de la spline à mi_spline() */
#define NB_POINTS 13

miColor C;
miScalar altitude;

/* Initialisation des tableaux des 3 composants */
miScalar red_components[] = {BROWN_R, …, BLACK_R};
miScalar green_components[] = {BROWN_G, …,BLACK_G};
miScalar blue_components[] = {BROWN_B, …, BLACK_B};

/* Calcul de l’altitude de la spline */
altitude = …;

/* Création de la spline */
C.r = mi_spline(altitude, NB_POINTS, red_components);
C.g = mi_spline(altitude, NB_POINTS, green_components);
C.b = mi_spline(altitude, NB_POINTS, blue_components);


 

 


Dans du code Mental Ray, on décompose les types composant par composant, que ce soit pour les macros de substitutions, la création de tableaux ou l’appel de fonctions. Un bon découpage du code facilite la lisibilité du code et le développement logique de shaders.

Enfin, il y a aussi des fonctions comme illuminate() et illuminance() qui n’ont pas de correspondant Mental Ray. Ces fonctions ne sont pas indispensables dans l’écriture de shaders.


 

 

 


b) Les apports du RSL


Le RSL fournit des fonctions facilitant le développement de shaders. Ces fonctions sont surtout utilisées dans le développement de textures procédurales. Elles ne sont pas présentes dans l’API de Mental Ray. Mais le code de ces fonctions est dans la documentation de Mental Ray.
Des fonctions telles que smoothstep(), clamp(), mix() sont des incontournables de l’écriture de shaders. De plus, ces fonctions se retrouvent dans un nombre important de shaders Renderman. Elles sont facilement convertibles en macro. Un fichier d’entête comprenant ces macros est disponible ici.


 

 

 


III. Illustration par un exemple

 

 

Dans cette partie, on va convertir le shader de plastique dont le code est disponible dans la documentation de Renderman. C’est un shader de base, mais il permet de mettre en œuvre les bases de l’écriture de shaders. En plus de voir concrètement une conversion, quelques bases des modèles d’illumination seront vues.

Dans la documentation de Renderman, le shader de plastique est définit ainsi :

 

 

 

surface plastic(
float Ka = 1;
float Kd =.5;
float Ks =.5;
float roughness =.1;
color specularcolor = 1;)
{
   normal Nf = faceforward(normalize(N), I);
   vector V = -normalize(I);
   Oi = Os;
   Ci = Os * (Cs * (Ka*ambient() Kd*diffuse(Nf))
          specularcolor * Ks*specular(Nf, V, roughness) );
}

 

 



Tout d’abord, les deux premières lignes ne sont jamais traduites en Mental Ray.
En effet, les deux opérations utilisées ici dans le code RSL sont effectuées automatiquement par Mental Ray.
Dans le cas de la première ligne il s’agit de la normale du point, donc state>normal.
Pour la seconde ligne, il s’agit de la direction de la lumière : state>dir.

La troisième ligne assigne l’opacité entrante à l’opacité sortante, rien de compliqué.

En fait, c’est la quatrième ligne qui nous intéresse le plus. Les fonctions ambient(), diffuse() et specular().


 

 

 


• La lumière ambiante


La lumière ambiante est la plus facile à traduire, on prend juste la couleur ambiante (ambi ici) que l’on multiplie à la couleur de la lumière (color en l’occurence).

 

 

 

miColor ambiant; /* couleur ambiante */

/* Réflexion ambiante */
ambiant.r = color.r * ambi>r;
ambiant.g = color.g * ambi>g;
ambiant.b = color.b * ambi>b;



 

 

 

• La réflexion diffuse


Dans l’API de Mental Ray, il n’y a pas de fonctions permettant de calculer la réflexion diffuse à partir de la normale donnée. En fait, si on applique la loi de Lambert, on sait que :

réflexion diffuse = ( normale . direction de la lumière ) * couleur diffuse

( . désigne le produit scalaire entre deux vecteurs)

Dans du code Mental Ray, on utilise souvent mi_sample_light() qui permet de renvoyer des valeurs (en paramètre de sortie), notamment le produit scalaire entre la normale et la direction de la lumière. On peut aussi utiliser mi_vectot_dot().

Dans le code qui suit, diff est la couleur diffuse choisie dans l’interface du logiciel 3D :

 

 

 

miColor diffuse;
miScalar dot_nl; /* produit scalaire entre la normale et la direction de la lumière */

/* Calcul du produit scalaire */
dot_nl = mi_vector_dot(&state>normal, &state>dir);

/* Réflection diffuse : loi de Lambert */
diffuse.r = color.r * Kd * dot_nl * diff>r;
diffuse.g = color.g * Kd * dot_nl * diff>g;
diffuse.b = color.b * Kd * dot_nl * diff>b;

 

 

 



Je n’ai pas utilisé ici mi_sample_light() car le code aurait été trop long.


 

 


• La Réflexion spéculaire


Dans Mental Ray, il existe mi_phong_specular(). L’utilisation de cette fonction se rapproche de specular() du RSL. Certains diront que ces deux fonctions ne se correspondent pas. En effet, elles n’appliquent pas le même modèle de réflexion. Mais la différence est minime voire inexistante dans certains cas.
Dans le code qui suit, spec est la couleur spéculaire choisie.

 

 

 

 


#define SPEC_EXP_PLASTIC 31 /* Exposant spéculaire du plastique */

/* Calcul du facteur de Phong */
refl = mi_phong_specular(SPEC_EXP_PLASTIC, state, &dir);

/* Calcul de la reflection spéculaire ssi la réflection est positive */
specular.r = specular.g = specular.b = 0;
if (refl > 0.0) {
specular.r = Ks * refl * spec>r;
specular.g = Ks * refl * spec>g;
specular.b = Ks * refl * spec>b;
}


 

 

 

Pour fournir la couleur de sortie créée à Mental Ray, on écrira donc :

 

 

 

 


result>r = ambient.r diffuse.r specular.r;
result>g = ambient.g diffuse.g specular.g;
result>b = ambient.b diffuse.b specular.b;


 

 

 

Rappel : Ces trois lignes montrent la base de l’illumination d’un objet. Il faut donc retenir :

Illumination = lumière ambiante réflexion diffuse réflexion spéculaire.


 

 

 

 

Le shader de plastique en action sous 3ds Max 7 :

 

space
space
space
space
space
A Propos | Contact | Publicité
Copyright © 2000-2018 3DVF. Tous droits réservés. | Infogérance serveur | tracker
space