Les lumières : introduction
Dans la création de mondes en 3D, l'éclairage revêt une importance fondamentale, tant dans la représentation fidèle du réel que dans celle du cinéma. Comme dans de nombreux domaines informatiques, nous atteindrons nos objectifs grâce à des calculs mathématiques, offrant ainsi une expérience visuelle optimale. Pour cela, nous introduirons un concept crucial dans la géométrie de nos objets : la notion de "normale" pour chaque face. En simplifiant, la normale d'une face est un vecteur perpendiculaire au plan qu'elle forme. De plus, chaque vecteur normalisé (avec une longueur comprise entre 0.0 et 1.0) garantira une représentation précise de la géométrie.
La lumière ambiante
La lumière ambiante constitue le modèle le plus élémentaire en matière d'éclairage. Il postule qu'il existe une source lumineuse omniprésente qui illumine de manière uniforme dans toutes les directions. Ce modèle représente le niveau minimal d'éclairage appliqué aux objets. Pour l'appréhender physiquement, on peut le comparer à la lumière solaire réfléchie par l'environnement, créant ainsi une sorte de luminosité diffuse. L'intensité de cette lumière sur une surface est définie par la formule : $Ip = pa*Ia$
Cette intensité lumineuse demeure constante sur toute la surface. Dans cette équation, 'Ia' représente l'intensité de la lumière ambiante, tandis que 'pa' correspond au coefficient de réflexion de la lumière ambiante par la surface $(0 <= pa <= 1)$. 'Ip' quantifie l'intensité de la lumière résultant de sa réflexion sur la surface. Imaginons un objet constitué d'une seule matière. Dans ce cas, 'pa' reste constant sur toute l'étendue de l'objet, ce qui donne à celui-ci une couleur uniforme. Cependant, ce modèle d'illumination ne parvient pas à mettre en relief le volume d'un objet, comme illustré dans la figure suivante.
La réflexion diffuse
Dans le cadre de notre modèle, nous supposons désormais que la source lumineuse est ponctuelle et émet de manière uniforme dans toutes les directions de l'espace. Dans le contexte de la réflexion diffuse, l'intensité lumineuse en un point donné d'une surface dépend de l'angle formé entre le rayon de lumière incident touchant ce point et la normale à la surface. Plus cet angle est petit, c'est-à-dire plus le rayon lumineux est proche de la normale, plus l'intensité lumineuse réfléchie visible par l'observateur est forte.
Ce modèle repose sur un principe physique fondamental : notre source lumineuse émet une certaine quantité d'énergie par mètre carré. Selon l'angle d'incidence des rayons lumineux, cette énergie est répartie sur une surface de l'objet plus ou moins grande. Lorsque les rayons lumineux et la surface de l'objet sont perpendiculaires, l'énergie lumineuse est distribuée sur la plus petite surface possible, ce qui entraîne une concentration maximale d'énergie par unité de surface (voir figure).
Maintenant que nous comprenons l'importance de l'angle entre la normale à la surface et les rayons lumineux, explorons comment déterminer la lumière qui sera réfléchie en direction de l'observateur. Pour cela, nous nous appuyons sur les propriétés de la surface. Si nous considérons que la surface est une surface lambertienne, telle que le papier ou la neige, alors nous pouvons postuler que la lumière incidente sur la surface est réfléchie de manière égale dans toutes les directions. Dans ce cas, la position de l'observateur n'a pas d'incidence. La lumière émise en direction de l'observateur dépend donc de l'intensité de la source lumineuse ('Il'), de l'angle theta formé par le rayon lumineux et la normale au plan, et du coefficient de réflexion 'pd' de la lumière diffuse par la surface $(0 <= pd <= 1)$. La formule obtenue est la suivante : $Ip = pd \times Il \times \cos(\theta)$. Voyons cela illustré dans la figure :
vec3 viewDir = normalize(-in_position);
vec3 lightDir = normalize(lightPosition - in_position);
vec3 diffuse = max(dot(in_normal, lightDir), 0.0) * lightData[lightIndex].lightColour.rgb;
La réflexion spéculaire
Le modèle de réflexion spéculaire se distingue du modèle de diffusion en intégrant le point d'observation. Dans ce schéma, les rayons lumineux sont réfléchis symétriquement par rapport à la normale à la surface. Ce modèle reflète les propriétés "miroir" des objets. Il implique le calcul du rayon réfléchi sur la surface, suivi de l'évaluation de l'intensité de la lumière perçue. Cette intensité dépend de theta, représentant l'angle entre le rayon réfléchi et le point d'observation, de l'intensité de la source lumineuse, et du coefficient de réflexion 'ps' de la lumière spéculaire par la surface (0 ≤ ps ≤ 1). Lorsque le rayon réfléchi est directement dans la ligne de vision, l'intensité est maximale. Autour de ce point, une certaine quantité de lumière peut encore être perçue, bien que légèrement atténuée. Cela indique que la surface ne reflète pas uniquement le rayon de manière directe, mais qu'il y a une diffusion autour de celui-ci. La fonction cosinus joue un rôle crucial ici, mais pour ajuster cette diffusion autour du rayon réfléchi, nous introduisons le coefficient 'n'. La formule obtenue est donc : $Is = ps * Il * cos(theta)^n$
Voici un exemple de réflexion spéculaire :
vec3 halfDir = normalize(lightDir + viewDir);
float specPower = pow(max(dot(in_normal, halfDir), 0.0), 500.0);
vec3 specular = lightData[lightIndex].lightColour.rgb * specPower;