Atténuation de la lumière
Jusqu'à présent, la distance entre la source lumineuse et la surface n'a pas été prise en compte. Pour corriger cela, nous pouvons intégrer un coefficient d'atténuation de la lumière dans les modèles de réflexion diffuse et de réflexion spéculaire. Ce coefficient permet de pondérer l'intensité de la lumière en fonction de la distance. Voici un exemple de coefficient de pondération : $fd = min(1/(c1+c2*dist+c3*dist^2), 1)$
float attenuation = 1.0 - clamp(dist / lightData[lightIndex].lightRadius, 0.0, 1.0);
attenuation *= lightData[lightIndex].intensity;
Pour éviter que l'atténuation ne devienne une amplification, nous prenons le minimum entre 1 et la valeur calculée. Cette formule introduit trois nouveaux coefficients sur lesquels nous pouvons agir. Pour l'utiliser dans les modèles de réflexion mentionnés précédemment, nous devons d'abord calculer la distance entre la source lumineuse et le point où nous évaluons l'intensité lumineuse. Ensuite, nous calculons la lumière selon le modèle choisi, en appliquant également le coefficient $f_d$. Le résultat final de l'intensité lumineuse est obtenu en multipliant l'intensité calculée par le coefficient d'atténuation $f_d$.
Modèle de lumière complexe
Pour obtenir des illuminations plus complexes, nous combinons la lumière spéculaire avec la lumière diffuse et la lumière ambiante, tout en tenant compte du coefficient de pondération en fonction de la distance. Pour ce faire, il suffit de calculer les intensités d'illumination pour chacun de ces modèles et d'additionner les résultats pour obtenir l'intensité lumineuse totale. De la même manière, si nous voulons intégrer plusieurs sources de lumière dans une scène, il nous suffit de calculer l'intensité lumineuse pour chaque source sur une surface donnée, puis d'additionner toutes les intensités pour obtenir l'intensité résultante de l'ensemble des sources de lumière sur cette surface.
Utilisation de l'intensité
En général, un point sur un écran (pixel) est représenté par trois composantes : le rouge, le vert et le bleu. Prenons l'exemple de la couleur marron, décomposée en 165 de rouge, 42 de vert et 42 de bleu. Supposons que nous ayons calculé une intensité de 0.7 pour ce point marron. Pour obtenir la nouvelle teinte de marron correspondant à une intensité de 0.7, il suffit de multiplier les composantes rouge, verte et bleue du marron initial par cette intensité. Ainsi, nous obtenons : 115 pour le rouge, 29 pour le vert et 29 pour le bleu.
Cela nous conduit à une autre question : les valeurs de rouge, de vert et de bleu sur un écran (dans la mémoire vidéo) sont bornées. Si nous considérons que ces valeurs sont comprises entre 0 et 255, que se passe-t-il en cas de débordement ? Par exemple, si l'intensité lumineuse en un point est importante (par exemple, 8), et que les valeurs dépassent 255, nous pouvons simplement plafonner les valeurs à 255. Bien que cela ne corresponde pas à un modèle physique précis, cela peut simuler un effet d'éblouissement où tout devient blanc lorsque la lumière est trop forte.
Voici un exemple qui illustre l'application de cette saturation en utilisant la lumière ambiante, la réflexion diffuse et spéculaire :