Lancer de rayons - Extensions
Aller plus loin
Pour améliorer votre raytracer, voici une liste (non-exhaustive) d'extensions possibles classées par catégories. Un niveau indicatif de difficulté est indiqué.Pensez encore une fois à aller consulter les diapositives du cours du MIT qui couvrent certains de ces sujets.
Si vous créez vos propres scènes et voulez placer la caméra précisément, utilisez le viewer pour placer la caméra où vous le souhaitez puis quittez avec
Escape
. Le fichier
.qglviewer.xml
contient alors le Frame
de la
caméra.
Nouveaux objets
Contrairement à la sphère, ces nouveaux objets sont sensibles à leur orientation (définie par leurframe()
). Calculer l'intersection d'un rayon avec (par exemple) un cylindre
arbitrairement positionné et orienté est difficile. Il est bien plus simple de faire l'inverse :
placer le rayon dans le repère du cylindre (qui est alors défini comme aligné avec un axe) pour y
faire les calculs. Le résultat (Hit
) n'aura ensuite qu'à être re-transformé dans le
repère monde.
La transformation du
Frame
étant une transformation rigide, les distances ne sont pas
modifiées et la comparaison du temps d'impact reste valable. Les méthodes de la classe
qglviewer::Frame
permettent de très facilemement convertir d'un repère à un autre.
Vous ajouterez donc une méthode qui convertit un
Ray
du repère monde au repère de
l'objet, ainsi que la méthode inverse dans Hit
pour remettre le résultat dans le repère
monde.
Plans - Niveau 1
La structuration claire de votre programme doit vous permettre d'ajouter la gestion de l'objet "plan" (infini) en plus des sphères en peu de temps. On décide qu'un plan passe par l'origine et a pour normale l'axez
, définis dans le Frame
associé (hérité de
Object
).
Si vous voulez créer vos propres scènes, la méthode
Quaternion(Vec(0,0,1),
votreDirection)
vous permet de trouver le Quaternion
associé à une normale
donnée.
Le plan étant infini, son
boundingRadius
sera empirique. Cette valeur ne sert de toutes
façons qu'au viewer OpenGL pour ne pas clipper des parties de la scène.
Les fichiers petanque.scn, deuxPlans.scn et rayure.png vous permettront de reproduire ces images.
Cette dernière contient simplement trois sphères et deux plans orthogonaux. La scène y semble pourtant dupliquée 3 fois du fait des réflexions.
Triangles - Niveau 1
Le triangle est un peu plus complexe dans sa méthodeintersect
, mais reste simple à
implémenter. Les deux faces d'un triangle jouent-elles le même rôle ? À vous de choisir.
Surfaces triangulées - Niveau 1
Le plus difficile est de bien définir le format de données. Il suffit ensuite d'utiliser les méthodes du triangle. La palette de scène s'en trouve par contre bien élargie, au prix d'un temps de calcul croissant.Cylindres - Niveau 2
Pour les cylindres, on pourra, en plus de la hauteur, donner deux rayons différents aux deux bases du cylindre pour genérer une plus grande diversité. Les calculs d'intersection sont un peu plus complexes. Indice pourdraw()
: gluCylinder
.
Surfaces splines - Niveau 3
La difficulté est ici de calculer l'intersection de la surface avec le rayon. Il faudra également bien choisir la manière de définir la surface. La mise au point de l'algorithme grâce à l'interface OpenGL peut s'avérer utile.Surfaces de subdivision - Niveau 3
Le problème est similaire aux surfaces splines. Il faut de plus bien assimiler le principe de ces surfaces. On se limitera à un schéma de subdivision simple.Constructive Solid Geometry - Niveau 3
Pour pouvoir faire de la CSG, il faut conserver toutes les intersections qui ont eu lieu le long d'un rayon, afin de pouvoir choisir celle qui sera conservée. Le cours du MIT donne quelques pistes.Phénomènes optiques
Perturbation de normales - Niveau 1
Il est très facile de rendre les objets moins lisse en perturbant très légèrement leur normale lors du calcul. On peut chercher à définir le(s) paramètre(s) adéquat(s) permettant de facilement modifier le matériau pour celà.Une autre méthode, très souvent employée consiste à fournir la modification de normale sous forme d'une texture de bump map (x,y et z étant codés dans R, G et B) que l'on accède via les coordonnées
u,v
précédemment définies (voir ce site pour un exemple sur les planètes).
Cartes d'environnement - Niveau 1
Lorsqu'un rayon n'intersecte aucun objet, au lieu de lui donner la couleur de fond de la scène, on va chercher dans une image représentant l'environnement sa couleur. Cette image peut être une carte cubique (6 textures sur les faces d'un cube) ou une (ou deux) carte sphérique (photo de la scène reflétée dans une sphère métallique). Il suffit de calculer correctement les coordonnées du pixel correspondant au rayon.Réflection de Fresnel - Niveau 2
LareflectiveColor
d'un matériau est en fait fonction de l'angle sous lequel est vu la
surface. Elle augmente aux angles rasants. C'est ce qui fait que le lino du fond d'un couloir semble
réfléchissant alors qu'il ne l'est pas quand on le regarde sous nos pieds.
La formule exacte et son approximation avec un cosinus puissance 5 sont dans le cours du MIT.
Lampes atténuées - Niveau 2
L'intensité des lampes utilisées ne dépend pas de la distance à la source. Elle devrait en fait varier comme l'inverse de cette distance au carré. Ajoutez trois paramètresa,b
et
c
à vos sources, qui viendront diminuer l'intensité de la source selon I = a -
b/d - c/(d^2)
(où d
est la distance à la source).
Une autre extension consite à gérer les lampes spot (voir la documentation de
glLight
).
Ces lampes directionnelles ont une intensité qui décroit lorsqu'on s'éloigne de la direction
principale, et qui finit par s'annuler.
Réfraction - Niveau 3
La réfraction du rayon permet de simuler des objets transparents. Il faut définir un coefficient de réfraction du matériau, et se souvenir de si le rayon est à l'intérieur au non, pour appliquer la réfraction inverse à la sortie du matériau.Cette extension est relativement complexe et risque de révéler des bugs dans le reste de votre code. On se réferera encore une fois au cours du MIT où le principe et quelques détails d'implémentation sont donnés.
Dernière extension : ne plus considérer les objets transparents comme totalement opaques et projetant des ombres. Les voir davantage comme des filtres qui colorent la lumière (en toute première approximation). A discuter lors de la soutenance.
Qualité de rendu
Prévisualisation - Niveau 1
Affichez sur le plan semi-transparent de la caméra une image (plus ou moins grossière) de la scène calculée par lancer de rayon.Affichage OpenGL - Niveau 2
Le but de cette extension n'est pas d'améliorer votre lancer de rayon, mais le prévisualiseur OpenGL ! On pourra utiliser les pixels shaders pour implémenter un phong par pixel, et les shadow map pour simuler les ombres.Ne vous lancez dans cette extension que si vous maîtrisez suffisement OpenGL et qu'elle vous intéresse, par exemple pour votre stage. Attention, les cartes graphiques des machines de l'ARV ne supportent pas le pixel shader, et il vous faut donc une machine personnelle adaptée.
On réfléchira aux avantages et aux limitations d'un rendu hardware par rapport au lancer de rayon.
Anti-aliassage - Niveau 2
On peut améliorer les résultats en pondérant les couleurs des rayons correspondant à un pixel par un noyau gaussien (centré sur le centre du pixel), plutôt qu'en moyennant simplement les couleurs. Il est plus souple de coder une classeFilter
qui donnera les poids ainsi que les
décalages (par rapport au centre du pixel) associés à chaque rayon. Cette classe pourra également
sauvegarder une image en niveaux de gris du filtre utilisé. Voici les résultats obtenus sur des
grilles nxn, pour n=1, 2, 3 et 4 (images grossies 3 fois):
On commentera ces résultats lors de la soutenance, en présentant une discussion sur les filtres utilisés (pourquoi une gaussienne, pourquoi un support plus grand que le pixel ?).
Ombres douces - Niveau 3
Une source étendue génère des ombres douces beaucoup plus réalistes. Il ne suffit plus de savoir si un point est dans l'ombre ou pas, mais quel pourcentage de la source est visible depuis ce point. Cela peut s'approximer en échantillonnant la surface de la source et en comptant quel pourcentage de rayons voit la source.La méthode peut rapidement gréver votre temps de rendu, et on réfléchira à des heuristiques pour l'accélérer (même si on ne les code pas).
Optimisations
Grille - Niveau 3
Pour accélérer les calculs d'intersection, en particulier avec une surface triangulée, on peut plonger la scène dans une grille régulière (éventuellement hiérarchique), dont chaque cellule connait les objets dont la surface les intersecte.Il y a deux difficultés : associer les objets aux différentes cellules et parcourir cette grille avec unrayon. Cette optimisation est largement détaillée dans l'assignement 5 du TP du MIT.