Lancer de Rayon
et traitement d'image par Tone Mapping

Ray Tracing & Tone Mapping - Abstract

Ray tracing is a computer technique used to generate images. This rendering method is based on a travelling ray of light entering a virtual 3D scene, and giving informations about its interaction in the scene to a set pixel. As a result, images rendered by ray tracing often have a high amount of detail and realism.
Tone Mapping is an image processing technique that uses algorithm to close the gap between computer generated images and what our eyes can see.
By combining these two techniques we hoped to create a virtual retina. However, due to time constraints, and the inherent hurdles met while learning a new programmation language, our expections fell short. As a result, we focused our practical production on the ray tracing, while approaching tone mapping theoretically.

Aperçu

Lancer de Rayon

L'avenir de la 3D

Implémentation

De l'algorithme au C++

Tone Mapping

Concept et utilisations du Tone Mapping

Ressources

Cours, bibliographie, & autres ressources

Lancer de Rayon

Le lancer de rayon est une méthode d'imagerie numérique servant à produire des images en 2D à partir d'un ensemble d'éléments en 3D. Elle permet, au passage, de calculer de nombreuses propriétés de l'image : ombres, reflets, diffraction de la lumière, etc.
C'est une méthode de synthèse d'images offrant des résultats très réalistes, mais demandant un temps de calcul d'autant plus élevé. Pour ces deux raisons, il est très rare que le lancer de rayon soit utilisé dans des calculs de rendu en temps réel (jeux vidéos par exemple). L'utilisation du lancer de rayons reste principalement réservée aux rendus pré-calculés : films d’animation, ou images photo-réalistes.
Nous allons voir, dans cette partie, comment fonctionnent les algorithmes de lancer de rayons.

Principe

Le principe de cette méthode de synthèse d'images est de reproduire le parcours inverse de la lumière : celle-ci commence son trajet à partir d'un récepteur (ici, une caméra), puis traverse une image, qui est une grille de pixels. Un pixel est traversé par un ou plusieurs rayons. La couleur de chaque pixel est alors déterminé en fonction de la façon dont ces rayons interagissent avec la scène.

Sur le schéma présenté ci-dessus, le rayon lancé par la caméra se déplace dans une scène vide. En théorie, cette scène contient un ou plusieurs objets 3D (qui sont représentés mathématiquement), et une ou plusieurs sources de lumière.
Il faut donc vérifier pour chaque objet présent dans la scène s'il va y avoir une intersection avec le rayon. Si le rayon n'entre en collision avec aucun objet, on défini la couleur du pixel correspondant comme la couleur « de fond », définie par défaut. En revanche, si une intersection se produit, de nombreux calculs sont à effectuer : A ce stade, il possible d'effectuer de nouveau un lancer de rayon selon le même principe à partir du rayon réfléchi ou du rayon transmis. L'algorithme du lancer de rayons fonctionne donc de façon récursive. Plus le nombre de récursions effectuées est élevé, plus la couleur du pixel sera réaliste, car il prendra en compte un maximum de sources de lumière passives ainsi que les reflets.

La BRDF

A chaque objet présent dans la scène est associée une BRDF. Une BRDF, ou Bidirectional Reflectance Distribution Function, est une fonction mathématique qui prend en paramètre différentes caractéristiques du rayon incident. Ces fonctions retournent une valeur : la luminance, qui correspond à l'intensité lumineuse du rayon réfléchi. De cette fonction dépendra l'aspect de l'objet. Voici quelques BRDF couramment utilisées :

L'illustration ci-dessous présente une illustration du rendu des ces deux BRDF, ainsi que la courbe d'évolution de la luminance en fonction de l'angle du rayon réfléchi.

Implémentation

Afin de mieux comprendre les mécanismes utilisés lors du lancer de rayons, notre projet était d'implémenter un lanceur de rayons basique en C++. L'objectif d'une telle démarche est, d'une part, de bien comprendre comment fonctionne un lanceur de rayons. D'autre part, cela permet de découvrir un langage de programmation qui nous était jusqu'alors inconnu.

Le choix du C++

Le projet a été développé en C++. Ce choix de langage est justifié par la grande vélocité de ce langage. Cela est indispensable pour un tel projet, étant donné le nombre de calcul extrêmement important qui seront réalisés. En effet, pour une image de 800*600 pixels, le nombre de pixels est de 480 000. Pour chaque de ces pixels, il faut effectuer une grande variété d'opérations : lancer un rayon, calculer les points d'intersections, calculer la normale à la surface intersectée, produire un rayon réfléchi, etc. Une grande vélocité est donc primordiale, et malgré l'existence de structures accélératrices.

A titre personnel, le C++ était un langage totalement inconnu. C'est un langage très utilisé dans de nombreux domaines (informatique embarquée, création de jeux vidéos), il nous semblait donc intéressant de profiter de cette occasion pour découvrir ce langage.

Lanceur de Rayon en Orienté Objet

Nous avons programmé notre lanceur de rayon en suivant le paradigme de programmation Orientée Objet (POO). Même basique, un tel programme nécessite une vaste variété d'objets différents. Il est donc important de bien définir ces différents objets qui le composeront.
Voici une liste des différents objets compris dans le lanceur de rayon:

Les objets mathématiques Cvertex et Cvector servent à définir les points et les vecteurs. Ceux-ci intègrent un ensemble de fonctions membres servant à calculer, par exemple, le produit scalaire, les opérateurs d'addition ou de soustraction, etc.

Diagramme UML

