TP1 (Fondations d`un lanceur de rayons) Mise en contexte

publicité
Université de Sherbrooke
Département d’informatique
Automne 2012
IMN528 – Synthèse d’images
TP1 (Fondations d’un lanceur de rayons)
Mise en contexte
Le rendu par lancer de rayon est un algorithme de rendu simple et populaire permettant d’atteindre un
niveau élevé de réalisme dans l’affichage de scènes virtuelles. Le lancer de rayon repose sur les lois de la
physique optique et simule le parcours inverse de la lumière lors de la composition d’une image. De plus,
contrairement aux méthodes de rendu polygonales, le lancer de rayon ne se limite pas au rendu de triangles
et utilise plutôt des primitives mathématiques pour définir le contenu d’un scène.
Le lancer de rayon reposant sur la simulation de la lumière et des primitives géométriques, il devient
primordial de savoir calculer l’intersection entre ceux-ci afin de déterminer quand et où un rayon de lumière
touche à une surface. Ce travail pratique vise à vous familiariser avec les bases d’un lanceur de rayons, soit
la manipulation de rayons et le calcul d’intersections.
Objectifs académiques
1. Savoir manipuler des droites mathématiques bornées dans un contexte de lancer de rayon.
2. Savoir manipuler des matrices de transformation et de projection pour la création d’images par lancer
de rayon.
3. Intégrer des algorithmes de calcul d’intersections entre des primitives géométriques diverses et un rayon.
4. Savoir manipuler des primitives géométriques dans un contexte de lancer de rayon.
5. Savoir implémenter efficacement des processus ou algorithmes mathématiques complexes.
Description du travail
Dans ce travail pratique, vous devrez mettre en place les éléments suivants :
• La boucle de lancer de rayon, qui consiste à utiliser les matrices de transformation (modèle-vue et
projection) pour créer votre image finale.
• Le parcours d’une scène contenant des primitives géométriques, afin de pouvoir tester les intersections
entre un rayon et les objets de la scène.
• Le calcul des intersections et de la normale à l’intersection entre un rayon et les primitives géométriques
suivantes : une sphère, un cube, un plan fini, un cylindre et un cône. Le calcul d’intersections
doit tenir compte des transformations géométriques appliquées à ces primitives. Le calcul d’intersection
pour le tore peut aussi être implémenté pour avoir des points bonus.
• Le rendu OpenGL des primitives pour lesquelles le calcul d’intersections doit être effectué.
1
Dans le cadre de ce travail, un moteur de lancer de rayon partiellement programmé vous sera fourni.
Toutes les composantes périphériques du moteur qui ne sont pas directement reliées au lancer de rayon ont
déjà été programmées pour vous. Votre tâche, tout au long de la session, consistera à implémenter certaines
méthodes ou fonctions laissées vides touchant au processus du lancer de rayon et correspondant à la matière
vue en classe.
Dans ce premier travail, vous devrez vous concentrer sur le lancer des rayons à partir de la caméra vers
la scène et le calcul des intersections avec la géométrie. À la fin du premier travail, vous verrez apparaı̂tre la
géométrie avec une couleur unie, sans effet d’éclairage. Lors du deuxième travail pratique, vous construirez
sur le code du premier TP afin d’ajouter des effets d’illuminations avancés.
Globalement, le moteur de lancer de rayon possède une fenêtre de prévisualisation OpenGL où vous
pouvez contrôler la caméra à l’aide de la souris et prévisualiser votre scène. Lorsque vous êtes satisfait de
l’angle de vue, vous pouvez appuyer sur la touche r de votre clavier afin de lancer le rendu de votre scène.
À ce moment, une deuxième fenêtre apparaı̂tra et le rendu par lancer de rayons s’y affichera. Bien entendu,
vous n’avez pas encore programmé le lancer de rayon ni l’affichage des primitives sous OpenGL. Vous ne
verrez donc probablement qu’une scène vide !
Trois classes distinctes forment la base du système, et la majorité de votre travail sera effectué dans ces
classes : la classe Scene, la classe Camera et les classes qui héritent de Object.
Classe Object : La classe Object est la classe parente de tous les objets affichables contenus dans la
scène. C’est donc dire que les classes dont vous devez implémenter l’intersection, soit Sphere, Cylinder,
Plane et Cone dérivent de cette dernière. (La classe Torus peut aussi optionnellement être implémentée
pour avoir des points en bonus.) Lors du rendu de la scène dans le prévisualisateur OpenGL, la méthode
virtuelle glRender() est appelée. Vous devrez implémenter cette méthode en utilisant les commandes OpenGL
vues dans le cours d’infographie (IMN428). Lors du rendu par lancer de rayons, la méthode intersects()
est appelée pour vérifier si un rayon intersecte avec l’objet géométrique. Cette méthode doit retourner un
booléen indiquant si une intersection s’est produite. Si c’est le cas, vous devrez aussi assigner des valeurs aux
paramètres interPos (position du point d’intersection), normal (normale de l’objet au point d’intersection),
distance (distance entre l’origine du rayon et le point d’intersection) et hitColor (couleur de l’objet au
point d’intersection). La couleur est obtenue avec la méthode getColor(). Notez que la classe Cube est déjà
implémentée, tant pour le rendu OpenGL que le calcul d’intersections. Vous pouvez donc vous en inspirer
pour l’implémentation des autres classes. La classe Object et les classes en héritant sont situées dans le dossier
Raytracer/source/renderables.
Classe Camera : La classe caméra est située dans le dossier Raytracer/source/scene de votre travail
pratique. Cette classe sert à définir les caractéristique de la caméra utilisée pour le rendu OpenGL et le
rendu par lancer de rayon. La mécanique de caméra sous OpenGL étant déjà programmée, vous n’aurez
qu’à vous concentrer sur le lancer de rayon. Lorsque le logiciel demande à la caméra de rendre la scène
en utilisant le lancer de rayon, la méthode renderRayTracedImage() est appelée. Dans cette méthode, vous
devrez implémenter une boucle lançant des rayons à travers la scène de manière à remplir chaque pixel
de l’image à rendre. Les dimensions de l’image à rendre sont données par les paramètres de la méthode.
Pour lancer les rayons dans votre scène, vous devrez construire les matrices de transformation modèlevue et projection de votre caméra. Ces dernières peuvent être respectivement construites en utilisant les
fonctions cameraModelViewMatrix et perspectiveProjectionMatrix fournies dans le fichier vision helpers.h
situé dans le dossier Raytracer/source/base. Ces fonctions requièrent les caractéristiques de votre caméra,
disponibles via les méthodes prévues à cet effet dans la classe Camera. Lorsque votre rayon a correctement
été initialisé, vous pourrez le soumettre à votre scène (paramètre scene) en utilisant les méthodes prévues à
cet effet dans la classe Scene. (Plus de détail sur ces méthodes dans le paragraphe qui suit.) Les méthodes en
question de la classe Scene retourneront une couleur, que vous devrez écrire dans l’image de sortie du lanceur
de rayon. Des informations sur l’écriture des couleurs dans un pixel de l’image de sorties sont fournies dans
l’implémentation de la méthode renderRayTracedImage.
2
Classe Scene : La classe scène est la classe contenant tous les objets de type Object qui constituent la
scène. Cette classe possède deux méthodes importantes à implémenter, soit la méthode performRaySceneSearch() et la méthode performHitTestSearch(). La première, performRaySceneSearch() reçoit un rayon en
paramètre et doit itérer à travers tous les objets de la scène afin de vérifier si un de ceux-ci intersecte avec
le rayon. Faites attention cependant, plusieurs objets peuvent intersecter avec un même rayon, il faut donc
conserver le point d’intersection le plus près. Lorsque le point d’intersection a été trouvé, la fonction doit
retourner la couleur de l’objet intersecté. Dans les travaux à venir, vous devrez effectuer un calcul d’illumination afin de déterminer la couleur. Pour ce travail, vous n’avez qu’à retourner la couleur contenue dans le
paramètre hitColor retourné par la méthode intersects() des objets Objects. La méthodes performHitTestSearch() doit aussi être implémentée en prévision des travaux futurs. Elle ne sera cependant pas utilisée
directement dans le travail courant. Globalement, cette méthode reçoit un rayon et un seuil de longueur.
Elle doit simplement retourner true si un objet intersecte le rayon à une distance inférieure au seuil, et false
autrement. La classe Scene est située dans le dossier Raytracer/source/scene.
Outre les trois classes importantes, une séries de classes mathématiques utiles vous est fournie dans
le dossier Raytracer/source/base. Ce dossier contient tous les outils mathématiques nécessaires à la
réalisation d’un rendu par lancer de rayon (Matrices de transformation, couleur, vecteur, rayon, etc.). Il est
donc fortement recommandé d’utiliser ces dernières pour faciliter la réalisation du travail pratique.
Finalement, notez que vous pouvez sauvegarder vos images rendues par lancer de rayons en cliquant sur
la fenêtre du rendu puis en appuyant sur la touche s de votre clavier. Une image sera sauvegardée dans votre
répertoire de travail sous le nom rendered image.bmp.
Définition de la scène 3D
Le moteur de lancer de rayon possède un système de définition de scène 3D. Il est donc possible de charger
différentes scènes 3D pour varier vos tests. La scène 3D à charger est spécifiée dans le fichier main.cpp à la
ligne 15. Vous pouvez y inscrire un nom de scène différent pour charger une autre scène (les scènes disponibles
sont situées dans le répertoire RayTracer/resources du TP.)
Si vous êtes curieux, vous pouvez aussi modifier les scènes affichées en éditant directement les fichiers de
scène. Une liste des commandes disponibles et de leurs paramètres est disponible dans le fichier scene reader const.h
situé dans le dossier Raytracer/source/utilities. Prenez cependant note que certaines fonctionnalités des
scènes (comme l’éclairage par exemple) ont été désactivées pour le premier travail pratique. Certaines commandes n’auront donc pas d’effet sur la scène.
Stratégie d’implémentation
Pour faciliter l’implémentation, il est recommandé d’utiliser la scène de test Scene Cubes.sce pour
commencer. Cette scène ne contient que des cubes, vous pourrez donc dès le début visualiser cette dernière
dans la fenêtre OpenGL puisque l’implémentation de la classe Cube est déjà fournie.
À partir de cette scène, vous pourrez implémenter les méthodes des classes Camera et Scene en ayant
l’assurance qu’il n’y a pas d’erreur dans le calcul d’intersection ou les transformations géométriques des
cubes. Si ces méthodes sont bien implémentées, l’image résultante devrait être pratiquement identique à
l’image de la fenêtre OpenGL.
Une fois l’implémentation des méthodes manquantes dans Camera et Scene complétée, vous pourrez
poursuivre avec l’implémentation des autres primitives. Des scènes de test pour chaque types de primitives
sont prévues dans le dossier RayTracer/resources.
Finalement, puisque l’éclairage n’a pas encore été implémenté, il ne sera pas possible de directement
valider les normales. Une façon de vérifier si votre normale est dans la bonne direction est de prendre les
trois composantes (X, Y, Z) normalisées de la normale et de les écrire comme étant les trois composantes
de la couleur à afficher lors du rendu par tracé de rayon (R, G, B). L’image résultante sera une image où
3
chaque couleur correspond à la normale, une couleur rouge serait donc une normale ayant la valeur (1, 0, 0).
Générer une image des normales est une pratique courante en infographie et l’image résultante s’appelle une
carte de normales (normal map). Vous pourrez ainsi temporairement visualiser vos normales et les valider.
Assurez-vous de remettre les couleurs initiales avant de remettre votre TP !.
Bonus
Pour ce travail pratique, il est possible d’obtenir jusqu’à 3 (sur 15) points en bonus. Pour obtenir le bonus,
vous devrez implémenter un test d’intersections et calculer la normale pour un tore. Pour ce faire, vous devrez
compléter l’implémentation de la classe Torus, située dans le fichier torus.h/.cpp que vous trouverez avec
les autres primitives géométriques. Une scène de test Scene Bonus Torus.sce est aussi fournie pour tester
votre tore.
Barème de correction
Ce travail est noté sur 15 points et offre la possibilité d’obtenir 3 points en bonus. Les points sont répartis
selon les pourcentages suivant :
Lancer de rayons dans la scène
Exploration de la scène pour les intersections
Calcul des intersections et des normales
Qualité de la programmation
25%
10%
50%
15%
La qualité de la programmation est déterminée notamment par la qualité de sa présentation (indentation, noms de variable, commentaires, clarté), et par la qualité algorithmique de votre code (complexité
algorithmique, efficacité de l’implémentation).
La validité des normale sera vérifiée à l’aide de cartes de normales tel qu’expliqué précédemment.
Lors de la correction, votre programme sera validé à l’aide de scènes ne figurant pas dans la batterie de
scènes fournie avec le travail pratique. La performance de votre implémentation n’est pas évaluée directement
mais un programme anormalement lent sera pénalisé.
Modalités de remise
Seulement les fichiers .h et .cpp des classes Scene, Camera, Cone, Cube, Cylinder, Plane et Torus doivent
être remis. Les autres fichiers ne seront pas considérés lors de la correction et celle-ci sera effectuée avec la
version originale des autres fichiers. Les modifier pourrait donc empêcher votre programme de compiler.
Vous avez jusqu’au 28 septembre à minuit, pour remettre ce travail. La remise peut se faire par turnin
ou par courriel. Dans tous les cas, assurez-vous de vous prendre un peu à l’avance, afin de ne pas avoir de
surprise désagréable au moment de soumettre. N’oubliez pas d’inscrire votre nom et celui de vos coéquipiers
dans la remise pour éviter toute confusion. Le travail doit s’effectuer en équipe de deux ou trois
étudiants.
Advenant un retard, une pénalité de 25% par jour sera appliquée sur la note du travail pratique. Ce
travail compte pour 15% de la note finale avec un bonus optionnel valant 3%. Un travail ne compilant pas
sur les ordinateur des laboratoires se voit automatiquement donné la note 0.
4
Annexe : un peu d’encouragement !
Les rendus pour ce travail seront évidemment peu spectaculaires. Ils forment cependant la base pour
votre prochain travail pratique, qui fournira des résultats beaucoup plus intéressants !
5
Téléchargement