Projet lancer de rayon

Introduction

Ce projet à été réalisé dans le cadre de l'UE d'introduction à la synthèse d'images réalistes, où j'ai dû réaliser une application permettant de réaliser un moteur de lancer de rayon en JAVA. Le projet a été réalisé en utilisant l'IDE Eclipse. Pour débuter ce projet j'ai débuté en utilisant comme base le projet de démarrage fourni ainsi que le parser d'objet Alias Wavefront.

Fonctionnement

L'objet principal permettant de définir l'application est l'objet Scene, il prend en paramètre une liste d'objets, une liste de lumières et la caméra. Ces variables permettent d'accéder a toutes les donnés permettant de générer l'image.

Les objets appartiennent à la classe Things qui une interface que tous les objets devront implémenter pour pouvoir être ajouter à la scène. En définissant ça propre méthode permettant de calculer les intersections d'un rayon avec celui-ci. En plus de ça, un objet doit avoir un matériau.

L'application implémente aussi une classe abstraite Material permettant de définir de nouveaux matériaux héritant de la classe Material. Material définit une méthode Shade permettant de calculer la couleur du point d'intersection entre un rayon et l'objet.

Une fois que tous les éléments de la scène sont définis l'objet Raytracer permettra de faire le rendu de la scène et de la stocker dans un objet BufferedImage. Pour cela il suffit d'utiliser la méthode render qui va lancer un rayon à l'aide de la méthode traceRay pour tous les pixels de l'image. Traceray calcul l'intersection entre tous les objets de la scène afin de retourner la couleur de l'intersection la plus proche.

Afin de faciliter le passage entre les différentes fonctionnalités du moteur de lancé de rayon j'ai ajouté un switch afin de pour voir changer tous les objets en fonction de la scène que l'on souhaite afficher. Chaque groupe d'objets présente les différentes fonctionnalités du moteur. Pour cela il suffit juste de modifier la variable choix dans le main par une valeur entre 1 et 5.

Octree

J'ai choisi d'implémenter l'octree comme structure accélératrice pour diminuer le nombre de calculs d'intersections. En effet subdivisant la scène en 8 cubes qui sont eux-même un octree, en faisant appartenir des objets aux feuilles de l'octree. Pour qu'un objet puisse être intersecté il faut que son octree soit intersectée par le rayon et pour que ce même octree soit intersecté il faut que l'octree auquel il appartient soit intersecté et ainsi de suite.

Cette méthode permet d'accélérer grandement le calcul des intersections, cependant il met pas mal de temps à se construire si l'octree est trop gros. J'utilise l'octree afin de stocker les objets OBJ de la scène car ils possèdent un très grand nombre de triangles à l'intérieur. L'octree est un objet Thing afin de pouvoir l'intégrer dans la scène.

CSG

J'ai aussi implémenté un objet CSG qui permet de réaliser des opérations booléennes. J'ai défini 3 opérations booléennes, l'intersection, l'union et la différence. Pour implémenter cette fonction il est nécessaire de rajouter une fonction pour les objets permettant de récupérer toutes les intersections des objets même celle en sortie de l'objet afin de calculer les opérations booléennes.

BRDF

J'ai aussi implémenté une BRDF qui peut être appliquée aux objets. La classe BRDFMaterial permet de définir les la BRDF spéculaire et la BRDF diffus de l'objet ainsi que ces coefficients. J'ai aussi créé deux interfaces BRDFDiffus et BRDFSpeculaire correspondant aux deux BRDF d'un matériau. J'ai implémenté 3 BRDFDiffus et 11 BRDFSpeculaire qui ont chacun différents paramètres pour les contrôler.

J'ai réalisé l'implantation des BRDF en me basant sur la BRDF Explorer de Disney. On peut utiliser leur application afin de visualiser les différentes BRDF et en modifier les paramètres de ces derniers afin de les comparer à des matériaux dont la réflectance à été mesurée au préalable comme la base de donnée MERL qui peut être interprétée par la BRDF Explorer de Disney.

J'ai aussi implémenté un matériau permettant de reproduire un miroir parfait. Pour cela j'ai du lancer des rayons secondaires afin d'appliquer les couleurs du rayon secondaire à la première intersection. Je réalise ce calcul dans la méthode shade du ReflectMaterial.