MOS8.5 - Centrale Lyon

TP2 - Eclairage ambiant


Maintenant que la base fonctionne pour tout le monde, on va pouvoir commencer à calculer des images.


Partie 1 : matière diffuse

Finissez la partie 5 du tp précédent.

Pensez à transformer les couleurs des pixels en sRGB avant d'enregistrer l'image. vous pouvez utiiiser les fonctions srgb(Color) ou srgb(Image) ou directement write_image_preview(Image) qui réalise la transformation avant d'enregistrer l'image.

pourquoi ? les couleurs affichables, ie celles que l'on utilise pour stocker les couleurs dans les fichiers images comme jpeg ou png ne sont pas linéaires, elles ont subies une transformation par une puissance, la transformation gamma (cf wikipedia). C'était nécessaire pour afficher une image sur un écran cathodique dont la réponse n'est pas linéaire. Et c'est resté...

Voila la différence entre une image correctement convertie en sRGB avant enregistrement et la même non convertie, avec des couleurs dans l'espace RGB linéaire :


couleurs RGB non converties : tout est très sombre...
 

couleurs sRGB après conversion


Partie 2 : éclairage ambiant

On souhaite maintenant simuler l'éclairage de la scène par le ciel, ie une source de lumière définie pour toutes les directions au dessus de l'horizon.


éclairage ambiant : 16 échantillons...

Ecrivez l'estimateur Monte Carlo de l'équation de rendu.
Quelle densité de probabilité / fonction de génération parait utilisable ?

rappel : recettes de génération "GI compendium" P. Dutre, 2003, équations 34, 35, et 36
rappel : les directions sont générées dans un repère arbitraire, Z vers le haut. Comment les transformer vers le repère de la scène 3d ? La meilleure solution connue est proposée par Pixar :  "Building an Orthonormal Basis, Revisited", T. Duff, 2017

rappel : Génération de nombres aléatoires en c++ :
#include <random>

// init
std::random_device hwseed;
std::default_random_engine rng( hwseed() );
std::uniform_real_distribution<float> uniform;

// generation
for(... )
{
    float u1= uniform( rng ); // uniforme entre 0 et 1
    float u2= uniform( rng );
    ...
}   
 

Constatez-vous une différence en utilisant les générateurs 34 et 35 ?
pourquoi ?

A quelle vitesse converge l'estimateur ? Que pourrait on améliorer ?


soleil + ciel avec 256 échantillons...

remarque : ces images (partie 2) sont fausses. que manque-t-il ?


Partie 3 : éclairage par un objet

Que faut-il modifier dans la formulation de l'équation de rendu pour rendre un objet émissif ?
On souhaite placer une autre sphère dans la scène et l'utiliser comme source de lumière.


source + ciel avec 4096 échantillons...


A quelle vitesse converge cette version ? Pourquoi ?

remarque : cette image (partie 3) est fausse. que manque-t-il ? c'est le même défaut pour la partie 2.

Partie 4 : triangles !

Lisez l'article sur les n manières de calculer l'intersection rayon / triangle : "Optimizing Ray-Triangle Intersection via Automated Search", A.Kensler, P.Shirley, 2006
Notamment les sections 2 et 3. Choisissez une solution proposée dans la section 4 et comparez avec votre voisin. Est ce que certaines versions sont plus rapides que d'autres ? ou plus simples ?

indications : n'hésitez à pas définir une structure Triangle adaptée à votre fonction d'intersection. On peut, par exemple, stocker directement certaines arêtes du triangle pour éviter de les re-calculer à chaque test.

indications : en 2d, pour tester l'inclusion d'un point dans un triangle, il suffit de vérifier que le point est du bon coté de chaque arête du triangle. Ce test d'orientation peut s'écrire de plusieurs manières : une solution simple consiste à calculer l'aire signée des 3 triangles formés par le point à tester et chaque arête. Si le signe de l'aire de ces 3 triangles est identique, alors le point testé est à l'intérieur du triangle. En 3d, l'idée est la même, mais on va utiliser le signe du volume de tetraedres pour vérifier que le rayon passe du bon coté de chaque plan formé par une arête du triangle et l'origine du rayon.

pour les curieux : on peut aussi construire une transformation pour simplifier la solution. Le test d'intersection est grandement simplifié en 2d sur un triange rectangle unitaire... cf "Realtime Ray Tracing of Dynamic Scenes on an FPGA Chip", S. Woop, 2004, section 2.1 "Ray triangle intersection".

Partie 5 : nettoyage

Reprenez votre code comme indiqué dans la dernière partie du tp précédent et prévoyez de stocker un ensemble de triangles.