2.3.1 Les formes basées sur les courbes

Après avoir acquis quelque expérience avec les formes simples disponibles dans POV-Ray, il est temps d'accéder aux formes plus complexes, plus émouvantes.

Vous devez savoir que les formes décrites maintenant ne sont pas simples à comprendre. Ne soyez pas inquiets si vous ne savez pas comment les utiliser, ou comment elles fonctionnent. Nous essayons seulement quelques exemples, et jouerons avec les caractéristiques décrites dans le chapitre de référence. Il n'y a rien de mieux que d'apprendre par l'expérience.

Vous pouvez vouloir sauter au chapitre "Options des textures simples" avant d'attaquer ces formes complexes.

2.3.1.1 L'objet lathe

Dans le monde réel, lathe fait référence à un procédé de fabrication de formes arrondies par rotation de la matière et usinage pendant le mouvement. Le résultat peut être des objets élaborés, arrondis et élégants comme les pieds de table, de la poterie, etc. Dans POV-Ray, un objet lathe est utilisé pour créer le même genre de chose, bien que nous nous référions plus à l'objet qu'à ce type de production.

Voici une source pour un lathe de base.

#include "colors.inc"
background {White}
camera {
	angle 10
	location <1, 9,-50>
	look_at <0, 2, 0>
}
light_source {
	<20, 20,-20> color White
}
lathe {
	linear_spline
	6,
	<0, 0>, <1, 1>, <3, 2>, <2, 3>, <2, 4>, <0, 4>
	pigment {Blue}
	finish {
		ambient .3
		phong .75
	}
}
Un objet tourné simple
Un objet tourné simple

Nous rendons ceci, et nous voyons que c'est un type simple d'objet tourné, qui ressemble à un chapeau d'enfant. Voyons comment fonctionne le code.

Premièrement, six points sont définis, que le raytraceur connecte avec des lignes. Nous notons que nous avons deux éléments seulement dans les vecteurs des points. Les lignes dessinées sont censées être dans le plan x-y, c'est à dire que tous les éléments sont considérés à z = 0. L'utilisation de vecteurs à deux dimensions est obligatoire (essayer des vecteurs 3D conduira à une erreur, sauf à une exception que nous verrons plus tard, avec les génératrices).

Une fois les lignes définies, le raytraceur les fait tourner autour de l'axe y, et nous pouvons imaginer une trace laissée dans l'espace au fur et à mesure, avec la surface de cette traînée devenant la surface de l'objet.

Les points sont connectés avec des lignes droites car nous avons utilisé le mot clé linear_spline. Il y a d'autres types de génératrices disponibles, qui donneront des courbes lissées, en virant aux alentours de points de transition, mais nous y reviendrons dans un moment.

D'abord, nous allons passer un peu de temps à expliquer la différence entre une forme tournée et une surface de révolution (SOR). L'objet SOR, décrit dans un autre exercice, peut sembler terriblement identique au premier abord. Il déclare également une série de points, en les connectant par des courbes avant d'exercer une rotation autour de l'axe y. La forme tournée a certains avantages comme les différents types de génératrices linéaires, quadratiques et cubiques, et quelque chose de plus :

Les mathématiques simples utilisées par le SOR n'autorisent pas le retour de la courbe sur l'axe des y, ainsi, si on utilise un SOR, tout virage soudain vers le bas de l'axe des y générera une erreur. Par exemple, imaginons que nous voulions une forme tournée allant de <0, 0> à <2, 2>, puis revenant sur <4, 0>. Tourné autour de l'axe des y, cela donnera quelque chose ressemblant à un demi tore arrondi, troué au centre. Mais avec SOR, puisque la courbe redescend sur l'axe des y , cela deviendra une déclaration illégale.

Toutefois, le SOR a un atout, car il utilise des formules simples, et est rendu plus vite que n'importe quelle forme tournée. Finalement, on utilise les SOR si ses limitations conviennent, mais dès que la surface se complique, on passe aux objets lathe.

2.3.1.1.1 Comprendre le concept des génératrices

Ce serait pratique, si vous disposiez, pour comprendre les génératrices, d'un atelier où vous pourriez pratiquer la manipulation des types et points de génératrices, et voir ce que ça donne. Alors, fabriquons le ! Maintenant que nous savons créer un lathe de base, ce sera facile :

#include "colors.inc"
camera {
	orthographic
	up <0, 5, 0>
	right <5, 0, 0>
	location <2.5, 2.5,-100>
	look_at <2.5, 2.5, 0>
}
/* set the control points to be used */
#declare Red_Point = <1.00, 0.00>;
#declare Orange_Point = <1.75, 1.00>;
#declare Yellow_Point = <2.50, 2.00>;
#declare Green_Point = <2.00, 3.00>;
#declare Blue_Point = <1.50, 4.00>;
/* make the control points visible */
cylinder {Red_Point, Red_Point - <0, 0, 20>, .1
	pigment {Red}
	finish {ambient 1}
}
cylinder {Orange_Point, Orange_Point - <0, 0, 20>, .1
	pigment {Orange}
	finish {ambient 1}
}
cylinder {Yellow_Point, Yellow_Point - <0, 0, 20>, .1
	pigment {Yellow}
	finish {ambient 1}
}
cylinder {Green_Point, Green_Point - <0, 0, 20>, .1
	pigment {Green}
	finish {ambient 1}
}
cylinder {Blue_Point, Blue_Point - <0, 0, 20>, .1
	pigment {Blue}
	finish {ambient 1}
}
/* something to make the curve show up */
lathe {
	linear_spline
	5,
	Red_Point,
	Orange_Point,
	Yellow_Point,
	Green_Point,
	Blue_Point
	pigment {White}
	finish {ambient 1}
}
Un atelier de génératrices
Un atelier de génératrices

Maintenant, prenons une profonde inspiration. Nous savons que tout paraît un peu mystérieux, mais avec quelques explications, nous pouvons voir ce que cela fait.

