I. Introduction

Image non disponible

OpenGL 3 a introduit trois qualificatifs d'interpolation qui sont à notre disposition dans le vertex et le fragment shader. Ces qualificatifs permettent de spécifier la méthode qu'utilisera un vertex shader pour interpoler ses sorties entre les primitives. La spécification/wiki OpenGL indique :

  • flat : la valeur n'est pas interpolée. La valeur donnée au fragment shader est la valeur du sommet initiateur (provoking vertex) pour cette primitive ;
  • smooth : effectue une interpolation correcte suivant la perspective ;
  • noperspective : effectue une interpolation linéaire dans l'espace écran.

L'interpolation par défaut est smooth lorsqu'aucun qualificatif n'est employé.

II. Utilisation

Voyons voir en pratique comment ces qualificatifs affectent le rendu. J'ai utilisé GLSL Hacker pour coder rapidement la démonstration et jouer avec les shaders GLSL. Toutes les démonstrations de ce tutoriel sont incluses dans le pack d'exemples du logiciel, dans le dossier GLSL_OpenGL_32_Interpolation/.

Le premier test est simple, un quadrilatère avec une couleur différente pour chaque sommet :

  • sommet 0 : rouge ;
  • sommet 1 : vert ;
  • sommet 2 : bleu ;
  • sommet 3 : jaune.

Voici le programme GPU utilisé pour le rendu du quadrilatère :

Vertex shader
Sélectionnez
#version 150
in vec4 gxl3d_Position;
in vec4 gxl3d_Color;
uniform mat4 gxl3d_ModelViewProjectionMatrix;

//flat out vec4 VertexColor;
smooth out vec4 VertexColor;
//noperspective out vec4 VertexColor;

void main()
{
  gl_Position = gxl3d_ModelViewProjectionMatrix * gxl3d_Position;
  VertexColor = gxl3d_Color;
}
Pixel shader
Sélectionnez
#version 150

//flat in vec4 VertexColor;
smooth in vec4 VertexColor;
//noperspective in vec4 VertexColor;

out vec4 Out_Color;
void main()
{
  Out_Color = VertexColor;
}

Avec le qualificatif smooth, le rendu est le suivant :

Image non disponible

Avec le qualificatif flat, le rendu est le suivant :

Image non disponible

Le qualificatif flat désactive l'interpolation et chaque triangle du quadrilatère est coloré avec la couleur du dernier sommet :

  • triangle 0 : sommets {0, 1, 2} - la couleur est bleue, car le sommet 2 est bleu ;
  • triangle 1 : sommets {2, 3, 0} - la couleur est rouge, car le sommet 0 est rouge.

Pourquoi le dernier sommet ? À cause du sommet initiateur. Par défaut, le sommet initiateur est le dernier sommet d'une primitive. Dans notre cas, le dernier sommet d'un triangle. Regardez ICI pour plus d'informations sur le sommet initiateur.

Avec le qualificatif noperspective, le rendu est le suivant :

Image non disponible

Comme vous pouvez le voir, la différence entre noperspective et smooth est très faible, seul un œil aiguisé peut voir les subtiles variations.

Maintenant, effectuons un second test avec un quadrilatère texturé. Voici le programme GPU avec l'application de la texture :

Vertex shader
Sélectionnez
#version 150
in vec4 gxl3d_Position;
in vec4 gxl3d_TexCoord0;
uniform mat4 gxl3d_ModelViewProjectionMatrix;

noperspective out vec4 VertexUV;
//smooth out vec4 VertexUV;
//flat out vec4 VertexUV;

void main()
{
  gl_Position = gxl3d_ModelViewProjectionMatrix * gxl3d_Position;
  VertexUV = gxl3d_TexCoord0 * 4;
}
Pixel shader
Sélectionnez
#version 150

noperspective in vec4 VertexUV;
//smooth in vec4 VertexUV;
//flat in vec4 VertexUV;

uniform sampler2D tex0;
out vec4 Out_Color;
void main()
{
  Out_Color = texture(tex0,VertexUV.xy);
}

Avec le qualificatif smooth, le rendu est le suivant :

Image non disponible

C'est le rendu habituel (celui que l'on attend) et les coordonnées de texture sont interpolées avec la correction de perspective.

Avec le qualificatif flat, le rendu est le suivant :

Image non disponible

La texture aux sommets 0 et 2 est rouge, c'est pourquoi le quadrilatère est uniformément rouge (pas un rouge réel, mais une couleur RGB {0.25, 0, 0}). Une autre façon de dire est que la couleur aux sommets initiateurs a une valeur RGB de {0.25, 0, 0}.

Avec le qualificatif noperspective, le rendu est le suivant :

Image non disponible

Avec le qualificatif noperspective, les coordonnées de texture sont interpolées dans l'espace écran (ou l'espace fenêtre) et nous voyons clairement les triangles.

Une dernière chose : les qualificatifs d'interpolation du vertex shader et du pixel shader doivent être les mêmes. Si ce n'est pas le cas, comme dans l'exemple suivant :

Vertex shader
Sélectionnez
...
smooth out vec vertex_color;
...
Fragment shader
Sélectionnez
...
flat in vec vertex_color;
...

vous obtiendrez des résultats étranges. Sur Windows + GTX 660, j'ai un quadrilatère noir :

Image non disponible

Avec Mac OS X et une carte graphique Intel HD 4000, le quadrilatère n'est même pas affiché :

Image non disponible

III. Références

IV. Remerciements

Cet article est une traduction autorisée de l'article paru sur Geeks3D.com.

Je tiens à remercier Winjerome pour sa relecture lors de la traduction de cet article, ainsi que f-leb pour sa relecture orthographique.