Méthodes accélératrices

Afin d'améliorer le temps de calcul de l'image par lancer de rayon, il est possible de faire appel à différentes méthodes accélératrices. La principale méthode utilisée est celle des "bounding box". Une bounding box, ou boîte englobante, se présente sous la forme d'un rectangle invisible, encadrant un objet ou un groupe d'objets 3D et facilitant le calcul des intersections des dits objets. En effet, si un rayon atteint une bouding box, le calcul d'intersection sera effectué pour les objets contenus par cette bounding box. Dans le cas contraire, ces calculs seront ignorés, gagnant ainsi le temps normalement nécessaire pour les effectuer.
Dans le cas d'une scène contenant de nombreux objets, le temps et les ressources ainsi économisés sont non négligeables.

Enrichissement

L'enrichissement d'un lanceur de rayon peut passer par plusieurs voies. L'ajout d'objets 3D est la plus évidente, en plus de la sphère que nous utilisons comme base nous pourrions ainsi programmé les fonctions d'intersections pour des plans, cube, et autres polygones.
Il pourrait également être intéressant de s'intéresser aux formes 2D. C'est-à-dire aux facettes, assimilables à des plans de taille réduite assemblés entre eux pour former un objet 3D plus complexe que les volumes géométriques classiques. Néanmoins cette addition devrait s'accompagner d'un interpréteur autorisant ainsi l'importation dans le lanceur de rayon de modèles 3D de formats différents, en provenance de logiciel de création d'objet (ex: Blender).
Un troisième axe d'enrichissement du programme est celui des caméras. En effet, en créant différentes caméras aux propriétés variées, nous obtiendrions autant d'images différentes. Les caméras les plus intéressantes à nos yeux seraient cependant celles de type "fish eye" et "pin hole", car elles permettraient d'aborder différents aspects de la vision avant même d'implémenter un algorithme de tone mapping.
Mais les possibilités de programmation d'un lanceur de rayon ne se limite pas à des ajouts d'objets ou de caméras, l'intégration d'équations mathématiques est également possible. Ces équations peuvent remplir différentes fonctions mais celle qui a retenu notre attention et que nous esperions implémenter se nomme "bump mapping". Le bump mapping est une technique visant à perturber les normales d'une surface, ainsi, lors de l'interaction d'un rayon lumineux avec la dite surface, le rendu ne sera pas celui d'une surface lisse, mais bel et bien d'une surface accidentée, ou en relief. L'intérêt d'une telle technique est qu'elle ne modifie pas la forme d'origine de l'objet, mais uniquement la lumière renvoyée par celui-ci, autorisant ainsi des rendus détaillés à moindre coût en calcul. Cet avantage peut également être considéré comme une limite lorsque l'on souhaite travailler sur les ombres d'un objet modifié de la sorte, en effet, celles-ci seront semblables aux ombres projetées par l'objet avant l'application du bump mapping.
Le bump mapping va généralement de paire avec un modèle d'interprétation de la lumière (ex: Phong). De fait, il serait intéressant d'implémenter des modèles supplémentaires tels que ceux de Schlick, ou Lambert.

Tone Mapping et système visuel de l'être humain

Le Tone Mapping est une dénomination regroupement l'ensemble des équations mathématiques permettant une amélioration d'images afin que celles-ci correspondent aux attentes d'un observateur. Cette méthode repose sur l'idée qu'il est possible de compléter les tons manquants d'une image de façon artificielle. En effet, l'immense majorité des appareils photo et caméras actuels ne capturent pour un pixel qu'une composante chromatique, mais, dans la réalités, le contraste local est bien plus important et plus d'une composante chromatique est impliquée.
Une équation de Tone Mapping peut être globale ou locale. Dans le cas d'une équation globale, la position du pixel n'est pas prise en compte en tant que facteur. Dans l'idée de simuler une rétine en combinant le lancer de rayon et le tone mapping, nous espérions pouvoir implémenter l'algorithme déveloper par Meylan & al.1.

Image tirée de l'article de Meylan & al. On voit ici la différence entre une équation de Tone Mapping appliquée à l'image dans son entièreté et l'équation de Tone Mapping devisé par Meylan & al. Cette dernière est dérivée d'un modèle rétinien et améliore les contrastes sans pour autant être affecté par les problèmes communs aux algorithmes locaux tel que la présence de halos.

Remerciements

Nous tenons à remercier notre tuteur de TER, Monsieur Philippe Blasi pour le temps qu'il nous a consacré et pour son aide précieuse.

Ressources

Répartition des tâches

La répartition des tâches a été effectuée à part égale au sein du binôme. Ainsi nous avons tous deux participer à la programmation du lanceur de rayon mais également à la conception de ce site à l'aide d'un template CSS.

Cours
  • T.Grenier - Introduction aux Méthodes Orientées Objets
  • P.Pesneau - Programmation Orientée Objet - C++
  • P.Blasi - Fondements et Algorithmes de la synthèse d'image réaliste
  • D.Meneveaux - Cours de synthèse d'images
Bibliographie
  • E.Angel - Interactive computer graphics : a top-down approach using OpenGL
  • Meylan & al. - Model of retinal local adaptation for the tone mapping of color filter array images
    (Retour à la référence)
  • S.Boulos - Notes on efficient ray tracing
Autres ressources
  • The Belgian VFX Guy - Link
  • Template css - Strata
  • Documentation C++ - Link
  • Exemple Tone Mapping - Link
  • Exemple Ray Tracing - Link