D'abord, nous avons utilisé une caméra orthographique. Si nous ne l'avons pas lu encore, un rapide sommaire est : elle rend une scène plate, éliminant la perspective, comme si l'objet était dessiné sur une feuille de papier (comme une vue de côté dans un modeleur CAD). Il y a plusieurs utilisations de ce type de caméra, mais ici, cela nous permet de voir notre lathe et le bout supérieur de nos cylindres, comme une coupe de sa courbe, plutôt que le lathe lui-même. Pour accentuer l'effet, nous avons enlevé l'ombre avec la finition ambient 1, qui, bien sûr, élimine aussi le besoin d'illuminer. Nous avons également positionné cette vue pour que <0, 0> apparaisse en bas à gauche de notre scène.

Ensuite nous déclarons une série de points. Nous notons que nous avons utilisé des vecteurs 3D plutôt que des vecteurs 2D attendus pour un lathe. C'est l'exception mentionnée plus haut. Quand nous déclarons un point 3D, utilisé dans un lathe, il ne prend que les deux premiers éléments du vecteur, et le troisième est ignoré. Ceci est pratique ici, puisqu'il rend l'exemple possible.

Puis nous faisons deux choses avec les points. D'abord nous les utilisons pour placer des petits cylindres avec les embouts faisant face à la caméra. Ensuite, nous réutilisons les mêmes vecteurs pour définir le lathe.

Puisque déclarer des vecteurs 2D peut avoir des effets bizarres, et que ce n'est pas ce que demandent les cylindres, nous prenons avantage de la tendance du lathe à ignorer le troisième élément en le déclarant à 0.

Le résultat : quand nous générons ce code, nous voyons un lathe blanc sur un fond noir, nous montrant comment la courbe se comporte, et les bouts des cylindres nous désignant la position de nos points de contrôle. Dans ce cas, c'est très simple. On a utilisé une génératrice linéaire, aussi notre courbe est une droite zigzaguant entre les points. Nous changeons les déclarations du Red_Point et du Blue_Point pour donner ce qui suit :

#declare Red_Point  = <2.00, 0.00>;
#declare Blue_Point = <0.00, 4.00>;
Déplacement de quelques points de la génératrice
Déplacement de quelques points de la génératrice

Nous lançons un nouveau rendu et, comme nous pouvons le voir, tout ce qui arrivé est que la ligne bouge pour prendre les nouvelles positions. Les génératrices linéaires sont si simples, que nous pourrions les manipuler en dormant, non ?

Essayons quelque chose de différent. D'abord nous changeons les points comme ceci :

#declare Red_Point = <1.00, 0.00>;
#declare Orange_Point = <2.00, 1.00>;
#declare Yellow_Point = <3.50, 2.00>;
#declare Green_Point = <2.00, 3.00>;
#declare Blue_Point = <1.50, 4.00>;
Un 'lathe' à génératrice quadratique
Un lathe à génératrice quadratique

Nous descendons à la déclaration de la forme tournée et changeons linear_spline en quadratic_spline. Nous rendons la scène et qu'avons-nous ? Bien, nous avons deux choses demandant une explication. D'abord, au lieu de lignes droites, nous avons des courbes lissées entre les points. Ces arcs sont faits de courbes quadratiques, rendant notre lathe plus intéressant. De même, le Red_Point n'est plus connecté. Qu'est-il arrivé ?

Bien, tandis que deux points sont seulement nécessaires pour une ligne droite, il en faut trois pour une courbe quadratique. POV-Ray ne regarde pas seulement les deux points à connecter, mais également le point les précédant immédiatement pour définir la formule de la courbe. Le problème est qu'au début de la courbe, il n'y a pas de point précédent. Alors, nous devons en déclarer un. Donc, quand nous utilisons des génératrices quadratiques, nous devons nous rappeler que le premier point n'est défini que pour les besoins de calcul de POV-Ray. Il ne sera pas pris dans la courbe.

Il y a encore autre chose. Même si notre courbe est faite de lignes incurvées, les transitions entre elles sont .... un peu sales, non ? Cette courbe semble démontrer que les liens entre les points sont terriblement mal adaptés. Selon ce qu'on veut faire, cela peut être acceptable, ou nous pouvons fortement désirer quelque chose de plus lissé. Heureusement, si ce dernier point est vrai, nous avons une autre option.

La génératrice quadratique prend plus de temps de traitement que la linéaire. La formule est beaucoup plus complexe. La génératrice cubique est plus gourmande encore, mais, pour une forme bien lissée, c'est la seule solution. Nous revenons en arrière et remplaçons simplement quadratic_spline par cubic_spline. Nous le rendons, et voyons ce que nous avons.

Un 'lathe' à génératrice cubique
Un lathe à génératrice cubique

Tandis que la génératrice quadratique demande trois points pour le calcul, la génératrice cubique en demande quatre. Donc, comme prévu, le Blue_Point est sorti de la courbe, comme le Red_Point, puisque les premiers et derniers points ne sont plus que des points de contrôle pour donner la forme à la courbe entre les points restants. Mais voyez la jonction de Orange_Point à Yellow_Point et au retour sur Green_Point. Maintenant, au lieu de sembler mal adapté, ce segment de courbe est parfaitement lissé.

Enfin, il y a un dernier type de génératrice quadratique, le bezier_spline. Celui-ci prend quatre points par section. Le point de départ, de fin, et deux points intermédiaires. Pour l'utiliser, nous devons faire quelques modifications à notre atelier. Détruire le point jaune, le cylindre jaune. Changer les points pour :

#declare Red_Point = <2.00, 1.00>;
#declare Orange_Point = <3.00, 1.50>;
#declare Green_Point = <3.00, 3.50>;
#declare Blue_Point = <2.00, 4.00>;

Et changer la forme tournée pour :

lathe {
	bezier_spline
	4,
	Red_Point,
	Orange_Point,
	Green_Point,
	Blue_Point
	pigment {White}
	finish {ambient 1}
}

Les points de contrôle vert et orange ne sont pas connecté à la courbe. Déplaçons-les un peu, par exemple #declare Orange_Point = <1.00, 1.50>;. La ligne qui peut maintenant être dessinée depuis son point de départ jusqu'au point de contrôle le plus proche (rouge à orange) montre la tangente de la courbe au point de départ. Même chose pour le dernier point, bleu à vert.

Un 'lathe' à génératrice de bezier
Un lathe à génératrice de bezier

Un segment courbe est bien, deux est mieux. Aussi nous allons ajouter un autre segment et le connecter au point bleu. Un segment a quatre points, donc deux segments en ont huit. Le premier point du second segment est le dernier du premier segment. Le point bleu. Aussi nous n'avons besoin que de déclarer trois points supplémentaires. Nous devons aussi déplacer la caméra et ajouter des cylindres. Voici la scène complète :

