Illumination/Shading avec OpenGL
Compilez et executez le code du répertoire scenes_inf443/02b_opengl_shading/.- - Les objets affichés utilisent un fragment shader minimaliste: shaders/shading_custom/shading_custom.frag.glsl.
- - La couleur des objets est uniforme, et obtenue par le produit:
- \(C = \alpha_a \; C_o\,C_l\)
-
- - \(C\): couleur de sortie
- - \(\alpha_a\): coefficient ambiant (paramètre uniform "ambiant") \(\in[0,1]\)
- - \(C_o, C_l\): couleur de l'objet et de la lumière
void main() { vec3 current_color; current_color = ambiant * material.color * light_color; FragColor = vec4(current_color, 1.0); // Note: the last alpha component is not used here }

Illumination de Phong
Coefficient diffus
Implémentez dans un premier temps la gestion du coefficient diffus suivant la formulation- \(C = (\alpha_a + \alpha_d \; (n\cdot u_l)_{+}) \; C_o\,C_l\)
-
- - \(\alpha_d\): coefficient diffus (paramètre uniform à ajouter) \(\in[0,1]\).
- - \(p\): position courante de l'objet.
- - \(n\): normale unitaire de l'objet à la position \(p\).
- - \(u_l\): direction unitaire pointant vers la lumière (entre \(p\) et la position de la lumière).
- - \((a\cdot b)_{+}\): correspond à \(\max(a\cdot b\,,\;0)\).
- - Dans un premier temps vous pouvez fixer la valeur de \(\alpha_d\) "en dur" dans le shader.
- - Si l'ensemble fonctionne, ajoutez le coefficient diffus \(\alpha_d\) dans la GUI de votre programme, et passez le en paramètre uniform (tout comme le coefficient ambiant).
-
- - Vérifiez une fois cela fait que votre illumination dépende bien de la position de la lumière.

- - La position courante de la forme est disponible dans "fragment.position"
- - La normale à la position courante est disponible dans "fragment.normal".
- - Il est possible de normaliser un vecteur a en GLSL en appelant "normalize(a)"
- - Attention: "fragment_data.normal" n'est pas forcément de norme 1. En effet, les paramètres de fragment sont obtenus depuis la sortie du vertex shader et sont obtenus par interpolation linéaire des valeurs aux sommets. L'interpolation linéaire de vecteurs unitaire, n'est pas forcément unitaire.
- - Le produit scalaire entre deux vecteurs (a,b) est obtenu par "dot(a,b)" en GLSL.
- - Le maximum entre a et b est obtenu par "max(a,b)".
- - Pour éviter de saturer les couleurs dès le lancement du programme, vous pouvez fixer la valeur par défaut du coefficient ambiant à 0.3, et celle du coefficient diffus à 0.8 dans le fichier scene.hpp.
- - En GLSL, les nombres flottant s'écrivent sans le f final (différent de C++). ex. 0.0, 0.5, 1.0, etc.
Coefficient spéculaire
Ajoutez la prise en compte du coefficient spéculaire. La formulation sera alors- \(C = (\alpha_a + \alpha_d \; (n\cdot u_l)_{+}) \; C_o\,C_l + \alpha_s\;(u_r\cdot u_v)_{+}^{s_{exp}}\;C_l\)
-
- - \(\alpha_s\): coefficient speculaire (paramètre uniform à ajouter) \(\in[0,1]\).
- - \(s_{exp}\): exposant speculaire (typiquement \(0<s_{exp}<256\)). (paramètre uniform à ajouter)
- - \(u_r\): direction de reflexion de \(-u_l\) par rapport à la normale.
- - \(u_v\): vecteur unitaire dans la direction du point de vue (entre la position sur l'objet le centre de la caméra).
Modèle d'illumination de Phong avec coefficients ambiant, diffus et spéculaire modifiables.
- - La position de la caméra peut être retrouvée à partir de la matrice "view" par le code suivant
mat3 O = transpose(mat3(view)); // get the orientation matrix vec3 last_col = vec3(view * vec4(0.0, 0.0, 0.0, 1.0)); // get the last column vec3 camera_position = -O * last_col;
-
- - L'explication peut être retrouvée à partir de cette slide (hors programme de votre cours).
-
- La matrice de "view" est l'inverse de la matrice des coordonnées de la caméra dans le référentiel globale. Il est possible de récupérer la position de la caméra en appliquant l'inverse par bloc sur la matrice composée d'une partie rotation et d'une translation.
- - GLSL dispose de la fonction reflect qui calcule la reflection d'un vecteur a vis à vis de la normale n.
Effet de brume
Un effet de "brume" (/fog) peut être réalisé en attenuant la couleur du fragment en fonction de sa profondeur. Un fragment proche de la caméra aura l'illumination de phong, alors qu'un fragment éloigné tendra vers la couleur de la brume. Dans le cas d'une atténuation linéaire en fonction de la distance, on peut considérer- \(C = (1-\alpha_{f}) C_p + \alpha_f C_f\)
-
- - \(C_p\): la couleur obtenue sans effet de brume.
- - \(C_f\): la couleur de la brume
- - \(\alpha_f\) le coefficient d'attenuation, calculé par exemple par
-
- \(\alpha_f = \min(d/d_{max},1)\)
- \(d\): distance de la position à la caméra
- \(d_{max}\): distance maximal à partir de laquelle on ne voit plus que la couleur de la brume.
Effet de brume avec atténuation linéaire. Ici \(d_{max}=15\).
- - La couleur de la brume calculée dans le shader n'est appliqué qu'aux fragments où des objets sont présents. Il est également nécessaire d'appliquer la couleur de la brume sur le background.
- \(\Rightarrow\) La couleur du background est paramétrée par la variable: "environment.background_color". Cette variable (par défaut blanche) est utilisée à chaque frame pour ré-initialiser l'image d'une couleur fixe.
- - En GLSL, la function "length(a)" calcule la norme d'un vecteur a.
Attenuation d'éclairage
Un autre effet d'illumination possible est l'atténuation de l'effet de la lumière en fonction de sa distance aux objets. On peut alors considérer une atténuation linéaire en fonction de la distance telle que- \(C_l = (1-\alpha_{l}) C_l^0\)
- \(\alpha_l=\min(d_l/d_{l,max},1)\)
-
- - \(C_l\): Couleur de la lumière en un point donné
- - \(C_l^0\): Couleur de la lumière initiale, sans atténuation
- - \(\alpha_l\): Attenuation due à la distance
- - \(d_l^0\): Distance entre la lumière et le point courant de la surface
- - \(d_{l,max}\): Distance à partir de laquelle la lumière n'a plus d'effet.
Effet d'attenuation de la source lumineuse avec effet de brume \(d_{max}=12, d_{l,max}=4\).
Extensions possibles
Uniquement si jamais vous avez fini en avance- - Appliquez un mouvement procédural au cours du temps aux sources lumineuses.
- - Ajoutez plusieurs sources lumineuses ayant des couleurs et intensités différentes.