|
Par Yannick Puech  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. De
plus, il n’est pas évident de développer un shader en partant de zéro
(ou presque), cela demande de la recherche. Par contre, en partant du
code d’un shader Renderman, le travail est déjà « mâché ». 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. 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 | | 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 :
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 : 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.
|