#include "colors.inc"
camera {
	orthographic
	up <0, 7, 0>
	right <7, 0, 0>
	location <3.5, 4,-100>
	look_at <3.5, 4, 0>
}
/* place les points de contrôle à utiliser */
#declare Red_Point = <2.00, 1.00>;
#declare Orange_Point = <1.00, 1.50>;
#declare Green_Point = <3.00, 3.50>;
#declare Blue_Point = <2.00, 4.00>;
#declare Green_Point2 = <3.00, 4.50>;
#declare Orange_Point2 = <1.00, 6.50>;
#declare Red_Point2 = <2.00, 7.00>;
/* rend les points de contrôles visibles */
cylinder {Red_Point, Red_Point - <0, 0, 20>, .1
	pigment {Red} finish {ambient 1}
}
cylinder {Orange_Point, Orange_Point - <0, 0, 20>, .1
	pigment {Orange} finish {ambient 1}
}
cylinder {Green_Point, Green_Point - <0, 0, 20>, .1
	pigment {Green} finish {ambient 1}
}
cylinder {Blue_Point, Blue_Point - <0, 0, 20>, .1
	pigment {Blue} finish {ambient 1}
}
cylinder {Green_Point2, Green_Point2 - <0, 0, 20>, .1
	pigment {Green} finish {ambient 1}
}
cylinder {Orange_Point2, Orange_Point2 - <0, 0, 20>, .1
	pigment {Orange} finish {ambient 1}
}
cylinder {Red_Point2, Red_Point2 - <0, 0, 20>, .1
	pigment {Red} finish {ambient 1}
}
/* quelque chose pour faire apparaître la courbe */
lathe {
	bezier_spline
	8,
	Red_Point, Orange_Point, Green_Point, Blue_Point
	Blue_Point, Green_Point2, Orange_Point2, Red_Point2
	pigment {White}
	finish {ambient 1}
}
Deux segments à génératrice de bezier, pas lissés
Deux segments à génératrice de bezier, pas lissés

Une belle courbe, mais si nous voulons la lisser ? Jetons un regard sur les tangentes sur le point bleu, traçant les lignes Green_Point, Blue_point et Green_Point2, Blue_point. Regardez l'angle qu'elles font, aussi pointu qu'une dent. Que ce passe-t-il avec un angle plus grand ? Un angle de 180° ? Essayons quelques positions pour Green_point2 et finissons avec #declare Green_Point2 = <1.00, 4.50>;. Une courbe lissée. Si vous vous assurez que les deux points de contrôle et le point de connection sont sur une ligne, la courbe est parfaitement lisse. En général, cela peut être fait par #declare Green_Point2 = Blue_Point+(Blue_Point-Green_Point);

Un 'lathe' à génératrice de bezier lissé
Un lathe à génératrice de bezier lissé

Le concept des génératrices est utile et nécessaire, et sera vu de nouveau dans les prismes et les polygones. Mais avec un peu de bricolage, nous pouvons rapidement avoir le sentiment de pouvoir travailler avec elles.

2.3.1.2 L'objet surface de révolution

Les bouteilles, vases et verres font de jolis objets dans les scènes en raytracing. Nous voulons créer une coupe dorée en utilisant l'objet surface de révolution (objet SOR).

Nous devons d'abord penser à la forme finale de l'objet. C'est difficile d'y parvenir avec une série de points décrivant une courbe, sans l'aide d'un modeleur supportant les SOR de POV-Ray. Si un tel programme est disponible, nous devons en user.

Les points configurant la forme de notre coupe
Les points configurant la forme de notre coupe

Nous utiliserons les points montrés dans la figure du dessus. Ils sont huit, décrivant la courbe qui sera mise en rotation autour de l'axe y, pour donner notre coupe. La courbe est calculée avec la méthode donnée dans la section de référence (voir "La surface de révolution").

Maintenant, il est temps de s'occuper de la scène qui utilise la SOR. Nous éditons un fichier appelé sordemo.pov et entrons le texte suivant.

#include "colors.inc"
#include "golds.inc"
global_settings {assumed_gamma 2.2}
camera {
	location <10, 15,-20>
	look_at <0, 5, 0>
	angle 45
}
background {color rgb <0.2, 0.4, 0.8>}
light_source {<100, 100,-100> color rgb 1}
plane {
	y, 0
	pigment {checker color Red, color Green scale 10}
}
sor {
	8,
	<0.0,-0.5>,
	<3.0, 0.0>,
	<1.0, 0.2>,
	<0.5, 0.4>,
	<0.5, 4.0>,
	<1.0, 5.0>,
	<3.0, 10.0>,
	<4.0, 11.0>
	texture {T_Gold_1B}
}

La scène contient notre coupe se tenant sur un plancher en damier. Le traçage donne l'image suivante.

Un objet SOR
Un objet SOR

La surface de révolution est décrite d'abord par le nombre de points, suivi par les points. Chaque point donne le rayon de la courbe à une hauteur donnée. Par exemple, le premier point valide (le second de la liste) est à la hauteur 0.0, de rayon 3. Nous devons prendre garde à ce que chaque point soit plus haut que le précédent, sinon le programme échouera sur un message d'erreur. Le premier et le dernier point de la liste sont utilisés pour déterminer la pente au début et à la fin de la courbe, et ils peuvent être définis pour n'importe quelle hauteur.

2.3.1.3 L'objet prisme

Le prisme est essentiellement un polygone ou une courbe fermée balayant un circuit linéaire. Nous pouvons imaginer une forme laissant une telle trace dans l'espace, et la surface de cette trace est celle de notre prisme. La courbe ou le polygone peut être la combinaison de sous-formes, utiliser chacun des trois types de génératrice, et conserver une épaisseur constante pendant le balayage, ou se réduire doucement vers un point. Mais avant que cela ne devienne trop confus, faisons un premier pas avec une forme simple de prisme. Nous entrons et rendons le code suivant (voir fichier prismdm1.pov).

