Le raytracing est connu pour la façon dramatique dont il dépeint les effets de réflexion, réfraction et illumination. Notre perception dépend surtout des propriétés réflectives d'un objet. Le raytracing peut exploiter cela en jouant avec notre perception, pour nous faire voir des détails complexes qui n'existent pas.
Supposons que vous vouliez une surface très bosselée. Il serait très difficile de décrire mathématiquement cette surface. Toutefois, nous pouvons simuler l'apparence de bosses en altérant la façon dont la lumière se reflète sur la surface. Les calculs de réflexion dépendent d'un vecteur appelé vecteur de normale de surface. Il pointe au-dessus de la surface, en restant perpendiculaire à elle. Par une modification artificielle (ou une perturbation) de ce vecteur, vous pouvez simuler des bosses. Ceci est fait en ajoutant une déclaration optionnelle normal.
Note : le modèle de normale ne modifie pas réellement la surface. Il affecte seulement la façon dont la lumière se reflète sur la surface, pour paraître bosselée.
La syntaxe est :
NORMAL: normal { [NORMAL_IDENTIFIER] [NORMAL_TYPE] [NORMAL_MODIFIER...] } NORMAL_TYPE: PATTERN_TYPE Amount | bump_map { BITMAP_TYPE "bitmap.ext" [BUMP_MAP_MODS...]} NORMAL_MODIFIER: PATTERN_MODIFIER | NORMAL_LIST | normal_map { NORMAL_MAP_BODY } | slope_map { SLOPE_MAP_BODY } | bump_size Amount | no_bump_scale Bool | accuracy Float
Chacun des éléments est optionnel, mais ils doivent respecter cet ordre. Tous les éléments après NORMAL_IDENTIFIER modifient ou écrasent les paramètres donnés dans l'identificateur. Si aucun identificateur n'est spécifié, alors la modification se porte sur les valeurs par défaut de la texture. Le PATTERN_TYPE peut être suivi, optionnellement, par une valeur numérique qui contrôle la profondeur apparente des bosses. Les valeurs typiques sont entre 0.0 et 1.0, mais toute valeur peut être utilisée. Les négatives inversent le modèle. La valeur par défaut est 0.5.
Il y a quatre types de NORMAL_TYPE. Ce sont les groupements de modèles de normales, les modèles de normale continus, les normales spécialisées et les spectres de bosses. Ils diffèrent par les types de modificateurs que vous pouvez utiliser. Le type de modèle est optionnellement suivi par un ou plusieurs modificateurs de normale. En plus des modificateurs de modèles génériques comme les transformations, la turbulence et la torsion, les normales ont aussi un NORMAL_LIST, slope_map, normal_map et bump_size qui sont spécifiques aux normales. Voir "Les modificateurs de modèles" pour des informations sur les modificateurs génériques. Les modificateurs spécifiques sont décrits plus bas. De tels modificateurs s'appliquent seulement sur la normale, et dans aucune autre partie de la texture. Ils doivent être spécifiés à la fin.
A l'origine, POV-Ray avait des modèles pour les pigments, et d'autres pour les normales. Depuis POV-Ray 3.0, vous pouvez utiliser tout modèle pour les pigments ou les normales. Par exemple, il est valide, maintenant, d'utiliser ripples comme pigment, ou le bois comme type de normale. Les modèles bumps, dents, ripples, waves, wrinkles et bump_map étaient exclusivement des modèles de normale, qui ne pouvaient pas être utilisés comme pigments. Parce que ces six types utilisent des calculs de modification de normale spécialisés, ils ne peuvent pas avoir les modificateurs slope_map, normal_map ou la forme de vague. Tous les autres types de modèles de normale peuvent les utiliser. Parce que les groupements de modèle damier, hexagone et brique ne retournent pas de série continuelle de valeurs, ils ne peuvent pas utiliser ces modificateurs. Voir "Les modèles" pour les détails sur les modèles spécifiques.
Une déclaration de normale est une partie de la texture. Toutefois il peut être lourd d'utiliser une déclaration de texture seulement pour ajouter des bosses. Aussi, vous pouvez directement attacher une normale à un objet sans spécifier explicitement que c'est une partie de texture. Par exemple, au lieu de ceci :
object {My_Object texture {normal {bumps 0.5}}}
Vous pouvez raccourcir en cela :
object {My_Object normal {bumps 0.5}}
Ceci crée une structure de texture complète avec un pigment et une finition par défaut, comme si vous aviez tapé entièrement texture {...}. Les identificateurs de normale peuvent être déclarés pour rendre les scènes plus lisibles et paramétrables. Un identificateur est déclaré comme ceci :
NORMAL_DECLARATION: #declare IDENTIFIER = NORMAL | #local IDENTIFIER = NORMAL
Où IDENTIFIER est le nom de l'identificateur sur 40 caractères et NORMAL est toute déclaration valide de normale. Voir "#declare vs. #local" pour des informations sur la portée.
Un spectre d'inclinaisons est un modificateur de modèle de normale qui donne un grand contrôle sur la forme exacte de l'élément bosse. Chacun des types de modèle est, en fait, une fonction mathématique qui prend toute position x, y et z, et la transforme en un nombre entre 0.0 et 1.0, inclus. Ce nombre est utilisé pour donner les positions des points hauts et bas. Il vous assiste pour les contours. Il est mieux illustré avec un modèle de normale gradient. Supposons que vous avez...
plane {z, 0 pigment {White} normal {gradient x} }
Cela donne un modèle de vague qui ressemble à de petites déclinaisons linéaires grimpant des points x = 0 à x = 1, puis retombant à 0 avant de reprendre de x = 1 à x = 2. Un spectre d'inclinaisons transforme cette simple inclinaison linéaire en toute forme de vague désirée. La syntaxe est :
SLOPE_MAP: slope_map { SLOPE_MAP_BODY } SLOPE_MAP_BODY: SLOPE_MAP_IDENTIFIER | SLOPE_MAP_ENTRY... SLOPE_MAP_ENTRY: [ Value, <Height, Slope> ]
Note : les parenthèses [] sont des éléments de SLOPE_MAP_ENTRY, et non des symboles de notation pour désigner les parties optionnelles. Les parenthèses entourent chaque entrée de l'application.
Il peut y avoir entre 2 et 256 entrées.
Chaque Value est une valeur numérique entre 0.0 et 1.0, inclus, et chaque <Height, Slope> est un vecteur à deux éléments comme <0, 1> où la première valeur représente la hauteur apparente de la vague, et la seconde, l'inclinaison de la vague en ce point. La hauteur doit être entre 0.0 et 1.0, mais toute valeur peut être utilisée.
La valeur de l'inclinaison est le changement de hauteur par unité de distance. Par exemple, une inclinaison de zéro signifie le plat, 1.0 donne un angle positif de 45 degrés, et -1 signifie une descente de 45 degrés. Théoriquement, une inclinaison verticale devrait avoir une valeur infinie. Dans la pratique, les valeurs doivent rester entre -3.0 et +3.0. Gardez en mémoire que ce n'est qu'une apparence. Une normale ne change pas la surface.
Par exemple, voici comment faire une pente croissante sur la première moitié, et décroissante sur le reste, donnant une vague triangulaire avec un sommet pointu au centre.
normal { gradient x // ceci est le PATTERN_TYPE slope_map { [0 <0, 1>] // commence en bas et grimpe [0.5 <1, 1>] // mi parcours, où la croissance stoppe [0.5 <1,-1>] // descente abrupte [1 <0,-1>] // fin sur une inclinaison descendante } }
La fonction du modèle est évaluée, et le résultat est une valeur entre 0.0 et 1.0. La première entrée dit qu'à x = 0, la hauteur apparente est 0, et l'inclinaison est 1. A x = 0.5, nous sommes à la hauteur 1 et l'inclinaison est toujours de 1. La troisième entrée spécifie qu'à x = 0.5 (c'est-à-dire à quelques fractions au delà de 0.5), nous avons la hauteur de 1, mais l'inclinaison passe à -1. Finalement à x = 1, nous sommes à la hauteur 0, et continuons de descendre de -1.
Même si cet exemple connecte les points avec des lignes droites, la forme est une génératrice cubique. Cet exemple crée une vague sinusoïde.
normal { gradient x // ceci est le PATTERN_TYPE slope_map { [0 <0.5, 1>] // commence au milieu et monte [0.25 <1.0, 0>] // aplatissement au sommet de la vague [0.5 <0.5,-1>] // descend à mi-chemin [0.75 <0.0, 0>] // aplatissement au plancher [1 <0.5, 1>] // fin au milieu et croissance } }
Cet exemple commence à la hauteur 0.5 grimpant avec l'inclinaison 1. Au quart du trajet, nous sommes au sommet de la courbe, hauteur 1 et aplanissement. L'espace entre ces deux est une courbe délicate, car les débuts et fins des inclinaisons sont différents. A mi-parcours, nous sommes à mi-hauteur avec une pente vers le bas au 3/4. A la fin, nous remontons avec une pente de 1 pour compléter le cycle. Il y a d'autres exemples dans slopemap.pov, dans les scènes d'exemples.
Un slope_map peut être utilisé avec tout modèle sauf brick, checker, object, hexagon, bumps, dents, ripples, waves, wrinkles et bump_map.
Vous pouvez déclarer et utiliser des identificateurs de spectres d'inclinaisons. Par exemple :
#declare Fancy_Wave = slope_map { // Maintenant, soyons fantaisiste [0.0 <0, 1>] // Fait un petit triangle d'ici [0.2 <1, 1>] // descendant [0.2 <1,-1>] // jusque [0.4 <0,-1>] // là. [0.4 <0, 0>] // Aire plate [0.5 <0, 0>] // jusque là. [0.5 <1, 0>] // Bord d'une vague carrée [0.6 <1, 0>] // autre bord [0.6 <0, 0>] // Encore plat [0.7 <0, 0>] // jusque là. [0.7 <0, 3>] // Début cannelure [0.8 <1, 0>] // plat au sommet [0.9 <0,-3>] // finissant ici. [0.9 <0, 0>] // Reste plat jusqu'à 1.0. } object {My_Object pigment {White} normal { wood slope_map {Fancy_Wave} } }
Les normales de surface, qui utilisent des modèles qui ne sont pas définis pour une utilisation avec les normales (n'importe quoi d'autre que les bosses, les dents, les vagues, les rides et les plis), utilisent un slope_map que vous le spécifiez ou non. Pour créer une normale perturbée depuis un modèle, POV-Ray échantillonne le modèle au quatre points d'une pyramide entourant la cible pour déterminer le gradient du modèle au centre de la pyramide. La distance de ces points avec le point central détermine la précision de l'approximation. L'utilisation de points trop proches amène des imprécisions. Toutefois, l'utilisation de points trop éloignés peut conduire à des artefacts tout comme à l'adoucissement d'éléments qui ne le doivent pas.
Habituellement, les points très proches sont désirés. POV-Ray utilise couramment une distance de 0.02. Parfois, il est nécessaire de baisser cette valeur pour obtenir plus de précision si vous avez une vue rapprochée de la texture. D'autres fois, il est agréable d'accroître cette valeur pour adoucir des bordures trop franches dans la normale (par exemple, lors de l'utilisation d'un modèle 'solide' de craquelure). Pour cette raison, une nouvelle propriété, accuracy, a été ajoutée aux normales. Cela fait une différence si la normale utilise un slope_map (qu'il soit spécifié ou implicite).
Vous pouvez spécifier la valeur de la précision (qui est la distance entre les points échantillons lors de la détermination du gradient du modèle pour slope_map) en ajoutant accuracy <float> à votre normale. Pour tous les modèles, le défaut est 0.02.
La plupart du temps, vous appliquerez un modèle de normale unique sur la totalité d'une surface, mais vous pouvez aussi créer un modèle de normale, ou un mélange, en utilisant un normal_map. La syntaxe pour un normal_map est identique à celle d'un spectre de pigments, sauf que vous placez des normales à chaque entrée. Une spectre de normales est spécifié par :
NORMAL_MAP: normal_map { NORMAL_MAP_BODY } NORMAL_MAP_BODY: NORMAL_MAP_IDENTIFIER | NORMAL_MAP_ENTRY... NORMAL_MAP_ENTRY: [ Value NORMAL_BODY ]
Où Value est une valeur numérique entre 0.0 et 1.0, inclus, et chaque NORMAL_BODY est tout ce qui doit apparaître dans une déclaration normal {...}. Le mot clé normal et les parenthèses {} ne sont pas nécessaires.
Note : les parenthèses [] font partie de NORMAL_MAP_ENTRY. Elles ne sont pas des symboles de notation pour délimiter les parties optionnelles. Elles entourent chaque entrée du spectre.
Il peut y avoir de 2 à 256 entrées.
Par exemple :
normal { gradient x // ceci est le PATTERN_TYPE normal_map { [0.3 bumps scale 2] [0.3 dents] [0.6 dents] [0.9 marble turbulence 1] } }
Quand la fonction gradient x retourne des valeurs de 0.0 à 0.3, alors les bosses retaillées sont utilisées. De 0.3 à 0.6 viennent les dents. De 0.6 à 0.9, un mélange de dents et de marbre turbulent est utilisé. A partir de 0.9, seul le marbre reste.
Les spectres de normales peuvent être emboîtés jusqu'au niveau de complexité désiré. Les normales dans un spectre peuvent avoir des spectres d'inclinaison, ou des spectres de normales, ou tout type de normale désiré.
Un spectre de normales est aussi utilisé avec le type de normale average. Voir "Le modèle moyen" pour les détails.
Des normales complètes, dans une liste de normales, peuvent aussi être utilisées avec les groupements de modèles comme le damier, l'hexagone et la brique. Par exemple...
normal { checker normal {gradient x scale .2} normal {gradient y scale .2} }
Note : dans le cas des groupements de modèles, l'emballage de normale est obligatoire autour des informations.
Vous ne pouvez pas utiliser normal_map ou des normales individuelles avec bump_map. Voir la section "Les spectres de textures" pour une autre façon de procéder.
Vous pouvez déclarer et utiliser des identificateurs de spectres de normales, mais la seule façon de déclarer un modèle de groupement de normales est de déclarer un identificateur de normale pour toute la normale.
Quand aucun des types de modèles de normale ne donne ce que vous cherchez, vous pouvez utiliser une application de bosses pour coller un modèle de bosses en 2-D sur vos objets en 3-D.
Au lieu de placer les couleurs de l'image, comme une application d'image, elle perturbe la normale de surface en se basant sur la couleur du pixel en ce point. Le résultat ressemble à une image embossée sur l'objet. Par défaut, cette carte utilise la luminosité de la couleur du pixel, la convertissant en niveau de gris avant de calculer la hauteur. Le noir est un point bas, le blanc est un point haut. Les valeurs de l'index de l'image peuvent aussi être utilisées (voir la section "Use_Index et Use_Color").
La syntaxe pour bump_map est :
BUMP_MAP: normal { bump_map { BITMAP_TYPE "bitmap.ext" [BUMP_MAP_MODS...] } [NORMAL_MODFIERS...] } BITMAP_TYPE: gif | tga | iff | ppm | pgm | png | jpeg | tiff | sys BUMP_MAP_MOD: map_type Type | once | interpolate Type | use_color | use_colour | bump_size Value
Après le mot clé requis BITMAP_TYPE, on trouve une expression chaîne de caractères contentant le nom du fichier bitmap de bosses, du type spécifié. Plusieurs modificateurs optionnels peuvent suivre la spécification du fichier. Ils sont décrits plus bas.
Note : les versions précédentes autorisaient quelques modificateurs avant BITMAP_TYPE, mais cette syntaxe est obsolète.
Note : le format sys est spécifique du système comme BMP pour Windows ou Pict pour Macintosh.
Les fichiers spécifiés dans la déclaration seront d'abord cherchés dans le dossier courant, puis dans les dossiers spécifiés dans les options +L ou Library_Path. Cela facilite la conservation de tels fichiers dans un répertoire séparé en donnant une option Library_Path pour situer la bibliothèque d'applications de bosses. Voir "Les chemins de bibliothèques" pour les détails.
Par défaut, le modèle de bosses est nappé sur le plan x-y. Les bosses sont projetées sur l'objet comme s'il y avait un projecteur quelque part dans la direction -z. Le modèle emplit exactement l'aire carrée de coordonnées (x, y) allant de (0, 0) à (1, 1), sans se soucier de la taille d'origine de l'image. Si vous voulez changer cela, vous pouvez déplacer, tourner ou retailler le pigment ou la texture pour la projeter comme désiré.
Le nom de fichier est suivi, optionnellement, par un ou plusieurs BITMAP_MODIFIERS. Les modificateurs bump_size, use_color et use_index sont spécifiques aux applications de bosses, et sont décrits dans les sections suivantes. Voir la section "Les modificateurs de bitmap" pour les modificateurs généraux de bitmap map_type, once et interpolate.
La taille relative des bosses peut être modifiée avec le modificateur bump_size. Le nombre peut être tout sauf 0, et est typiquement entre 0.1 et 4.0 ou 5.0.
normal { bump_map { gif "stuff.gif" bump_size 5.0 } }
A l'origine, bump_size ne pouvait être utilisé que dans une application de bosses, mais il peut, maintenant, être utilisé avec toute normale. Typiquement, il est utilisé pour écraser une taille déjà définie. Par exemple :
normal { My_Normal // ceci est un identificateur de normale précédemment défini bump_size 2.0 }
Usuellement, l'application de bosses convertit les couleurs des pixels en niveaux de gris d'une valeur allant de 0.0 à 1.0, et calcule les bosses en se basant sur cette valeur. Si vous spécifiez use_index, le numéro de la couleur de la palette sera utilisé pour le calcul de la hauteur. Ainsi, le numéro de couleur 0 sera bas, et le numéro 255 sera haut (si l'image a 256 entrées dans la palette). L'actuelle couleur du pixel n'entre pas en considération avec l'utilisation de l'index. Cette option n'est disponible que pour les formats basés sur une palette. Le mot clé use_color peut être spécifié pour dire que la méthode des couleurs doit être utilisée. L'autre terme use_colour est aussi valide. Ces modificateurs ne doivent être utilisés qu'avec la déclaration bump_map.
Lors du dimensionnement d'une normale; ou d'un objet en possédant une, sa profondeur est affectée. Cela n'est pas toujours désiré. Si vous voulez désactiver le dimensionnement des bosses pour une texture ou une normale, vous pouvez ajouter le mot clé no_bump_scale aux modificateurs de texture ou de normale. Ce modificateur sera passé à toutes les textures ou normales contenues dans cette texture ou normale. Pensez à cela comme la façon dont no_shadow passe pour les objets contenus dans une CSG.
Il est aussi important de noter que si vous ajoutez no_bump_scale à une normale ou une texture qui est contenue dans un autre modèle (comme dans une texture_map ou normal_map), alors le seul dimensionnement qui sera oublié est celui de cette texture ou normale. Le dimensionnement de la texture ou de la normale parent affectera la profondeur des bosses, sauf si no_bump_scale est spécifié au premier niveau de la texture (ou de la normale, si elle n'esp pas englobée dans une texture).
Complément sur les modificateurs de modèle
| 3.4.3 La finition |