Qualificatifs d'interpolation d'OpenGL (GLSL)

JeGX

Traducteur

Alexandre Laurent

OpenGL 3 a introduit de nouvelles possibilités, notamment en offrant à l'utilisateur un meilleur contrôle sur les différentes étapes du rendu. Découvrons ici les qualificatifs d'interpolation du GLSL.

Commentez

- Titre : Qualificatifs d'interpolation d'OpenGL (GLSL)

- Auteur : JeGX

- Traducteur : Alexandre Laurent

- Parution : 22 mai 2013

- Mise à jour : 22 mai 2013

- Licence : 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 ® 2013 Geeks3D. Aucune reproduction, même partielle, ne peut être faite de ce site et 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.

Sommaire

- I. Introduction

- II. Utilisation

- III. Références

- IV. Remerciements

I - Introduction

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

#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

#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 :

Avec le qualificatif flat, le rendu est le suivant :

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 :

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

#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

#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 :

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 :

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 :

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

...
smooth out vec vertex_color;
...

Fragment shader

...
flat in vec vertex_color;
...

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

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

III - Références

- Wiki OpenGL - Qualificatifs de type (GLSL)

- Wiki OpenGL - Vertex initiateur

- Extension GL_ARB_gpu_shader_5

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.