#include "colors.inc"
background {White}
camera {
	angle 20
	location <2, 10,-30>
	look_at <0, 1, 0>
}
light_source {<20, 20,-20> color White}
prism {
	linear_sweep
	linear_spline
	0,	// trace la forme suivante d'ici ...
	1,	// ... jusqu'ici
	7,	// le nombre de points de la forme ...
	<3, 5>, <-3, 5>, <-5, 0>, <-3,-5>, <3,-5>, <5, 0>, <3, 5>
	pigment {Green}
}
Une forme de prisme hexagonal
Une forme de prisme hexagonal

Cela produit une polygone hexagonal, qui est balayé de y = 0 à y = 1. En d'autres mots, nous avons maintenant un hexagone extrudé. Un point à noter est que c'est une figure à six côtés, alors que nous avions sept points. N'oublions pas qu'un polygone est supposé être fermé, ce que nous avons fait en entrant un septième point identique au premier. Techniquement, avec les polygones linéaires, si nous ne l'avions pas fait, POV-Ray aurait automatiquement rejoint les deux extrémités, toutefois, une alarme serait apparue. Cela ne fonctionne qu'avec les génératrices linéaires, alors nous devons prendre en compte ces messages d'alerte !

2.3.1.3.1 Enseigner un nouveau truc sur les vieilles génératrices

Si vous avez suivi le chapitre couvrant les génératrices, sous le cours concernant le lathe (voir la section "Comprendre le concept des génératrices"), nous savons qu'il y a deux autres types de génératrice : la génératrice quadratique, et la cubique. Bien entendu, nous pouvons les utiliser sur les prismes pour faire plus de formes libres, et doucement incurvées.

Il y a un piège, et vous devez lire attentivement cette section si vous ne voulez pas vous arracher les cheveux devant de mystérieux messages "too few points in prism", qui bloqueront votre rendu. Vous devez probablement deviner le sujet : comment clore une génératrice non linéaire. Au contraire de ces dernières, qui dessinent simplement une ligne entre le premier et dernier point si vous oubliez de faire le dernier égal au premier, les génératrices quadratiques et cubiques sont plus difficiles.

Avant tout, nous nous souvenons que les quadratiques définissent l'équation de la courbe qui connectera deux points, en se basant sur ces deux points et le précédent, ainsi, le premier est juste un point de contrôle et ne fait pas partie de la courbe. Cela signifie que : quand nous fabriquons notre forme à partir de génératrice quadratique, nous devons copier le second point sur celui de fin, puisque le premier n'est pas dans la courbe - c'est juste un point de contrôle pour les besoins de calcul.

De la même manière, les génératrices cubiques ont besoin de deux points de contrôle, le premier et le dernier, donc, pour fermer une génératrice cubique, nous devons copier le second point sur l'avant dernier. Sinon, nous obtenons l'erreur "too few points in prism". POV-Ray attend toujours que vous fermiez la forme, et quand il passe sur les points et qu'il ne trouve pas la fermeture, une erreur est générée.

Confus ? OK, pourquoi pas un exemple ? Nous remplaçons le prisme de notre dernier code par ceci (voir fichier prismdm2.pov).

prism {
	cubic_spline
	0,	// trace la forme suivante d'ici ...
	1,	// ... jusqu'ici
	6,	// le nombre de points de la forme ...
	<3,-5>,	// point#1 (point de contrôle... pas sur la courbe)
	<3, 5>,	// point#2  ... CE POINT ...
	<-5, 0>,	// point#3
	<3,-5>,	// point#4
	<3, 5>,	// point#5 ... DOIT CORRESPONDRE A CE POINT
	<-5, 0>	// point#6 (point de contrôle... pas sur la courbe)
	pigment {Green}
}
Une forme de prisme triangulaire, cubique
Une forme de prisme triangulaire, cubique

Ce simple prisme produit ce qui ressemble à un triangle extrudé aux angles arrondis. Les points deux, trois et quatre sont les coins, le point cinq ferme la courbe en revenant au numéro deux. Les points un et six sont des contrôles et n'apparaissent pas, il ne sont utilisés que pour calculer le type de courbe à utiliser entre les autres points.

2.3.1.3.2 Transitions lissées

Maintenant, quelque chose d'important à noter est que nous avons le point un égal au point quatre, et le point six égal au point trois. Oui, C'est important. Même si la courbe est correctement fermée, si nous n'avions pas placé ces points ainsi, les transitions n'auraient pas été aussi lissées. Changeons les points un et six en <4, 6> et <0, 7> respectivement et rendons pour voir l'altération de l'angle arrière (voir prismdm3.pov).

Plus généralement, si nous voulons une fermeture lissée sur une génératrice cubique, nous rendons le premier point égal à l'avant-avant-dernier, et le dernier point égal au troisième. Sur une génératrice quadratique, le problème est le même, mais comme il n'y a qu'un point de contrôle, il faut rendre le premier point égal à l'avant dernier.

2.3.1.3.3 Sous-formes multiples

Tout comme avec le polygone (voir la section "L'objet polygone"), le prisme est très flexible et nous autorise l'ajout de plusieurs sous-prismes. Pour cela, la seule chose à faire et de continuer à saisir des points après avoir entré la première forme. La seconde forme peut être un ajout allant dans une autre direction que le premier, mais le plus intéressant est que si des sous-formes se recouvrent, cette région est comme vidée de ces deux formes. Voyons un autre exemple. Encore une fois, il faut les codes de la caméra, sources de lumière et autres, puis nous plaçons ce prisme complexe (voir fichier prismdm4.pov).

prism {
	linear_sweep
	cubic_spline
	0,	// trace la forme suivante d'ici ...
	1,	// ... jusqu'ici
	18,	// le nombre de points de la forme ...
	<3,-5>, <3, 5>, <-5, 0>, <3,-5>, <3, 5>, <-5, 0>,	// sous-forme #1
	<2,-4>, <2, 4>, <-4, 0>, <2,-4>, <2, 4>, <-4, 0>,	// sous-forme #2
	<1,-3>, <1, 3>, <-3, 0>, <1,-3>, <1, 3>, <-3, 0>	// sous-forme #3
	pigment {Green}
}
Utilisation de sous-formes pour créer une forme plus complexe
Utilisation de sous-formes pour créer une forme plus complexe

