
Par Yannick Puech
I. Généralités
|
Les shaders ont permis d’accroître le réalisme des rendus 3D. Les shaders Renderman sont les shaders les plus populaires dans l’industrie graphique 3D. Le moteur de rendu Mental Ray permet aussi de développer des shaders grâce à une API complète. L’intérêt de convertir des shaders Renderman en Mental Ray est qu’il n’y a que très peu de ressources(sources et articles sur le web, livres etc..) sur les shaders Mental Ray, par contre, on peut trouver sur le net un nombre important de ressources à propos des shaders Renderman. |
![]() |
Tout d’abord, nous allons voir les points communs, en montrant les correspondances, et différences entre les shaders Renderman et Mental Ray.
Ensuite, on prendra un exemple simple de shader Renderman à convertir.
Enfin, vous pourrez voir les images de quelques shaders Renderman que j’ai convertis.
Tout au long de cet article, des remarques générales seront faites sur l’écriture de shaders Mental Ray.
1) Pré requis
Pour comprendre ce qui suit, il faut connaître le langage C. Egalement, il faut avoir des notions du développement de shaders Renderman et Mental Ray.
Des liens vers des articles et des cours traitant de ces sujets sont donnés à la fin du présent article.
2) A qui s’adresse ce cours ?
Ce cours s’adresse aussi bien aux débutants dans le développement de shaders Mental Ray qu’aux gens désireux de se perfectionner dans l’écriture de shaders Mental Ray.
Il est plutôt orienté pour les programmeurs mais il peut-être lu par des artistes connaissant Renderman et souhaitant convertir leurs shaders Renderman en shaders Mental Ray.
La partie 4 montre les images de shaders que j’ai développé, tout le monde peut donc consulter cette partie.
II. Renderman Shading Language et Mental Ray API
1) Les points communs
a) Correspondances au niveau des types
Renderman contient un langage appelé Renderman Shading Language qui permet d’écrire des shaders personnalisés. Ce langage a des types prédéfinis. Les trois types du RSL qui nous intéressent sont les suivants : float, point et color.
Dans Mental Ray, le type scalaire utilisable est miScalar, qui est en fait une rédifinition du type float standard du langage C comme suit :
typedef float miScalar;
Pour des raisons de portabilité, il est préférable d’utiliser miScalar à float. De plus, lors de la définition d’une variable constante ou d’une macro, il est recommandé de mettre un « f » à la fin du nombre constant sinon le compilateur part du fait que le nombre est un double, ce qui va sûrement activer des warnings lors de la compilation et ralentir l’exécution du shader. Illustration :
…
#define BLACK_R 0.0f
…
Pour représenter une position ou une direction dans l’espace avec l’API de Mental Ray, on utilise miVector. Il ne faut pas oublier qu’un point est un vecteur qui part de l'origine. Il n’y a donc pas d’ambiguïté avec le type point du RSL. Il existe aussi vector, on le traduira logiquement donc par miVector.
Egalement, le RSL fourni le type normal. Ce type est en fait un vecteur spécial qui est perpendiculaire à la surface.
Le type destiné à stocker une couleur dans un code de shader Mental Ray est miColor. Contrairement au type color du RSL, miColor ne peut être exprimé que dans le repère RGBA (Red Green Blue Alpha).
Le tableau suivant présente les correspondances entre les types :
|
Type RSL
|
Type Mental Ray
|
But
|
|
float
|
miScalar
|
Type scalaire
|
|
point, vector, normal
|
miVector
|
Position ou direction dans l’espace
|
|
color
|
miColor
|
Couleur et intensité d’une lumière
Réflexivité et opacité d’une surface |
b) Correspondances variables globales du RSL avec variables du « state »de Mental Ray
Le RSL contient également des variables globales prédéfinies. Pour convertir avec succès un shader, il faut donc connaître la correspondance Mental Ray de ces variables globales.
Il est à noter, que la correspondance n’existe pas pour toutes les variables globales et que certaines variables Mental Ray ne sont disponibles seulement que dans certains types de shaders.
Le tableau suivant présente les correspondances :
|
Variable du RSL
|
Equivalent Mental Ray
|
Rôle
|
|
P
|
state>point
|
Position sur la surface
|
|
dPdu
|
state>bump_list[0]
|
Dérivée de P suivant u
|
|
dPdv
|
state>bump_list[1]
|
Dérivée de P suivant v
|
|
N
|
state>normal
|
Normale en P
|
|
Ng
|
state>normal_geom
|
Normale géométrique en P
|
|
u, v (ou s, t)*
|
state>tex_list[0].x,
state>tex_list[0].y |
Coordonnées de P dans le repère de plaquage de texture
|
|
I
|
state>dir
|
Direction entre P et la caméra
|
|
Ci
|
*result
|
Couleur de la surface en sortie
|
|
Oi
|
result>a
|
Opacité de la surface en sortie
|
|
E
|
state>org
|
Position de la caméra
|
(*) Dépend du contexte d’utilisation, on retrouve très souvent s et t à convertir, on mettra plutôt :
…
miScalar ucoord, vcoord ; /* Coordonnées U et V = UVs */
…
state>tex = state>tex_list[0]; /* Initialisation car non effectuée par Mental Ray */
…
/* Récupère les UVs du state */
ucoord = state>tex.x;
vcoord = state>tex.y;
…
Lorsque l’on développe un shader utilisant les UVs d’un objet, le code précédent est utile si on souhaite se servir de state>tex.
c) Points communs au niveau des types des shaders
Le RSL permet la définition de shaders de plusieurs types, Mental Ray et son API aussi. Il est à noter que Mental Ray propose beaucoup plus de types de shaders que le RSL.
Le tableau suivant présente les correspondances :
|
Type shader RSL
|
Type shader Mental Ray
|
But
|
|
light
|
light
|
Définition d'une source lumineuse
|
|
surface
|
texture
|
Définition des caractéristiques optiques d'une surface (couleur, opacité)
|
|
volume
|
volume
|
Définition des caractéristiques optiques de l'intérieur d'un volume
|
|
transformation
|
na (*)
|
Définition de transformations géométriques
|
|
displacement
|
displacement
|
Définition de transformations effectuées sur la surface des objets
|
|
imager
|
output
|
Définition d'une fonction de conversion couleur vers couleur
|
(*) Mental Ray propose un type de shader nommé « Geometry shaders » permettant de créer des objets procéduralement. Il permet donc de définir les propriétés géométriques d’un objet, mais pas d’animer ses vertices. Attention donc à la confusion possible.
d) Points communs au niveau des fonctions prédéfinies
L’utilisation de fonctions fournies par le RSL se rapproche beaucoup de celles de l’API de Mental Ray. C’est le cas notamment de certaines fonctions de calcul de la diffusion de la lumière, de transformation de repère, de noise.
Par exemple, on a phong() (ou specular()) dans le RSL et mi_phong_specular() avec Mental Ray. De même pour les fonctions de noise ; noise() et mi_noise_xd() (avec x = 1 à 3).
Du côté des fonctions mathématiques, normalize() et mi_normalize(), lengh() et mi_norm().
Les fonctions de changement de repères existent dans les deux APIs. Par exemple :
Rworld = vtransform("world", R);
Devient :
mi_vector_to_world(state, &Rworld, &R);
Egalement, l’opérateur “-“ de Renderman est considéré comme une function lorsqu’il est appliqué à un vecteur, comme ceci :
…
vneg = -v; /* v et vneg sont de type vector */
…
Avec Mental Ray on mettra :
…
vneg = v; /* v et vneg sont de type miVector */
mi_vector_neg(&vneg) ;
…
De plus, la fonction texture() du RSL devient mi_lookup_color_texture() ou mi_lookup_filter_color_texture() et environment() se change en mi_trace_environment().
La liste des correspondances entre les fonctions est longue et ce n’est pas le but de cet article de dresser une telle liste. Pour trouver les correspondances entre les fonctions du RSL et de l’API de Mental Ray, il est préférable de regarder leur documentation.
