Skip to content

Latest commit

 

History

History
128 lines (88 loc) · 5.74 KB

File metadata and controls

128 lines (88 loc) · 5.74 KB

IFT3355 : Infographie TP4 : Lancer de rayons

Nom : Olivier Trudel Matricule : 20134177


Rappel sur le modele d'illumination :

RECAP de Raytracer::Shade : Dans un premier temps, l'illumination directe est faite avec le modele Blinn-Phong (ou Phong, c'est juste le vecteur "halfway" ou reflection pour le terme speculaire, ca ne change pas la structure generale).

Mathematiquement la couleur finale au point d'intersection ressemble a ceci : 
    couleur = emission + terme_ambiant + somme_sur_les_lumieres(terme_diffus + terme_speculaire) + reflect * couleur_reflechie

Dans le code, ca correspond a notre gros for loop et le return a la fin :
    for (auto lightIter = scene.lights.begin(); lightIter != scene.lights.end(); ++lightIter) { 
        ... 
    }
    return material.emission + ambient + diffuse + specular + material.reflect * reflectedLight;

Aussitot qu'on entre dans la boucle, on calcule le facteur d'attenuation et le terme ambiant (pas affecte par les ombres)

SOLUTION du TP pour les ombres durs : Pour la partie evalue dans le TP, on calcule l'ombrage comme suit :

- On lance un shadow ray depuis le point d'intersection vers la position de la lumiere
- On teste les intersections avec tous les objets de la scene 

if (!inShadow) {
    // appliquer Blinn/Phong la formule classique
    diffuse  += ...
    specular += ...
}

Ca nous donne des ombres durs (0 ou 1), pas de penombre.


Partie 2.6 : License Creative : ombres douces avec lumiere surfacique

On passe a une lumiere surfacique (disque autour de la point light) et on prends des points uniformement dans un cercle + evaluer la somme (integrale) avec du Monte-Carlo.

On ajoute 3 variables globales : - USING_SOFT_SHADOW : active/desactive les ombres douces (boolean) - SOFT_SHADOW_SAMPLES : nombre de shadow rays par lumiere - AREA_LIGHT_RADIUS : rayon du disque qui represente la lumiere surfacique

Etape 1 : Base orthonormale La premiere chose qu'on fait, c'est de prendre le vecteur lumiere "L" et construire une base orthonormale locale (u, v, w) autour.

- On pose w = L (direction lumiere)
- On choisit un axe "a" qui n'est pas colineaire a "w" (prend la plus petite composante)
- On construit le plan perpendiculaire : (produit vectorielle)
    u = w x a
    v = w x u

Etape 2 : Integrale de l'illumination et Monte-Carlo Dans un vrai modele de lumiere surfacique la contribution de la lumiere est une integrale surface sur toutes les directions possibles de la lumieres, numeriquement, on approxime par une somme pondere sur un nombre fini de samples "SOFT_SHADOW_SAMPLES". Un estimateur de type Monte-Carlo

L = (1/N) * somme_sur_les_directions( f(sample_i) )

chaque `sample_i` correspond a un point tire aleatoirement sur le disque

Donc le for loop ressemble a ceci :
    
    for (int i = 0; i < SOFT_SHADOW_SAMPLES; ++i) {
        // point aleatoire sur le disque
        // shadow ray vers ce point
        // si bloque -> aucune contribution
        // sinon -> accumuler diffus/speculaire pour ce sample
    }

Et a la fin : 

    diffuse += k_d * I_d * (diffuse_sum  / SOFT_SHADOW_SAMPLES);
    specular += k_s * I_s * (specular_sum / SOFT_SHADOW_SAMPLES);

REMARQUE SUR LE SAMPLING UNIFORME SUR DISQUE : On veut des point uniformes sur le disque de rayon R. Un element d'aire vaut : dA = (2pir) dr

Pusique r est lineaire ici, on obtiens plus de points vers le centre et pas assez sur le bord... 
Donc pas uniforme en aire. 

Ce qu"on veut vraiment, c"est une probabilite proportionnelle au rapport des aires : 
    rand_uniform_01 = (pi*r/pi*R)^2 = (r/R)^2 
    r = R*sqrt(rand_uniform_01)

Et on prends l'angle rand_uniform_01 aussi. 

Apres on convertit en coord. cartesiennes : 
    dx = r * cos(theta);
    dy = r * sin(theta);

Et on utilise note base (u, v) pour prendre la position offset :
    offset = u * dx + v * dy;
    sample_pos = light.position + offset; // nouvelle position sur le disque



REMARQUE FINALE :

Ce n'est pas du path tracing (on ne lance pas plusieurs rayons aleatoire par pixel)

Ca ressemble plus a du "Distributed Raytracing" : https://en.wikipedia.org/wiki/Distributed_ray_tracing

- Plusieurs shadow ray par point d'intersections, tires sur une lumiere surfacique (disque)
- Pour chaque sample, on refait le calcul de Blinn/Phong avec un nouveau point lumineux avec un offset.
- La moyenne des contributions donnes des ombres douces avec p¨¦nombres.