Pour des raisons de lisibilité, nous avons créé une ligne pour chaque sous-forme, mais le raytraceur ne se base que sur l'égalité des points, lui indiquant à quel moment une forme se termine, et une autre commence. Nous rendons ce nouveau prisme, et regardons le résultat. C'est la même forme familière, mais elle a été creusée en son centre, et une plus petite y a été introduite.

Simplement, l'anneau extérieur est l'endroit où n'existe qu'une sous-forme, la partie creusée est celle ou les sous-formes une et deux se recoupent. Au centre, l'objet réapparaît parce que les trois formes se chevauchent, redonnant un nombre impair de pièces chevauchées. Avec cette technique, vous pouvez faire toutes sortes de prismes complexes !

2.3.1.3.4 L'élévation conique et l'effet effilant

Dans notre prisme d'origine, le mot clé linear_sweep est optionnel. C'est l'élévation par défaut d'un prisme. Mais il y a un autre type d'élévation, extrêmement utile : l'élévation conique. L'idée de base est comme un prisme classique, à part que, au fur et à mesure que la forme s'élève de la hauteur d'origine à la hauteur finale, nous l'étendons constamment d'un point singulier, à l'origine, à sa taille complète, à l'arrivée. Pour se rendre compte de l'utilisation possible, nous remplaçons notre prisme existant avec ceci (voir prismdm4.pov):

prism {
	conic_sweep
	linear_spline
	0,	// hauteur 1
	1,	// hauteur 2
	5,	// le nombre de points de la forme...
	<4, 4>, <-4, 4>, <-4,-4>, <4,-4>, <4, 4>
	rotate <180, 0, 0>
	translate <0, 1, 0>
	scale <1, 4, 1>
	pigment {gradient y scale .2}
}
Création d'une pyramide avec l'élévation conique
Création d'une pyramide avec l'élévation conique

Le pigment graduel a été sélectionné pour ajouter un peu de définition à notre objet sans modifier les sources de lumière et la caméra, et une fois rendu, qu'avons nous créé ? Une pyramide rayée horizontalement ! Nous reconnaissons la génératrice linéaire qui rejoint les quatre points d'un carré, le cinquième servant à fermer la figure.

Notez toutes les transformations dans la déclaration de l'objet. Cela mérite quelques explications. La rotation et la translation sont simple. Normalement, une élévation conique commence par un point unique, et s'étale ou fur et à mesure de sa croissance, et bien sûr, cela doit être retourné pour donner une pyramide. Donc nous avons basculé la forme autour de l'axe x, pour la mettre dans le bon sens, et comme elle tourne autour de l'origine, nous l'avons déplacée pour la repositionner.

La tailla est là pour donner les bonnes proportions à cet exemple. La base est de huit unités par huit unités mais la hauteur (de y=1 à y=0) est seulement de une unité, donc nous avons dû l'étirer un peu. Là, vous pensez probablement "Pourquoi ne pas avoir balayé de y = 0 à y = 4 et évité le changement de taille ?"

C'est une erreur grave avec les élévations coniques. Pour voir ce qui ne va pas, mettons-le en pratique (voir fichier prismdm5.pov). Nous devons enlever le redimensionnement, et remplacer la ligne qui dit

	1,	// hauteur 2

par

	4,	// hauteur 2

Cela place la seconde hauteur à y=4, donc, rendons-le et voyons les effets.

Choisir une seconde hauteur plus grande que un avec les élévations coniques
Choisir une seconde hauteur plus grande que un avec les élévations coniques

Wow ! Notre hauteur est correcte , mais la base est énorme maintenant ! Qu'est ce qui ne va pas ? Simple. La base que nous avons décrite, prend sa valeur à y=1 sans se soucier de la seconde hauteur. Alors, si nous plaçons la hauteur au-dessus de un, l'élévation continue de s'étendre jusqu'à notre hauteur, rendant notre base de plus en plus grosse.

Pour éviter de perdre le contrôle d'une élévation conique, il est préférable de laisser la seconde hauteur à 1, et d'utiliser la déclaration scale pour ajuster la hauteur par rapport à la largeur. Ainsi, nous sommes sûrs que les coins de la base resteront là où nous les avons placés.

Cela nous conduit à une autre chose intéressante sur les élévations coniques. Et si nous ne voulions pas qu'elle se termine par un point ? Et si nous voulions une ziggourat au lieu d'une pyramide ? Facile à faire. Après avoir replacé la seconde hauteur à 1 et replacé notre échelle, nous changeons la ligne

	0,	// hauteur 1

par

	0.251,	// hauteur 1
Augmentation de la première hauteur avec une élévation conique
Augmentation de la première hauteur avec une élévation conique

Quand nous rendons, nous voyons que l'élévation coupe court, nous donnant une pyramide sans sommet. La quantité de sommet oblitéré dépend de la différence entre les deux hauteurs.

2.3.1.4 L'objet 'Sphere Sweep'

Un objet 'Sphere Sweep' est l'espace qu'une sphère occupe pendant son mouvement le long d'une courbe. Donc nous devons spécifier le type de génératrice et une liste de points de contrôle pour définir cette courbe. Pour aider POV-Ray nous lui disons combien de points de contrôle sont utilisés. En plus, nous donnons également le rayon que doit avoir la sphère en mouvement lorsqu'elle passe à travers chaque point de contrôle.

La syntaxe de l'objet sphere_sweep est :

sphere_sweep {
	linear_spline | b_spline | cubic_spline
	NUM_OF_SPHERES,
	CENTER, RADIUS,
	CENTER, RADIUS,
	...
	CENTER, RADIUS
	[tolerance DEPTH_TOLERANCE]
	[OBJECT_MODIFIERS]
}

Un exemple pour un pinceau sphérique linéaire pourrait être :

sphere_sweep {
	linear_spline
	4,
	<-5,-5, 0>, 1
	<-5, 5, 0>, 1
	<5,-5, 0>, 1
	<5, 5, 0>, 1
}

Cet objet est décrit par quatre sphères. Vous pouvez utiliser autant de sphères que vous voulez pour décrire l'objet, mais vous avez besoin d'au moins deux sphères pour une linéaire, et quatre sphères au moins avec une génératrice cubic_spline ou b_spline.

L'exemple du dessus donnera un objet ressemblant à la lettre "N". La pinceau sphérique passe à travers tous les points qui sont connectés par des cônes droits.

