vers l'index général de l'aide

les boîtes d'optimisation ("bounding boxes")

Le description de ce que sont les boîtes d'optimisation nécessite un petit rappel sur le fonctionnement d'un raytracer.

La tâche première d'un raytracer consiste à "balayer" systématiquement le champ de vision de la caméra, pixel par pixel, afin de déterminer la couleur finale de de ces pixels. Pour chaque pixel, un premier rayon (appelé "rayon primaire", qui démarre de la position de la caméra et qui passe par la position du pixel considéré dans le plan de projection), un premier rayon, donc, est tracé dans l'espace, et le programme doit déterminer si ce rayon touche ou non un objet, et si oui, lequel et à quel endroit.

Dans un raytracer très basique (POV-Ray 1.0, par exemple), cela demande de vérifier, pour chaque objet présent, si une intersection se produit avec le rayon. Si on a 1000 objets, cela signifie 1000 tests d'intersection par pixel, même si finalement aucun de ces tests n'aura été concluant. Si on a une image avec deux arbres distants, constitués chacun de 1500 objets, chaque pixel donnera lieu à 3000 tests d'intersection, y compris ceux de l'autre arbre qu'on a aucune chance de toucher, et même si on tombe finalement sur le ciel.

Alors, pour éviter à notre brave raytracer de perdre du temps à lancer des rayons pour rien, on a inventé les boîtes d'optimisation (concernant POV-Ray, elles sont apparues dans la version 2.0). Ce sont des parallélépipèdes rectangles, toujours parallèles au système d'axes, qui "englobent" totalement les objets et groupes d'objets. Ces boîtes sont hiérarchisées, c'est-à-dire qu'elles suivent la structure des objets complexes (union, intersection,...), et qu'une boîte d'optimisation peut contenir un groupe d'objets, qui ont leur propre boîte, qui, à son tour, etc...

Désormais, le rayon primaire ne va plus, dans un premier temps, s'intéresser aux objets eux-mêmes, mais à leur boîte d'optimisation. Si l'intersection avec une de ces boîtes est avérée, alors c'est le contenu de la boîte, et seulement de celle-là, qui sera à son tour analysé. Les autres boîtes peuvent contenir des tas d'objets, le programme n'en a cure, puisqu'il est certain de ne pas risquer d'en rencontrer un seul.

Vous pouvez jeter un coup d'oeil aux statistiques produites après chaque rendu, et vous verrez, pour chaque type d'objet, le nombre de tests d'intersection effectués, et le nombre de tests couronnés de succès.

Ainsi, dans le cas de nos arbres, chaque arbre serait englobé dans une grande boîte, à l'intérieur de laquelle se trouvent tous les composants de l'arbre, eux-mêmes contenu dans leur propre boîte, etc...

L'illustration ci-dessous montre cette hiérarchie des boîtes d'optimisation.

boîtes d'optimisation

min_extent et max_extent

MegaPOV a apporté deux fonctions très intéressantes : min_extent et max_extent, qui permettent de connaître les coordonnées de la boîte d'optimisation d'un objet ou d'un groupe d'objets. Ces fonctions retournent un vecteur, qui correspond au coin de la boîte le plus proche ou le plus éloigné de l'origine.

Elles permettent de faciliter le positionnement dans l'espace d'un objet dont on ne connaît pas vraiment la position (après une rotation,..), ou bien de déceler un éventuel problème d'optimisation pour une CSG complexe.

(Ce sont ces fonctions qui ont permis la réalisation de l'illustration précédente)

syntaxe :

min_extent (Objet)
max_extent (Objet)

exemple :

#declare Boule1 = sphere {<20,10,30>,15 pigment {YellowGreen}}
#declare BoiteOptim = box {
                          min_extent (Boule1),max_extent (Boule1)
                          pigment {SteelBlue filter .9}
                          }
object {Boule1}
object {BoiteOptim }

options de la ligne de commande

Ces options sont détaillées dans la section consacrée aux options de la ligne de commande, mais nous les mettons ici pour rappel.

commandeinidéfautdescription
+MB, -MBBounding=b+enclenche l'optimisation automatique
+MBn, -MBnBounding_Threshold=n25spécifie à partir de combien d'objets il faut enclencher l'optimisation
+UL, -ULLight_Buffer=b+enclenche l'optimisation des lumières
+UV, -UVVista_Buffer=b+enclenche l'utilisation du "vista buffer"
+UR, -URRemove_Bounds=b+enlève les optimisations manuelles des objets quand elles semblent inutiles
+SU, -SUSplit_Unions=b-enlève les optimisations manuelles des unions quand elles semblent inutiles

Le "light buffer" est une optimisation similaire, spécifique aux sources lumineuses. Si vous avez beaucoup de sources lumineuses dans une scène, genre une centaine, vous avez intérêt à désactiver cette option, sinon l'étape de parsing pourrait devenir interminable.

Le "vista buffer" est une optimisation supplémentaire, équivalente aux boîtes d'optimisation, mais dans le plan de l'écran, en 2D, sous forme de rectangles. On peut voir ces rectangles en utilisant l'option +UD.

optimisation manuelle

En principe, le processus d'optimisation est automatisé, mais dans certains cas, il sera utile de définir manuellement l'optimisation d'un objet, à l'aide de la commande bounded_by.

union {
   ...
   ...
   bounded_by {Objet}
}

N'importe quel objet peut être utilisé, mais choisissez de préférence des volumes simples (sphères, boîtes,..) qui sont eux-mêmes bien optimisés par POV-Ray.

N'utilisez pas bounded_by pour modifier la forme d'un objet (en utilisant un conteneur trop petit), ce n'est pas fait pour ça, bounded_by n'a d'influence que dans le plan de l'image rendue.

Voyez la section consacrée aux "modificateurs d'objets" pour plus de détails.

remarques

Si les unions sont très bien optimisées (surtout depuis POV-Ray 3.0), il n'en va pas toujours de même pour les intersection et les différences, où une optimisation manuelle sera la bienvenue. Utilisez les fonctions min_extent et max_extent pour visualiser l'optimisation de ces objets, et ajustez manuellement si nécessaire.

Les objets infinis (plans, quartiques,..) ne sont pas optimisés automatiquement, mais vous pouvez les optimiser manuellement si nécessaire.

rédacteur : Fabien Mosen