IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Les shaders dans OpenGL

Introduction à la programmation de shaders GLSL


précédentsommairesuivant

IV. Étude des shaders

IV-A. Techniques de base

IV-A-1. Éclairage

Exemple d'éclairage d'une théière
Exemple d'éclairage d'une sphère en OpenGL

L'éclairage est une partie importante pour toute application graphique. Nous allons reproduire le comportement du pipeline fixe lors du calcul des lumières.

Pour rappel, nous distinguons trois types de sources :

  • La lampe directionnelle ;
  • Le spot ou projecteur (voyons-le comme un cône ayant sa pointe à la source de la lampe) ;
  • Le point de lumière (point light) (pensez à une luciole).


Lors du calcul de l'éclairage, nous distinguons trois types de lumière :

  • la lumière ambiante représentant une lumière globale ;

    Éclairage d'une théière avec une lumière ambiante
  • la lumière diffuse représentant les rayons rebondissant sur nos objets des différentes sources de lumière ;

    Éclairage d'une théière avec une lumière diffuse
  • la lumière spéculaire représentant le reflet des lumières.
Éclairage d'une théière avec une lumière spéculaire

Avant de commencer les calculs, il faut déterminer les besoins afin de décrire les lumières. Les informations à passer à notre shader sont les suivantes :

  • la position de la lumière. Effectivement, avec la position de la lumière, il sera plus facile de calculer la zone éclairée par la lumière ;
  • la couleur ambiante de la lumière ;
  • la couleur diffuse de la lumière ;
  • la couleur spéculaire de la lumière.


Seulement pour les spots et les points de lumière :

  • atténuation constante ;
  • atténuation linéaire ;
  • atténuation quadratique.


Seulement pour les spots :

  • une direction ;
  • un angle d'ouverture ;
  • un coefficient d'exposition (un objet en plein dans l'angle du spot sera plus éclairé qu'un objet à la limite de la zone éclairée par le spot) ;
  • une limite d'éclairage (pour définir là où le spot n'éclaire plus, car l'objet est trop loin).

Il est toujours possible de ne pas utiliser toutes ces informations afin de simplifier et/ou d'optimiser les calculs.

Pour les exemples de code qui suivent, nous allons partir du principe que nous utilisons la structure suivante :

Structure des informations pour la lumière
Sélectionnez
struct Lumiere
{
    vec3 position;
    vec4 couleurAmbiante;
    vec4 couleurDiffuse;
    vec4 couleurSpeculaire;
    float shininess ; // Seulement pour la lumière spéculaire
// Spécifique aux spots et points
    float attenuationConstante ;
    float attenuationLineaire ;
    float attenuationQuadratique ;
// Spécifique aux spots
    vec3 direction ;
    float angle ;
    float exposition;
    float limite;
}

Afin de faire les calculs de lumière diffuse et de lumière spéculaire, nous avons besoin des normales pour chaque vertex de nos objets. Finalement, il est nécessaire de connaître l'inverse de la matrice de vue, pour le calcul de la lumière spéculaire.

IV-A-1-a. La lumière ambiante

Certainement la plus simple à appliquer, celle-ci est simplement une application de la couleur ambiante sur l'objet à éclairer.

Calcul de la lumière ambiante
Sélectionnez
couleurAmbiante = lumiere.ambiant;
IV-A-1-b. La lumière diffuse
Schématisation de la lumière diffuse
Schématisation de la lumière diffuse