Le changement du type d'interpolation pour un cubic_spline produit un objet un peu différent, légèrement courbé. Il commence à la seconde sphère et finit à l'avant-dernière. Puisque le premier et dernier point sont utilisés pour contrôler la courbe, vous avez besoin de deux points supplémentaires pour avoir une forme pouvant être comparée à la génératrice linéaire. Ajoutons-les :

sphere_sweep {
	cubic_spline
	6,
	<-4,-5, 0>, 1
	<-5,-5, 0>, 1
	<-5, 5, 0>, 0.5
	<5,-5, 0>, 0.5
	<5, 5, 0>, 1
	<4, 5, 0>, 1
	tolerance 0.1
}

Ainsi la génératrice cubique crée une brosse sphérique passant à travers tous les points (sauf le premier et le dernier). Dans cet exemple, le rayon de la seconde et troisième sphère a été changé. Nous avons aussi ajouté le mot clé "tolerance" parce que des points noirs apparaissent sur la surface avec la valeur par défaut (0.000001).

Quand on utilise une b_spline, l'objet rendu est quelque chose de similaire à la génératrice cubique, mais il ne passe pas à travers les points de contrôle. Il passe quelque part entre eux.

2.3.1.5 L'objet surface bicubique

Les surfaces bicubiques sont des représentations de surfaces pratiques car elles facilitent la définition de surfaces en utilisant seulement quelques points de contrôle. Les points de contrôle servent à définir la forme de la surface. Au lieu de définir les sommets de triangles, nous donnons simplement les coordonnées de points de contrôle. Une seule pièce a 16 points de contrôle, quatre aux angles, et le reste est positionné pour diviser la pièce en petites sections. POV-Ray ne trace pas les surfaces directement, elles sont évaluées en utilisant des triangles comme décrit dans la section Langage de description de scène.

Les surfaces de Bezier sont presque toujours créées en utilisant un modeleur, mais pour ce cours, nous les manipulerons à la main. Des modeleurs qui supportent les surfaces bicubiques et exportent vers POV-Ray peuvent être trouvés dans la section des liens à www.povray.org
Entamons la scène de base et commençons l'exploration de la surface bicubique.

#version 3.5;
global_settings {assumed_gamma 1.0}
background {rgb <1, 0.9, 0.9>}
camera {location <1.6, 5,-6> look_at <1.5, 0, 1.5> angle 40}
light_source {<500, 500,-500> rgb 1}
#declare B11 = <0, 0, 3>; #declare B12 = <1, 0, 3>;
#declare B13 = <2, 0, 3>; #declare B14 = <3, 0, 3>;	// ligne 1

#declare B21 = <0, 0, 2>; #declare B22 = <1, 0, 2>;
#declare B23 = <2, 0, 2>; #declare B24 = <3, 0, 2>;	// ligne 2

#declare B31 = <0, 0, 1>; #declare B32 = <1, 0, 1>;
#declare B33 = <2, 0, 1>; #declare B34 = <3, 0, 1>;	// ligne 3

#declare B41 = <0, 0, 0>; #declare B42 = <1, 0, 0>;
#declare B43 = <2, 0, 0>; #declare B44 = <3, 0, 0>;	// ligne 4

bicubic_patch {
	type 1 flatness 0.001
	u_steps 4 v_steps 4
	uv_vectors
	<0, 0> <1, 0> <1, 1> <0, 1>
	B11, B12, B13, B14
	B21, B22, B23, B24
	B31, B32, B33, B34
	B41, B42, B43, B44
	uv_mapping
	texture {
		pigment {
			checker
			color rgbf <1, 1, 1, 0.5>
			color rgbf <0, 0, 1, 0.7>
			scale 1/3
		}
		finish {phong 0.6 phong_size 20}
	}
	no_shadow
}

Les points B11, B14, B41, B44 sont les coins de la surface. Tous les autres sont des points de contrôle. Les noms des points déclarés sont comme ceci : B pour la couleur de la surface, le premier chiffre donne le numéro de ligne, le second donne le numéro de colonne. Si vous rendez la scène, vous obtenez un échiquier carré bleu et blanc, pas très excitant.

D'abord nous ajouterons quelques sphères pour rendre les points de contrôle visibles. Comme nous ne voulons pas taper le code de 16 sphères, nous utiliserons un tableau et une boucle while pour construire les sphères.

#declare Points = array[16] {
	B11, B12, B13, B14
	B21, B22, B23, B24
	B31, B32, B33, B34
	B41, B42, B43, B44
}
#declare I = 0;
#while (I<16)
	sphere {
		Points[I], 0.1
		no_shadow
		pigment {
			#if (I = 0 | I = 3 | I = 12 | I = 15)
				color rgb <1, 0, 0>
			#else
				color rgb <0, 1, 1>
			#end
		}
	}
	#declare I = I+1;
#end

Le rendu de cette scène montre la surface avec ses points de coin en rouge et ses points de contrôle en cyan. Maintenant il est temps d'explorer.
Changez B41 à <-1, 0, 0> et rendez.


Changez B41 à <-1, 1, 0> et rendez.

Changez B41 à <1, 2, 1> et rendez.

Faisons quelques exercices avec les points de contrôle. Repartez sur une surface plate.
Changez B42 à <1, 2, 0> et B43 à <2,-2, 0> et rendez.


Remettez B42 et B43 à leurs positions d'origine et essayez B34 à <4, 2, 1> et B24 à <2,-2, 2> et rendez.

Faites encore quelques déplacements, et essayez aussi les points de contrôle au centre.

'Bicubic_patch' avec les points de contrôle
Bicubic_patch avec les points de contrôle

Nous notons deux choses :

Maintenant, revenons à notre atelier de génératrices et jetons de nouveau un regard sur bezier_spline. Bien sûr, les points B11, B12, B13, B14, forment une courbe de bezier. Ainsi que les points B11, B21, B31, B41 et B41, B42, B43, B44 et B14, B24, B34, B44.

Jusque là nous ne nous sommes attardés que sur une surface unique, mais l'une des forces de la surface bicubique est dans la possibilité de les connecter proprement, pour faire des surfaces plus grandes. La manière de connecter est simple puisqu'il y a actuellement seulement deux règles à suivre. Cela peut être fait en utilisant une macro bien conçue ou en utilisant un modeleur. Pour donner une idée de ce qui est nécessaire nous ferons un exemple à la main.

