M2IM – TGSESI

Développement d’un lancer de rayon sous Mitsuba :

I – Mise en place

  • Aller sur www.mitsuba-renderer.org et compiler Mitsuba (en -j4 pour paralléliser).
  • Télécharger une scène par défaut pour les tests (Cornell box par exemple).
    La passer en version 0.5.0, il suffit de l’ouvrir une fois avec Mitsuba GUI (mtsgui).
    La passer en rendu LDR (low dynamic range) :

    <film type="ldrfilm" name="film">
  • Ouvrir la documentation de Mitsuba.

II – Premier pas

  • Suivre le tutorial de prise en main de Mitsuba (pages 203-207) jusqu’à obtenir une carte de profondeur.
    NB : Il faut ajouter l’intégrateur à la compilation en modifiant mitsuba/src/integrators/CMakeLists.txt
  • Afficher la normale en repère monde en chaque sommet vu. Que remarquez-vous ?
    NB  : Attention, les normales sont dans [-1,1]^3 et la couleur dans [0,1]^3.

Rappel :

Pour calculer une image de synthèse de manière physiquement réaliste, il faut évaluer la radiance incidente sur le capteur dans chaque direction. Ce calcul dépend d’une infinité de rayons lumineux se propageants partout dans la scène et il est donc impossible de l’évaluer analytiquement.
On utilise généralement des approches de type Monte Carlo qui intègrent sur le domaine en évaluant des échantillons aléatoires. Dans notre cas, un échantillon est un rayon qui part de la caméra et que l’on va propager dans la scène. Certains rayons rebondiront vers la gauche, d’autres vers la droite. Au fur et à mesure que le nombre d’échantillons augmente, le hasard fait bien les choses et l’évaluation converge vers le résultat théorique, ce que nous allons constater dès maintenant.

Rappel 2 :

La fonction Li calcule la radiance incidente pour une position et une direction données. Celles-ci sont définies par un rayon. Pour définir les « conditions » dans lesquelles Li est appelée, comme par exemple la scène associé, les données connues auparavant, elle prend en paramètre (entrée et sortie) une RadianceQueryRecord, structure qui va stocker différentes informations relatives à l’évaluation de la radiance. C’est dans cette structure que vous trouverez la scène, l’échantillonneur, la profondeur dans le chemin, et autres.

  • Changer le nombre d’échantillons par pixel (samples per pixel) de votre scène à 1. Ce nombre représente le nombre de fois que la fonction Li sera appelée par pixel :
    <integer name="sampleCount" value="1"/>
  • A partir du RadianceQueryRecord, tirer au hasard un échantillon 2D et afficher sa valeur (canaux rouge et vert par exemple).
    Calculer plusieurs fois l’image. Que constatez-vous ?
    Idem pour 4spp, 16spp puis 64spp.

    Un échantillon n’a pas de signification à proprement parlé. Il peut servir à représenter une position 2D (axe des x et des y), une direction (angle zénithale et azimutale), 2 jets de pile ou face, etc. Dans notre cas, nous avons besoin de tirer au hasard des directions, pour savoir vers où rebondit la lumière.

  • A partir de la BSDF, échantillonner une direction de rebond (une direction sortante). Vous aurez besoin de la classe BSDFSamplingRecord. 
    Afficher la probabilité de l’échantillon. Que constatez-vous ?
    Idem pour 4spp, 16spp puis 64spp.
  • Changer la BSDF d’un objet de la scène (small_box par exemple) en conducteur et/ou diélectrique.
    Recalculer l’image. Que constatez-vous ?

    <bsdf type="dielectric"/>
  • Afficher la valeur de la BSDF dans la direction échantillonnée.

III – RayTracing basique

  • Calculer l’éclairage direct :
    • A partir de la scène, échantillonner une position/direction pour le calcul de l’éclairage direct. Vous aurez besoin de la classe DirectSamplingRecord.
    • Calculer la valeur de la BSDF pour le couple de vecteurs incident/sortant.
    • Ajouter au résultat la valeur de l’éclairage direct : radiance émise * BSDF.
    • Limiter le calcul de l’éclairage direct aux BSDFs non purement spéculaires (= contenant une composante diffuse).
  • Calculer l’éclairage indirect :
    • Echantillonner une direction de rebond.
    • Créer un rayon dans la direction échantillonnée.
    • Evaluer la radiance incidente dans la direction de ce rayon, en récursif ou en itératif.
      NB : Attention d’utiliser une RadianceQueryRecord à jour.
    • Ajouter une condition d’arrêt sur la profondeur.
    • Ajouter une condition d’arrêt par roulette russe sur l’intensité du rayon.
  • Prendre en compte l’intersection d’émetteurs, auquel cas la radiance à retourner est la radiance émise par l’émetteur.

IV – PhotonMapping basique

  • Créer un nouvel intégrateur qui contiendra une PhotonMap, un rayon de recherche, un nombre de photons à stocker et une profondeur maximale.
  • Dans la phase de preprocess :
    • Initialiser les variables membres.
    • Initialiser les constantes.
    • Remplir la PhotonMap :
      • Créer un échantillonneur :
        ref<Sampler> sampler = static_cast<Sampler *> (PluginManager::getInstance()->createObject(MTS_CLASS(Sampler), Properties("ldsampler")));
      • Echantillonner un rayon émis par un émetteur.
      • Tracer son chemin :
        • Calculer l’intersection avec la scène.
        • Si l’objet est diffus, stocker le photon dans la carte.
        • Echantillonner une direction de rebond.
        • Continuer le trajet du rayon.
          Conditions d’arrêt : pas d’intersection, profondeur maximale atteinte ou roulette russe sur l’intensité (à partir d’une certaine profondeur).
      • « Construire » la PhotonMap (appel à setScaleFactor et build).
  • Dans la phase d’évaluation de la luminance :
    • Si l’objet intersecté est diffus, estimer l’irradiance de la PhotonMap.
    • Si l’objet intersecté est spéculaire, échantillonner un rebond jusqu’à obtenir une intersection diffuse.
    • Gérer l’intersection d’émetteur.

Résultats :

PM Mitsuba

PM Mitsuba

256spp

PT Mitsuba : 256spp

PM : 10M photons - 2% rayon scène - 1024 photons par requête

PM : 10M photons – 2% rayon scène – 1024 photons par requête – Sans Final Gathering

PM : 10M photons - 2% rayon scène - 1024 photons par requête - Avec Final Gathering

PM : 10M photons – 2% rayon scène – 1024 photons par requête – Avec Final Gathering

256spp - Profondeur de 10 max. - Sans roulette russe

RT : 256spp – Profondeur de 10 max. – Sans roulette russe