La lumière diffuse est une application de la formule de la réflexion de Lambert :

  • intensité = couleur_de_la_lumière_diffuse * cos(angle_entre_le_rayon_de_la_lumière_et_la_normale_de_l'objet)


Comme vous pouvez le constater, la couleur que l'on applique sur le pixel n'est qu'une fraction de la lumière de la lampe. La fraction dépend de l'angle entre le rayon lancé par la lampe sur l'objet et de l'orientation de l'objet (sa normale).

Le rayon de la lumière n'est autre que le vecteur entre la lumière et le point d'impact de celle-ci. Il est simple de connaître ce vecteur, car nous avons la position de la source de lumière, mais aussi la position du point de rebond. Ce point est exactement celui dont nous calculons l'intensité de la lumière. L'opération sera donc :

Calcul du vecteur entre le vertex et la lumière
Sélectionnez
Vec3 rayon = lumiere.position – vertex;

(Note : la position de la lumière doit être normalisée.)

Pour connaître le cosinus de l'angle entre deux vecteurs, nous allons utiliser le produit scalaire (en anglais : dot product). Le GLSL nous fournit une fonction appelée 'dot' pour appliquer ce calcul. Nous aurons donc dans notre code :

Calcul de l'angle entre le rayon de la lumière et la normale de l'objet
Sélectionnez
float angleLumiere = dot(normal, rayon);

Finalement, nous pouvons appliquer la formule de la réflexion de Lambert :

Calcul de la lumière diffuse
Sélectionnez
Vec3 couleurDiffuse = lumiere.diffuse * angleLumiere;
IV-A-1-c. La lumière spéculaire
Schématisation de la lumière spéculaire
Schématisation de la lumière spéculaire

La lumière spéculaire est le reflet de la lampe sur l'objet que nous dessinons. Pour calculer celle-ci, nous utilisons le modèle simplifié Blinn-Phong. La formule de ce modèle est la suivante :

  • spec = (Normale . (œil – rayon_lumière))shininess * couleur_de_la_lumière_speculaire


Pour connaître la position de l'œil, nous allons utiliser la position du vertex que nous sommes actuellement en train de calculer pour lui appliquer la matrice inverse de vue. Pour rappel, la matrice de vue, permet de transformer des coordonnées de l'espace monde à l'espace de la caméra. La multiplication avec la matrice inverse fait donc l'opération inverse, ainsi, nous pouvons retrouver la position de la caméra. Le code de cette opération est le suivant :

Calcul de la position de la caméra
Sélectionnez
Vec3 oeil = matrice_inverser_vue * vertex;

Le rayon_lumière, qui représente le vecteur entre la lumière et l'objet se calcule en soustrayant la position de la lumière à celle du vertex :

Calcul du vecteur de lumière
Sélectionnez
Vec3 ray = lumiere.position – vertex;

Le reste de la formule ne pose pas de problème. Pour rappel, afin d'effectuer les calculs sur les puissances le GLSL fournit la fonction pow (pour 'power' qui signifie puissance en anglais). La variable appelée 'shininess' correspond à la force du reflet.

Calcul de la lumière spéculaire
Sélectionnez
vec3 couleurSpeculaire = pow(dot(normale,(oeil-ray)),lumiere.shininess) * lumiere.couleurSpeculaire;

Voici les résultats avec un shininess de 8, 64 et 128 :

Exemple d'éclairage avec une valeur de shininess à 8
Shininess à 8
Exemple d'éclairage avec une valeur de shininess à 64
Shininess à 64
Exemple d'éclairage avec une valeur de shininess à 128
Shininess à 128
IV-A-1-d. Application de nos différentes lumières

Le calcul final de la couleur se résume à la somme des différentes lumières. Toutefois, la lumière spéculaire ne doit pas apparaître si l'angle de la lumière (défini lors du calcul de la lumière diffuse) est inférieur à zéro (il serait dommage de voir le reflet de la lampe alors que celle-ci éclaire l'autre face de l'objet).

Calcul de la couleur finale
Sélectionnez
gl_FrontColor = couleurAmbiante + couleurDiffuse + couleurSpeculaire;
Résultat de l'éclairage
Résultat de l'éclairage

Maintenant que nous savons comment calculer les différentes lumières, nous allons découvrir comment reproduire les différents types de lampes. Les formules que nous avons apprises juste ci-dessus sont appliquées dans les trois cas, seulement des effets d'atténuation, ou de limite sont ajoutés.

IV-A-1-e. Lampe directionnelle
Schématisation d'une lampe directionnelle
Schématisation d'une lampe directionnelle

La lampe directionnelle peut être comparée au soleil. Ainsi nous pouvons prétendre que la lumière est à une distance infinie, ce qui nous permet de considérer tous les rayons parallèles et ne subissant aucune atténuation. Pour l'appliquer, nous n'avons besoin que de la direction de ses rayons (ou de la position de la lampe). Cela nous simplifie énormément les calculs.

En fait, comme il s'agit d'une lampe sans atténuation, qui éclaire le monde entier, les calculs de la lumière peuvent être effectués tels qu'ils ont été présentés précédemment.

IV-A-1-f. Point de lumière
Schématisation d'un point de lumière
Schématisation d'un point de lumière

Cette lampe ne se base que sur la distance des objets. Selon cette distance, l'objet sera plus ou moins éclairé. De plus, cette lampe éclaire dans toutes les directions.

Comme vous avez pu le deviner, il nous faut calculer la distance de la lampe à l'objet :

Calcul de la distance des objets
Sélectionnez
Vec3 vLumObj = lumiere.position – vertex ;
                  float distance = length(vLumObj);

Puis, encore une fois, nous allons calculer l'atténuation selon cette distance :

Calcul de l'atténuation selon la distance
Sélectionnez
float attenuation = lumiere.attenuationConstante  +
                  lumiere.attenuationLineaire * d +
                  lumiere.attenuationQuadratique * d * d;

Finalement, nous n'avons plus qu'à appliquer cette atténuation sur la lumière :

Calcul de la lumière selon l'atténuation du point de lumière
Sélectionnez
couleurAmbiante = couleurAmbiante * attenuation ;
                  couleurDiffuse = couleurDiffuse * attenuation ;
                  couleurSpeculaire = couleurSpeculaire * attenuation;
IV-A-1-g. Spot
Schématisation d'un spot
Schématisation d'un spot

Le spot peut être représenté par un cône ayant la pointe à la source de la lampe. Si l'objet éclairé est au centre du cône, il reçoit la lumière « forte », mais si celui-ci est sur les bords, la couleur de la lumière est atténuée.

Déjà vous pouvez vous douter des besoins d'une telle lampe. Il nous faut :

  • la direction de la lumière ;
  • l'angle d'ouverture du cône ;
  • atténuation constante ;
  • atténuation linéaire ;
  • atténuation quadratique ;
  • une limite d'éclairage ;
  • un coefficient d'exposition.


Commençons par récupérer la distance entre notre lampe et notre objet. Lors du calcul du rayon de la lumière, nous avons vu comment récupérer le vecteur entre la lumière et l'objet. Pour calculer la distance à partir d'un vecteur, le GLSL nous fournit une fonction toute prête : length() (qui signifie 'distance' en anglais).

Calcul de la distance entre la lumière et l'objet
Sélectionnez
Vec3 vLumObj = lumiere.position – vertex ;
float distance = length(vLumObj);

Maintenant, nous allons calculer l'atténuation selon la distance de l'objet. Pour cela, nous allons reprendre la formule utilisée par OpenGL dans son pipeline fixe.

Calcul de l'atténuation selon la distance
Sélectionnez
float attenuation = lumiere.attenuationConstante  +
lumiere.attenuationLineaire * d +
lumiere.attenuationQuadratique * d * d;

Ensuite nous devons savoir si l'objet est dans le cône de lumière de la lampe. Pour cela nous allons calculer l'angle entre le vecteur de la position de la lampe à l'objet et le vecteur entre l'objet et la direction de la lampe. Encore une fois, nous utilisons le produit scalaire :

Calcul de l'angle entre l'objet et la lampe et la direction de la lampe
Sélectionnez
float angle = dot(-vLumObj, normalize(lumiere.direction));

Nous allons calculer une deuxième atténuation qui, cette fois, dépend de l'angle entre le spot et l'objet.

Atténuation selon l'angle
Sélectionnez
float spotAttenuation = 0.0f
if ( angle >= lumiere.limite )
{
    spotAttenuation = pow(angle,lumiere.exposition);
}

Nous appliquons cette atténuation sur la première que nous avions trouvée :

Application de l'atténuation
Sélectionnez
attenuation *= spotAttenuation;

Pour finir, nous appliquons l'atténuation dans notre calcul de la lumière :

Calcul de la lumière selon l'atténuation du spot
Sélectionnez
couleurAmbiante = couleurAmbiante * attenuation ;
couleurDiffuse = couleurDiffuse * attenuation ;
couleurSpeculaire = couleurSpeculaire * attenuation;
IV-A-1-h. Matériaux

Il nous reste une toute petite partie (optionnelle) lors du calcul de l'effet de lumière sur notre objet. Actuellement, dans nos calculs de lumière nous n'avons pas pris en compte la couleur de nos objets. Plus précisément, nous parlons de matériaux, car les objets peuvent réfléchir de différentes manières la lumière.

Pour décrire un matériau, il faut définir :

  • la couleur ;
  • la couleur diffuse (celle qui est renvoyée à l'œil) ;
  • la couleur spéculaire (une altération du reflet de la lumière, par le matériau).


Pour appliquer un matériau, il faut juste suivre la formule suivante :

(Je pars du principe, que les différentes couleurs contiennent les valeurs précédentes de nos calculs de lumière.) La structure pour les matériaux peut être la suivante :

Structure des informations pour les matériaux
Sélectionnez
struct Materiaux
{
    vec4 ambiante;
    vec4 diffuse;
    vec4 speculaire;
}
Calcul de la lumière en prenant en compte le matériau
Sélectionnez
couleurAmbiante = couleurAmbiante * mat.ambiante;
couleurDiffuse = couleurDiffuse * mat.diffuse;
couleurSpeculaire = couleurSpeculaire * mat.speculaire;

Notez qu'encore une fois, il faut que la lumière spéculaire ne soit visible que si l'angle est supérieur à 0.

IV-A-1-i. Conclusion sur les lumières

Nous avons vu les différentes lumières et les différents types d'éclairages qui étaient présents dans le pipeline fixe d'OpenGL. Vous pouvez implémenter vos propres effets afin d'avoir le résultat qui vous convient le mieux. Le site Wikipedia regorge d'informations sur ce sujet en perpétuelle évolution.

Les algorithmes décrits dans cette section peuvent être appliqués dans le vertex shader ou dans le pixel shader. Sachant que le pixel shader est exécuté pour tous les pixels dessinés, l'exécution sera plus lente, par contre, ce sera plus beau.

L'ancien pipeline était limité à huit lampes. Maintenant vous pouvez faire plus, mais cela va ralentir l'exécution. Il existe une méthode appelée « rendu différé » (Deferred Shading) permettant de mettre des centaines de lampes dans une scène.

IV-A-2. Application d'une texture

Du côté OpenGL, le code pour appliquer une texture est le même que celui qui n'utilise pas de shader.

Pour les textures, il y a quatre variables à gérer :

  • la matrice de la texture : gl_TextureMatrix ;
  • les coordonnées de la texture : gl_MultiTexCoord0 ;
  • les coordonnées de la texture (interpolées) : gl_TexCoord[ gl_MaxTextureCoords ] ;
  • l'échantillon de la texture (les couleurs), qui est une variable uniforme.


La matrice de texture est un tableau, ayant au maximum gl_MaxTextureCoords. gl_MultiTexCoord0 représente les coordonnées de la première texture, pour le vertex actuel. Le zéro peut être remplacé par un chiffre de 0 à 7.

L'échantillon 'sampler' est un type qui représente la texture dans le fragment shader.

Ce qui nous donne le processus suivant :

Vertex shader : transforme nos coordonnées de texture et passe le résultat au fragment shader.

Vertex shader d'application d'une texture
Sélectionnez
void main (void)
{
    gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
    gl_Position = ftransform();
    //gl_FrontColor = vec4(couleur,1.0);
}

Fragment shader : accède à notre texture pour récupérer la couleur. Pour cela, nous utilisons texture2D, qui nous retournera la couleur de la texture à l'endroit indiqué par les coordonnées de texture.

Fragment shader d'application d'une texture
Sélectionnez
uniform sampler2D tex;
void main(void)
{
    gl_FragColor = texture2D(tex,gl_TexCoord[0].st);
}
Cube texturé
Cube texturé
IV-A-2-a. Différents types d'application

Dans le pipeline fixe d'OpenGL, nous avions la possibilité de choisir la façon dont la couleur de la texture allait être appliquée sur notre objet. Je vais retranscrire rapidement les différentes formules.

GL_REPLACE :

Remplace la couleur actuelle par la couleur de la texture. C'est exactement le calcul que j'ai fait dans l'exemple précédent.

Application de texture avec GL_REPLACE
Sélectionnez
Couleur = texture2D(tex0, gl_TexCoord[0].xy) ;
Effet du GL_REPLACE
Effet du GL_REPLACE

GL_MODULATE :

Multiplie la couleur venant du vertex shader avec celle de la texture. Cela peut être utile si le calcul de la lumière est effectué dans le vertex shader, et que cette lumière doit avoir un effet sur l'application de la texture.

Application de texture avec GL_MODULATE
Sélectionnez
couleur *= texture2D(tex0, gl_TexCoord[0].xy) ;
Effet du GL_MODULATE
Effet du GL_MODULATE

GL_DECAL :

Utile dans le cas où vous voulez afficher la texture d'un logo sur une surface. La valeur alpha de la texture est utilisée pour faire une interpolation entre la couleur venant du vertex shader (gl_Color), et la couleur de la texture. Finalement, la valeur alpha du vertex shader est utilisée.

Application de texture avec GL_DECAL
Sélectionnez
Vec4 couleurText = texture2D(tex0, gl_TexCoord[0].xy) ;
vec3 coul = mix(color.rgb, couleurText.rgb, couleurText.a) ;
couleur = vec4(coul, color.a);
Effet du GL_DECAL
Effet du GL_DECAL

GL_BLEND :

Ce mode prend en compte la couleur de la texture de l'environnement, en faisant une interpolation entre la couleur venant du vertex shader et celle-ci. Le facteur pour l'interpolation est la texture. Finalement la couleur alpha est déterminée par la multiplication de l'alpha entrant et celui de la texture.

Application de texture avec GL_BLEND
Sélectionnez
Vec4 couleurText = texture2D(tex0, gl_TexCoord[0].xy) ;
vec3 coul = mix(color.rgb, gl_TextureEnvColor[0].rgb, couleurText.rgb) ;
couleur = vec4(coul, color.a * couleurText.a);
Effet du GL_BLEND
Effet du GL_BLEND

GL_ADD :

Ajoute simplement les couleurs. La composante alpha est multipliée pour calculer la composante alpha résultante. Finalement nous remettons les valeurs dans l'intervalle [0, 1], car le calcul peut engendrer des résultats trop grands.

Application de texture avec GL_ADD
Sélectionnez
Vec4 couleurText = texture2D(tex0, gl_TexCoord[0].xy) ;
color.rgb *= couleurText.rgb;
color.a *= couleurText.a ;
couleur = clamp(color,0.0, 1.0);
Effet du GL_ADD
Effet du GL_ADD

Depuis OpenGL 1.3, il y a de nouveaux modes d'application de texture. Ils ne sont pas décrits ici, car cela sort du cadre de ce tutoriel. De plus, il est facile de deviner leur implémentation selon leur description.

IV-A-2-b. Génération automatique de coordonnées de texture

Dans OpenGL, nous pouvions demander au pipeline de générer automatiquement les coordonnées de texture. Si vous voulez toujours utiliser cette méthode (qui présente quelques défauts), voici comment faire.

Pour rappel, OpenGL définit cinq types de générations :

  • GL_OBJECT_LINEAR : utile lorsque la texture est fixée à l'objet (par exemple : un terrain) ;
  • GL_EYE_LINEAR : utile pour produire des contours dynamiques aux objets ;
  • GL_SPHERE_MAP : peut générer des coordonnées pour l'application d'environnement ;
  • GL_REFLECTION_MAP : utilise le vecteur de réflexion comme coordonnées de texture ;
  • GL_NORMAL_MAP : utilise la normale comme coordonnées.

Le calcul pour une sphère, tel qui est décrit dans la spécification d'OpenGL est le suivant :

Calcul de coordonnées de texture pour GL_SPHERE_MAP
Sélectionnez
vec2 sphereMap(in vec3 cameraPosition, in vec3 normal)
{
     float m ;
     vec3 r, u ;
     u = normalize(cameraPosition) ;
     r =reflect(u, normal) ;
     m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0)) ;
     return vec2(r.x / m + 0.5, r.y / m + 0.5);
}