D'abord reprenez une surface plate. Puis changez #declare B14 = <3, 0, 3>; #declare B24 = <3, 2, 2>; #declare B34 = <3.5, 1, 1>; #declare B44 = <3,-1, 0>; #declare B41 = <0,-1, 0>;. Reculez un peu la caméra camera {location <3.1, 7,-8> look_at <3,-2, 1.5> angle 40} et détruisez tout le code pour les sphères.


Nous allons essayer maintenant de coller une surface sur le côté droit de la précédente. Bien sûr, les points sur le côté gauche (colonne 1) de la nouvelle surface doivent être à la même position que les points sur le côté droit (colonne 4) de l'ancienne.

Rendez la scène, en incluant notre nouvelle surface :

#declare R11 = B14; #declare R12 = <4, 0, 3>;
#declare R13 = <5, 0, 3>; #declare R14 = <6, 0, 3>;	// ligne 1

#declare R21 = B24; #declare R22 = <4, 0, 2>;
#declare R23 = <5, 0, 2>; #declare R24 = <6, 0, 2>;	// ligne 2

#declare R31 = B34; #declare R32 = <4, 0, 1>;
#declare R33 = <5, 0, 1>; #declare R34 = <6, 0, 1>;	// ligne 3

#declare R41 = B44; #declare R42 = <4, 0, 0>;
#declare R43 = <5, 0, 0>; #declare R44 = <6, 0, 0>;	// ligne 4

bicubic_patch {
	type 1 flatness 0.001
	u_steps 4 v_steps 4
	uv_vectors
	<0, 0> <1, 0> <1, 1> <0, 1>
	R11, R12, R13, R14
	R21, R22, R23, R24
	R31, R32, R33, R34
	R41, R42, R43, R44
	uv_mapping
	texture {
		pigment {
			checker
			color rgbf <1, 1, 1, 0.5>
			color rgbf <1, 0, 0, 0.7>
			scale 1/3
		}
		finish {phong 0.6 phong_size 20}
	}
	no_shadow
}

Cela donne un résultat désappointant. Les surfaces sont connectées mais pas correctement. Dans la connection de surfaces, les mêmes principes s'appliquent que pour la connection de deux courbes de bezier comme nous le voyons dans l'atelier de génératrice. Le point de contrôle, le point de connection et le point de contrôle suivant doivent être sur une ligne pour donner un résultat lissé. Aussi il est préféreable, mais non obligatoire, que les distances entre les deux points de contrôle et le point de connection soient les mêmes. Pour la surface bicubique nous devons faire la même chose, pour tous les points de connection concernés dans la jonction. Aussi, dans notre cas, les points suivants doivent être sur une ligne :

Pour cela nous faisons :

#declare R12 = B14+(B14-B13);
#declare R22 = B24+(B24-B23);
#declare R32 = B34+(B34-B33);
#declare R42 = B44+(B44-B43);
surfaces, (in)correctement connectées
surfaces, (in)correctement connectées

Cela donne une surface lissée. L'ajout d'une troisième surface en avant est relativement simple maintenant :

#declare G11 = B41; #declare G12 = B42;
#declare G13 = B43; #declare G14 = B44;	// ligne 1

#declare G21 = B41+(B41-B31); #declare G22 = B42+(B42-B32);
#declare G23 = B43+(B43-B33); #declare G24 = B44+(B44-B34);	// ligne 2

#declare G31 = <0, 0,-2>; #declare G32 = <1, 0,-2>;
#declare G33 = <2, 0,-2>; #declare G34 = <3, 2,-2>;	// ligne 3

#declare G41 = <0, 0,-3>; #declare G42 = <1, 0,-3>;
#declare G43 = <2, 0,-3>; #declare G44 = <3, 0,-3>;	// ligne 4

bicubic_patch {
	type 1 flatness 0.001
	u_steps 4 v_steps 4
	uv_vectors
	<0, 0> <1, 0> <1, 1> <0, 1>
	G11, G12, G13, G14
	G21, G22, G23, G24
	G31, G32, G33, G34
	G41, G42, G43, G44
	uv_mapping
	texture {
		pigment {
			checker
			color rgbf <1, 1, 1, 0.5>
			color rgbf <0, 1, 0, 0.7>
			scale 1/3
		}
		finish {phong 0.6 phong_size 20}
	}
	no_shadow
}

Enfin, plaçons quelques sphères dans la scène et ajoutons quelques cylindres pour visualiser. Voyez ce qui arrive si vous bougez par exemple B44, B43, B33 ou B34.

#declare Points = array[8] {B33, B34, R32, B43, B44, R42, G23, G24}
#declare I = 0;
#while (I < 8)
	sphere {
		Points[I], 0.1
		no_shadow
		pigment {
			#if (I = 4)
				color rgb <1, 0, 0>
			#else
				color rgb <0, 1, 1>
			#end
		}
	}
	#declare I = I+1;
#end
union {
	cylinder {B33, B34, 0.04} cylinder {B34, R32, 0.04}
	cylinder {B43, B44, 0.04} cylinder {B44, R42, 0.04}
	cylinder {G23, G24, 0.04}
	cylinder {B33, B43, 0.04} cylinder {B43, G23, 0.04}
	cylinder {B34, B44, 0.04} cylinder {B44, G24, 0.04}
	cylinder {R32, R42, 0.04}
	no_shadow
	pigment {color rgb <1, 1, 0>}
}

La partie difficile dans l'utilisation des surfaces bicubiques n'est pas la connection de plusieurs surfaces. La difficulté est de garder le contrôle sur la forme que vous voulez construire. A mesure que des surfaces sont ajoutées, pour garder un résultat lissé, le contrôle sur la position de nombreux points devient difficile.

3 surfaces, quelques points de contrôle
3 surfaces, quelques points de contrôle

2.3.1.6 L'objet texte

L'objet text est une primitive qui peut utiliser des polices TrueType et les collections TrueType pour créer des objets texte. Ces objets peuvent être utilisés dans un CSG, transformés et texturés comme n'importe quelle autre primitive POV.

Pour cette leçon, nous aurons deux utilisations de l'objet texte. D'abord, faisons quelques blocs de lettres sur un plan en damier. Toute police TTF ira, mais nous utiliserons timrom.ttf ou cyrvetic.ttf qui sont fournies avec POV-Ray.

