Brett Ridel

About Me

-
Publications
-
Teaching
-
The Revealing Flashlight

TD5 - Photon Mapping

1. Photon Mapping

L'objectif de cette partie est d'implémenter une version simple de l'algorithme de photon mapping qui permettra la visualisation directe (sans final gather) de la photon map pour les surfaces diffuses et utilisera le path tracer pour les autres matériaux.

Commencez par télécharger la correction des TP précédent, incluant le pathtracing : pathtracer.zip.
La structure de données représentant une photon map vous est fournie dans les fichiers kdtree.h et photon.h/.cpp. Vous disposez également du squelette d'un nouvel intégrateur : PhotonMapper. Durant la première passe de l'algorithme, dans la méthode PhotonMapper::preprocess, vous devrez remplir cette photon map en générant des photons depuis toutes les sources lumineuses et en les traçant dans la scène. Durant la seconde passe, dans la méthode PhotonMapper::Li, vous tracerez des chemins depuis la caméra, comme pour le path tracer, sauf que vous utiliserez la photon map à chaque intersection avec une surface diffuse.

1.1. Émission et tracé des photons

Seules les sources étendues émettront des photons. Modifiez les méthodes samplePhoton des classes Scene et AreaLight. La première sélectionnera aléatoirement une source étendue et appellera la seconde. Celle-ci tirera uniformément une position aléatoire sur la source, puis une direction aléatoire sur l'hémisphère orientée selon la normale à la surface (avec Material::squareToCosineHemisphere). Dans le cas particulier d'une source étendue carrée, la puissance du photon est \(Phi = \pi ~ A ~ L_e\) avec \(L_e\) la radiance émise par la source et \(A\) l'aire de la lampe (donc du rectangle).

Chaque photon généré est alors tracé dans la scène, comme une chemin lumineux, c'est-à-dire en échantillonnant récursivement une direction de la BRDF (avec importance sampling), en traçant un rayon dans cette direction, et en utilisant le mécanisme de roulette Russe comme critère d'arrêt (utilisez le ratio entre la puissance du photon avant et après le rebond). La pondération associé au matériau (BRDF et PDF) et à la roulette Russe doit être progressivement multipliée à la puissance du photon. À chaque fois qu'une surface diffuse est intersectée, un photon est enregistré dans la photon map. Une fois le nombre visé de photons \(N\) atteint (m_photonCount), le KdTree est construit en appelant sa méthode build.

1.2. Estimation de la radiance

La seconde passe est presque identique à votre implémentation de PathMats::Li. La seule différence est que, lorsqu'un rayon intersectera une surface diffuse, l'algorithme devra chercher directement dans la photon map les photons à proximité du point d'intersection (dans le rayon m_photonRadius) pour calculer une estimation de la radiance, et stopper la récursion.

Vous utiliserez le noyau de reconstruction de Simpson : $$K(x) = \begin{cases} \frac{3}{\pi} \left(1-||x||^2 \right)^2 & \text{si } x \in [0,1] \\ 0 & \text{sinon} \end{cases} $$ avec \(w\) le rayon de recherche / bande passante du noyau de reconstruction.
La radiance sortante peut alors être estimée par : $$L_{o}(p \leftarrow \omega) \approx \frac{1}{N~w^2} \sum_{i=0}^{N} K\left(\frac{p-p_i}{w}\right) ~ \Phi_i ~ \rho(p,\omega_o,\omega_i)$$

Pour la Cornell Box, vous devriez obtenir :

512 chemins par pixel
(PathTracing)
\(10^6\) photons - 1 chemin par pixel (PhotonMapping) \(10^7\) photons - 25 chemins par pixel (PhotonMapping)

Remerciements

Ce projet est basé sur celui de Pierre Bénard.