Le calcul utilisé pour GL_REFLECTION_MAP est :

Calcul de coordonnées de texture pour GL_REFLECTION_MAP
Sélectionnez
vec3 reflectionMap(in vec3 cameraPosition, in vec3 normal)
{
     vec3 u = normalize(cameraPosition) ;
     return (reflect(u,normal));
}

Finalement, selon le choix que vous faites pour votre génération, le code généraliste pour avoir les coordonnées de texture est le suivant :

Génération coordonnées texture
Sélectionnez
vec2 sphereMapCoord ;
vec3 reflectionCoord;
 
If ( isTexSphere )
{
    sphereMapCoord = sphereMap(cameraPosition,normal);
}
 
if ( isTexReflection )
{
    reflectionCoord = reflectionMap(cameraPostion,normal);
}
 
// Pour toutes les textures activées
for ( int i = 0 ; i < nombreTexture ; i++ )
{
    if ( isTexObject )
    {
        gl_TexCoord[i].s = dot(gl_Vertex, gl_ObjectPlaneS[i]) ;
        gl_TexCoord[i].t = dot(gl_Vertex, gl_ObjectPlaneT[i]) ;
        gl_TexCoord[i].p = dot(gl_Vertex, gl_ObjectPlaneR[i]) ;
        gl_TexCoord[i].q = dot(gl_Vertex, gl_ObjectPlaneQ[i]);
    }
 
    if ( isTexEye )
    {
        gl_TexCoord[i].s = dot(gl_Vertex, gl_EyePlaneS[i]) ;
        gl_TexCoord[i].t = dot(gl_Vertex, gl_EyePlaneT[i]) ;
        gl_TexCoord[i].p = dot(gl_Vertex, gl_EyePlaneR[i]) ;
        gl_TexCoord[i].q = dot(gl_Vertex, gl_EyePlaneQ[i]);
    }
 
    if ( isTexSphere )
    {
        gl_TexCoord[i] = vec4(sphereMapCoord, 0.0, 1.0);
    }
    if ( isTexReflection )
    {
        gl_TexCoord[i] = vec4(reflectionCoord, 1.0);
    }
    if ( isTexNormal )
    {
        gl_TexCoord[i] = vec4(normal, 1.0);
    }
}