Nous créons un fichier appelé textdemo.pov et le modifions comme ceci :

#include "colors.inc"
camera {
	location <0, 1,-10>
	look_at 0
	angle 35
}
light_source {<500, 500,-1000> White}
plane {
	y, 0
	pigment {checker Green White}
}

Maintenant, ajoutons l'objet texte. Nous utiliserons la police timrom.ttf et nous créerons la phrase 'POV-RAY 3.0'. Pour l'instant, les lettres seront rouges. La syntaxe est très simple. La première phrase entre apostrophes est le nom de la police, la seconde est la phrase à rendre. Les deux nombres sont l'épaisseur et l'offset. Les valeurs de .5 à 2 sont les meilleures pour l'épaisseur. L'offset ajoute une distance entre les lettres. Nous le laisserons à 0 pour l'instant.

text {
	ttf "timrom.ttf" "POV-RAY 3.0" 1, 0
	pigment {Red}
}

Nous notons que les lettres sont vers la droite de l'écran. C'est parce que le coin bas avant gauche de la première lettre est à l'origine. Pour centrer la phrase, nous devons la déplacer sur l'axe des x. Mais de combien ? Dans les documents, nous voyons que les lettres ont entre 0.5 et 0.75 unités de haut. Si nous assumons qu'elles ont environ 0.5 unités sur l'axe x, alors, la phrase a six unités de long (12 caractères et espaces). Déplaçons le texte de 3 unités dans le sens inverse de l'axe x.

text {
	ttf "timrom.ttf" "POV-RAY 3.0" 1, 0
	pigment {Red}
	translate -3*x
}

C'est mieux. Maintenant, jouons un peu avec quelques paramètres de l'objet texte. D'abord, augmentons l'épaisseur jusqu'à... disons 25 !

text {
	ttf "timrom.ttf" "POV-RAY 3.0" 25, 0
	pigment {Red}
	translate -2.25*x
}

Ce n'est pas mal. Maintenant, remettons l'épaisseur à 1 et essayons un offset différent. Mettons-le à 0.1 et rendons la scène.

Attendez une minute ?! Les lettres partent selon un angle ! Ce n'est pas ce que les documents disaient ! C'est comme si l'offset s'appliquait sur l'axe des x et des y, au lieu du seul axe des x. Cela serait-il un vecteur au lieu d'un nombre ? Essayons. Nous remplaçons 0.1 par 0.1*x et rendons de nouveau.

C'est ça ! Les lettres restent alignées sur l'axe x, avec un léger écartement. Vérifions encore en donnant un offset seulement sur l'axe y. Nous remplaçons 0.1*x par 0.1*y. Cette fois encore, cela fonctionne comme prévu, avec les lettres grimpant vers la droite, sans espace additionnel sur l'axe x. Maintenant, essayons l'axe z. Nous remplaçons 0.1*y par 0.1*z. Le rendu est décevant. Aucun offset ! Il ne peut s'appliquer que sur les axes x et y.

Finissons notre scène en donnant une agréable texture aux lettres, en utilisant une sympathique épaisseur, et en ajoutant un léger offset sur l'axe y. Pour le plaisir, nous y jetons un ciel, améliorons un peu notre plan, et utilisons une vue de caméra plus intéressante (nous rendons la scène à 640x480 +A0.2) :

#include "colors.inc"
camera {
	location <-5, .15,-2>
	look_at <.3, .2, 1>
	angle 35
}
light_source {<500, 500,-1000> White}
plane {
	y, 0
	texture {
		pigment {SeaGreen}
		finish {reflection .35 specular 1}
		normal {ripples .35 turbulence .5 scale .25}
	}
}
text {
	ttf "timrom.ttf" "POV-RAY 3.0" 25, 0.1*y
	pigment {BrightGold}
	finish {reflection .25 specular 1}
	translate -3*x
}
#include "skies.inc"
sky_sphere {S_Cloud5}

Essayons d'utiliser le texte dans un objet CSG. Nous allons tenter de créer une incrustation dans un bloc de pierre. Nous créons un nouveau fichier appelé textcsg.pov et modifié comme ceci :

#include "colors.inc"
#include "stones.inc"
background {color rgb 1}
camera {
	location <-3, 5,-15>
	look_at 0
	angle 25
}
light_source {<500, 500,-1000> White}

Maintenant, créons le bloc. Nous voulons qu'il fasse 8 unités de long, car notre texte (POV-RAY 3.0) en fait six. Nous voulons aussi qu'il fasse 4 unités de haut et une unité d'épaisseur. Mais nous voulons éviter une coïncidence de surface avec le texte, alors nous mettrons la première coordonnée z à 0.1 au lieu de 0. Finalement, nous lui donnons une jolie texture de pierre.

box {
	<-3.5,-1, 0.1>, <3.5, 1, 1>
	texture {T_Stone10}
}

Ensuite, nous voulons faire l'objet texte. Nous pouvons utiliser le même objet que dans la leçon précédente, sauf que nous allons utiliser une épaisseur et un offset légèrement différents.

text {
	ttf "timrom.ttf" "POV-RAY 3.0" 0.15, 0
	pigment {BrightGold}
	finish {reflection .25 specular 1}
	translate -3*x
}

Nous nous souvenons que l'objet texte est placé par défaut avec la face directement contre le plan x-y. Si la face de la boîte commence à z=0.1 et que l'épaisseur est à 0.15, la profondeur de l'incrustation sera de 0.05 unités. Nous plaçons une différence autour des deux objets.

difference {
	box {
		<-3.5,-1, 0.1>, <3.5, 1, 1>
		texture {T_Stone10}
	}
	text {
		ttf "timrom.ttf" "POV-RAY 3.0" 0.15, 0
		pigment {BrightGold}
		finish {reflection .25 specular 1}
		translate -3*x
	}
}
Pierre gravée
Pierre gravée

Nous rendons à 200x150 -A. Nous pouvons clairement voir l'incrustation, et c'est d'une belle couleur or. Nous relançons à 640x480 +A0.2 pour voir plus clairement le résultat, mais soyez prévenu, ça prendra un peu de temps.

2.3 Caractéristiques avancées 2.3 Caractéristiques avancées 2.3.2 Les formes basées sur les polygones 2.3.2 Les formes basées sur les polygones