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 :
#
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;
}
#
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 :
#
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
;
}
#
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 :
...
smooth
out
vec vertex_color;
...
...
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▲
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.