IV-A-3. Brouillard

Le brouillard est un effet qui altère la couleur de l'objet selon la distance entre celui-ci et la caméra.

Dans le pipeline fixe, nous pouvions retrouver trois algorithmes différents pour le calcul du brouillard. Le premier pouvait être sélectionné en indiquant GL_LINEAR à glFogf(GL_FOG_MODE).

La formule utilisée est la suivante :

  • f = fin – z / fin – début


Les variables doivent être dans l'espace de coordonnées de la vue. Toutes ces variables sont intégrées dans le GLSL :

début : gl_Fod.debut
fin : gl_Fod.end
z : gl_FogFragCoord

Le GLSL nous facilite quelque peu la tâche en nous proposant le résultat de gl_Fog.end – gl_Fog.debut dans la variable gl_Fog.scale. Effectivement, ce calcul ne dépend pas de la position du vertex que nous sommes en train de calculer, donc le mieux est de ne faire qu'une seule fois le calcul.

La formule dans notre code sera donc :

Calcul d'un brouillard linéaire
Sélectionnez
Fog = (gl_Fod.end &#150; gl_FogFragCoord) * gl_Fog.scale ;
Brouillard linéaire
Brouillard linéaire

Le deuxième brouillard présent dans OpenGL est un brouillard exponentiel donnant un résultat plus convaincant.

La formule utilisée est la suivante :

  • f = e-(densité * z)


Z est toujours le même que précédemment (soit gl_FogFragCoord) et la densité est une variable uniforme donnée par le programme. Pour le calcul de l'exponentielle, nous allons utiliser la fonction exp() incluse dans le langage.

Le code résultant en GLSL est le suivant :

Calcul du brouillard exponentiel (première méthode)
Sélectionnez
Fog = exp(-gl_Fog.density * gl_FogFragCoord) ;
Brouillard exponentiel
Brouillard exponentiel

Finalement, le troisième algorithme présent dans le pipeline fixe (correspondant à GL_EXP2) est une amélioration (graphique) de l'algorithme précédent.

La nouvelle formule est la suivante :

  • fog = e-(densité * z)²


Qui correspond au code suivant :

Calcul du brouillard exponentiel (seconde méthode)
Sélectionnez
Fog = exp(-gl_Fog.density * gl_FogFragCoord * gl_Fog.density * gl_FogFragCoord);
Image non disponible
2e Brouillard exponentiel

Pour appliquer le brouillard, il faut être sûr que la variable fog est entre 0 et 1. Cela peut se faire en utilisant une fonction du GLSL appelée clamp :

Limitation du brouillard
Sélectionnez
fog = clamp(fog, 0.0,1.0);

Finalement, nous pouvons appliquer le brouillard sur la couleur calculée pour l'objet. Le brouillard a une couleur propre contenue dans gl_Fog.color :

Application du brouillard
Sélectionnez
couleur = mix(vec3(gl_Fog.color), couleur, fog);

IV-A-4. Clipping

Le clipping est l'action de découper des morceaux de rendu final afin de ne pas les afficher. Cette fonctionnalité est toujours intégrée de manière fixe dans le pipeline graphique (entre le processeur de vertex et le processeur de fragment).

Si vous utilisez, le clipping, vous allez devoir indiquer la position de vertex afin qu'OpenGL puisse savoirs'il doit l'afficher ou non. Pour cela il suffit d'assigner une valeur à la variable gl_ClipVertex. Habituellement, les utilisateurs stockent le rectangle à découper dans l'espace de coordonnées de l'œil. Cela veut donc dire que nous devons transformer notre vecteur afin de l'avoir dans cet espace :

Calcul du clipping
Sélectionnez
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;

précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2011 Alexandre Laurent. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.