pour enregistrer l'image en png, utilisez write_image( image,
"fichier.png" ); cf
doc
Partie 2 : matières et lumière
si vous avez du mal à organiser votre code,
regardez les codes d'exemples :
- tuto_ray_gltf
: charge une scène gltf, récupère tous les triangles et
calcule toutes les intersections, c'est la version gltf du
code de départ dans "principes
du lancer de rayons"
- tuto_bvh2
: construit un bvh à 2 niveaux, charge un mesh .obj et
crée quelques instances "à la main",
- tuto_bvh2_gltf
: idem mais charge une scène gltf,
- tuto_bvh2_gltf_brdf
: idem + utilitaires pour récupérer les normales, les
coordonnées de textures, les paramètres des brdfs, etc...
étape 1 : normale interpolée de l'intersection
maintenant que l'on sait quel triangle est visible pour chaque
pixel, il faut finir les calculs, mais il faut connaitre la
normale au point d'intersection...
on peut tout simplement calculer la normale géométrique du
triangle :
Vector n= normalize( cross(triangle.e1,
triangle.e2) );
mais on utilise en général la normale interpolée au
point d'intersection... comment faire ? il faut récupérer les
normales des sommets du triangle, les interpoler et transformer
la normale dans le repère de la scène (
rappel : l'objet à
subit une transformation pour etre placé dans le repère de la
scène)
les coordonnées barycentriques pour l'interpolation sont
fournies par l'intersection, cf u et v (et w= 1 - u - v).
quelles sont les normales des sommets du triangle ?
connaissant l'indice du triangle dans une primitive d'un
maillage, il faut récupérer ces informations, cf
GLTFScene
quelle est la transformation qui à placé le triangle dans la
scène ? celle du noeud (ou de l'instance) cf GLTFNode::model
transformez la normale dans le repère de la scène et utilisez la
pour évaluer un modèle diffus / lambert, en utilisant une
direction vers la camera comme direction de la source (cf tp
précédent)
étape 2 : ou sont les sources ?
maintenant que l'on connait la normale, il reste à savoir ou se
trouve la lumière pour calculer la couleur du pixel.
en pre-traitement, on va construire l'ensemble des sources de
lumière de la scène. il y a des sources simples (point,
direction, etc) qui sont stockées directement dans la scène
gltf, mais les objets peuvent également émettre de la lumière...
il suffit de parcourir les triangles des objets de la scène, de
récupérer la matière associée et de conserver les triangles dont
la matière à une emission non nulle. cf la structure
GLTFMaterial
indication : les matières sont associées aux primitives
dans la scène gltf. un triangle connait les indices de GLTFMesh
et de GLTFPrimitives, il ne reste plus qu'à récupérer l'indice
de la matière... cf GLTFPrimitive::material_index
utilisez le centre de chaque triangle émettant de la lumière
comme source de lumière.
étape 3 : ou sont les ombres ?
que faut-il faire pour savoir que le point d'intersection est
éclairé ou à l'ombre d'une source ?
indication : s'il n'y a pas d'intersection entre le point
d'intersection et la source, le point est éclairé...
étape 4 : matières, la suite...
quels sont les paramètres de la matière associée au triangle ?
utilisez au moins la couleur de base de la matiere pour le
modèle diffus.
les détails sont dans la
doc
/ section "c'est quoi le modèle ?" et dans la structure
GLTFMaterial
indication : vous pouvez vous inspirer ? ou re-utiliser
Brdf
du code d'exemple :
tuto_bvh2_gltf_brdf.cpp
pour les curieux : et les textures transparentes ?? par
exemple les feuilles des arbres ou le sillage des bateaux ?
dans l'intersection rayon triangle, il faut verifier que la
texture associee au triangle est opaque avant d'accepter
l'intersection comme valide.
Partie 3 : intégration numérique
exercice 1 : éclairage ambiant
reprenez le cours étape par étape...
exercice 2 : et les pénombres ?
c'est toujours pareil, on commence par écrire / formuler ce que
l'on veut calculer, ensuite on ecrit l'estimateur E(f/p) et il
n'y a plus qu'à trouver la bonne recette de cuisine pour générer
les points / directions, etc. évaluer leur densité et finir le
calcul...
recueil de recettes :
GI
Compendium
pour les curieux, les explications sur les transformations sont
dispo dans le
chapitre
13 de PBRT, notamment les sections
"transforming
between distributions" ainsi que
"the
inversion method".
Annexe : code de départ
si vous avez du mal à démarrer, regardez
tutos/tuto_ray_gltf.cpp
mais essayez de construire votre code sans copier l'intégralité
du code proposé, vous gagnerez du temps au final...