Ray tracing — 05 — Réflexion et réfraction

Comment le ray tracing rend le verre et les miroirs : rayons récursifs, loi de Snell-Descartes pour la réfraction, équations de Fresnel pour doser le mélange, et la limite de récursion.

05 — Réflexion et réfraction

Ce que tu vas apprendre

  • Pourquoi un reflet n'est qu'un rayon de plus, lancé en récursif
  • La différence entre réflexion et réfraction, et la loi de Snell-Descartes
  • Comment Fresnel dose le mélange des deux selon l'angle
  • Pourquoi il faut une limite de récursion, sinon ça boucle à l'infini

Prérequis


L'algorithme d'Appel donne des objets mats, éclairés ou dans l'ombre. C'est Turner Whitted qui, en 1980, lui ajoute ce qui en fait un outil spectaculaire : les reflets et la transparence. Son idée tient en un mot — la récursivité. Un reflet, ce n'est pas un effet spécial : c'est l'algorithme qui s'appelle lui-même.

Un reflet, c'est un rayon qui repart

Quand un rayon primaire touche une bille de verre, on ne s'arrête pas au point d'impact. On regarde ce que ce point « voit » à son tour. Pour un miroir ou une surface réfléchissante, on calcule la direction réfléchie à partir de deux choses : la direction du rayon entrant et la normale à la surface (la perpendiculaire au point d'impact). On lance un nouveau rayon dans cette direction réfléchie, et on relance dessus tout l'algorithme : il touche un autre objet, on calcule la couleur de cet objet (avec son propre rayon d'ombre), et cette couleur devient la couleur du reflet sur la bille.

La loi de la réflexion est simple : l'angle d'incidence égale l'angle de réflexion, de part et d'autre de la normale. C'est le rebond d'une boule de billard sur une bande.

        N (normale)
        |
  \     |     /
   \    |    /      angle entrant = angle réfléchi
    \   |   /
  ────●───────  surface
  rayon  rayon
  entrant réfléchi

La réfraction : la lumière qui se plie

Pour un objet transparent — verre, eau —, une partie de la lumière ne rebondit pas : elle traverse en se pliant. C'est la réfraction, et c'est pour ça qu'une paille dans un verre d'eau a l'air cassée. Le rayon qui traverse s'appelle le rayon transmis, et sa direction dépend de trois ingrédients : la normale, la direction du rayon entrant, et l'indice de réfraction du matériau (environ 1,33 pour l'eau, 1,5 pour le verre).

La règle qui régit ce pliage est la loi de Snell-Descartes :

n₁ · sin(θ₁) = n₂ · sin(θ₂)

n₁, n₂ sont les indices des deux milieux (l'air et le verre, par exemple) et θ₁, θ₂ les angles par rapport à la normale. Détail qui compte : quand le rayon ressort de la sphère de l'autre côté, il change à nouveau de milieu, donc il se réfracte une seconde fois. Une bille de verre plie donc la lumière au moins deux fois.

Fresnel : doser le mélange

Voilà le vrai problème. Une surface de verre est à la fois réfléchissante et transparente. Quel pourcentage de chaque ? Ce n'est pas du 50-50 fixe. La réponse dépend de l'angle sous lequel on regarde, et elle est donnée par les équations de Fresnel.

L'intuition est facile à vérifier : regarde un lac. Juste à tes pieds, presque à la verticale, tu vois à travers l'eau (le fond, les cailloux) — c'est de la réfraction. Vers l'horizon, en rasant la surface, l'eau devient un miroir qui reflète le ciel — c'est de la réflexion. Plus l'angle est rasant, plus ça réfléchit. C'est l'effet Fresnel, et il est partout.

En pratique, Fresnel renvoie deux coefficients : Kr (la part réfléchie) et Kt (la part transmise). Comme la lumière ne se crée ni ne se perd (la conservation vue à l'article 02), on a toujours :

Kr + Kt = 1

Donc connaître l'un donne l'autre. Le mélange final s'écrit alors directement :

cppcolor reflectionColor = computeReflectionColor();   // rayon réfléchi (récursif)
color refractionColor = computeRefractionColor();   // rayon transmis (récursif)

float Kr, Kt;
fresnel(indiceRefraction, normalHit, primaryRayDirection, &Kr, &Kt);  // Kt = 1 − Kr

couleurDuVerre = Kr * reflectionColor + Kt * refractionColor;

La couleur de la bille de verre est un barycentre entre ce que reflète sa surface et ce qu'on voit à travers, pondéré par l'angle de vue.

Stop : la limite de récursion

Cette beauté a un piège. Si les rayons réfléchis et réfractés relancent l'algorithme, et qu'ils tombent à leur tour sur des surfaces réfléchissantes, le processus se répète sans fin. Mets une caméra dans une boîte aux murs de miroir : un rayon rebondirait indéfiniment, et le calcul ne s'arrêterait jamais.

La parade est pragmatique : on impose une profondeur de récursion maximale. On compte les rebonds, et au-delà d'une limite (souvent 3, 4 ou 5), on arrête et on renvoie une couleur par défaut. C'est une approximation — un miroir face à un miroir n'aura pas son infinité de reflets — mais une approximation invisible à l'œil au-delà de quelques niveaux, et qui garantit que le rendu se termine en temps fini. On retrouvera cette constante MAX_RAY_DEPTH dans le code de l'article suivant.

L'algorithme complet de Whitted est là : intersection, ombre, réflexion, réfraction, mélange Fresnel, le tout récursif et borné. Il ne reste plus qu'à l'écrire pour de vrai.


Sources

  • Whitted, T. (1980). An Improved Illumination Model for Shaded Display. Communications of the ACM, 23(6), 343–349. DOI : 10.1145/358876.358882texte intégral
  • Scratchapixel. Adding Reflection and Refraction. scratchapixel.com
  • Pharr, M., Jakob, W., & Humphreys, G. (2023). Physically Based Rendering (4ᵉ éd.), chap. « Reflection Models » (équations de Fresnel, loi de Snell). pbr-book.org
  • Hecht, E. (2017). Optics (5ᵉ éd.), chap. sur la réfraction et les coefficients de Fresnel. Pearson.

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.