~4 min de rendu sur mon MacBook Pro 2012

Rendering statistics:
Cones : 0
Cubes : 1
Cylinders : 0
Groups : 6230
Lights : 3
Planes : 0
Spheres : 0
Triangles : 23490
Smooth Triangles : 23490
OBJ File : 1
CSG : 0
==================================================
Pixel rendered : 480000
Ray casted : 9588809784
Light Ray casted : 2714514
Reflection ray casted : 684176
Refraction ray casted : 474342
Intersect object created: 4353032
Intersection created : 41699064
Malloc called : 4353032
Realloc called : 5051195
Bounding box missed : 136542307
Min depth attained : 0
Max intersect count : 28
==================================================
~24K triangles, transparence (meme si ce n'est pas evident, l'indice de refraction est assez élevé) et reflection, et plusieurs sources de lumière, ca fait pas mal de rayon a lancer et d'intersection a tester!
il faut en gros 1 rayon par pixel, puis sur le point d'intersection, 1 rayon par lumières sur la scene.
Si on intersectionne avec une surface qui est marqué comme reflective, on lance un autre rayon et on regarde ce sur quoi on tape, lz tout de manière récursive, parceque il faut après testé les lumières pour le point et la reflectivity du matériaux, etc...
Idem pour la refraction, l'angle est different de celui de la reflection (et va dépendre des difference d'indice de refraction entre le milieu avant l'intersection et celui après l'intersection. Et on fait ca aussi de manière recursive, et on continue soit jusqu'a ce que la pile explose (c'est pas bien sur sur certaines scenes

) soit jusqu'a une limite de récursion qu'il est forcement recommandé de gardé petit en tout cas tant qu'on est pas sur le rendu final.
A ca on peux ajouter (ce n'est pas le cas sur cette scene) :
- le super sampling ou on lance plus d'un rayon par pixel pour en faire la moyenne
- La gestion de la distance focale, ou idem on va lancer plusieurs rayons par pixels (mais c'est different du super sampling parce que ca change globalement comment la caméra fonctionne) mais donne un rendu plus réaliste ou une partie de la scene est net, le reste flou, comme avec un vrai appareil photo
- Les lumières de "zones" et non ponctuelles comme utilisé dans la scene la: on ne lance pas qu'un seul rayon par lumière mais un nombre plus que certains dépendant de comment la lumière est configuré (plus il y a de point, et plus les ombres sont lissée, moins il y a de point et plus la transition de l'ombre est brutale)
Si on mixe le tout, ca peu faire un gros plein beaucoup de rayon a tester par pixel d'image, sans compter quand un rayon a la malchance de toucher plusieurs objets ca ralentit aussi pas mal le rendu.
Bref..
C'est lent

(la je travaille sur de potentielles optimisations, mais certains truc qui consomment le plus ne sont pas forcement très évident à optimiser, genre cette operation d'une matrice de 4x4 par un tuple de 4x1:
return Tuple(b.x * FastGet4(0, 0) + b.y * FastGet4(0, 1) + b.z * FastGet4(0, 2) + b.w * FastGet4(0, 3),
b.x * FastGet4(1, 0) + b.y * FastGet4(1, 1) + b.z * FastGet4(1, 2) + b.w * FastGet4(1, 3),
b.x * FastGet4(2, 0) + b.y * FastGet4(2, 1) + b.z * FastGet4(2, 2) + b.w * FastGet4(2, 3),
b.x * FastGet4(3, 0) + b.y * FastGet4(3, 1) + b.z * FastGet4(3, 2) + b.w * FastGet4(3, 3));
difficile de vraiment optmiser un tel code plus que ce que le compilateur peur faire (gcc et clang semblent utiliser des instructions AVX pour ca) et meme la ca reste un de bout de code qui mange le plus de temps au final parce qu'il est appelé pour quasiment chaque intersection rayon/surface qui a actuellement un impact sur la scene vu que dans le cas le plus basique c'est un point de la surface d'un des objets qu'on veux dessiner;
L'operation est utilisé entre la matrice inverse de transformation d'un objet, et le point a la surface du dit objet.
Pour simplifier grandement les mathématiques d'intersection entre rayon et primitives, elle travaillent toutes dans un espace local et c'est le rayon qui est déformé suivant les transformations que la primitive subit dans la scene pour le rendu finale. Mais comme la primitive donne un point dans son espace, il faut convertir le point vers l'espace de la scene, d'ou la multiplication avec la matrice inverse de transformation du dit objet.
Par exemple faire que cette fonction puisse être inline (et deux autres qui sont beaucoup appelé) permet de gagner ~200s cumulé entre tous les coeurs.
C'est assez impressionnant o_O