Free online content available in this course.

Got it!

Last updated on 1/5/16

Introduction au GLSL

Log in or subscribe for free to enjoy all this course has to offer!

Vous vous demandez probablement qui peut bien être ce GLSL, et à quoi il peut servir ? o_O

Je vais, dans ce premier chapitre, essayer de vous expliquer à quoi il peut amener. Nous verrons ce qu'il représente exactement et comment il intervient dans un rendu 3D avec OpenGL.

Que saurais-je faire à la fin de ce tutoriel ?

Je ne peux pas être affirmatif sur ce point, mais je pense pouvoir vous apprendre :

  • à faire de la lumière. Nous apprendrons à gérer des lumières avec le GLSL;

  • cel-shading, ou rendu cartoon. Cet effet est très simple à réaliser, je pense que c'est l'un des premiers que nous étudierons;

  • manipulation de textures. Nous verrons comment déformer simplement nos textures pour donner des effets de distorsion, mais aussi des effets de flou (comme le flou de vitesse de certains jeux de voiture);

  • pseudo-HDR. La gestion de la lumière alliée à la manipulation des textures nous permettra de réaliser "facilement" un effet de pseudo-HDR.

Mais avant de voir toutes ces jolies choses, il nous faut tout d'abord connaître l'essentiel : qu'est-ce que le GLSL, et comment on l'utilise.

C'est quoi ?

A l'origine pensé par Pixar pour ses animations vidéos, les shaders ont fait leur apparition dans le domaine du jeu vidéo assez récemment et sont aujourd'hui indispensables pour qui veut réaliser des effets graphiques un tant soit peu évolués.

GLSL (Def. GLSL (en)) est l'abréviation de OpenGLShading Language, traduisez : langage de programmation de shaders OpenGL.
Effectivement, le GLSL est un langage de programmation de shaders.

La programmation GPU

Le GPU est le processeur de votre carte graphique, c'est lui qui calcule vos rendus 3D. La programmation GPU revient donc à... programmer nos calculs de rendus 3D o_O
Ah bah tiens, c'est la meilleure du siècle celle-là :p

Les shaders servent à programmer le pipeline de rendu par défaut de votre carte graphique, appelé le FFP.
Les shaders ne sont donc rien de plus que des programmes, donc :

  • un code source;

  • une compilation;

  • une exécution.

Ils se différencient toutefois des programmes écrits en C, C++ ou autre langage réservé à une exécution CPU, de par leur compilation et leur exécution.
La compilation d'un shader est effectuée lors du lancement de votre application, et l'exécution se passe au niveau du GPU, contrairement à vos programmes habituels (C, C++, C#, Java, ...) qui eux sont traités par le CPU, et c'est ce qui fait la puissance et la flexibilité des shaders dans le rendu 3D en général :)

En assembleur ?

Quand on parle de la programmation d'un processeur, on pense généralement à l'assembleur. Il existe effectivement des langages assembleur pour programmer un GPU, mais nous ne les traiterons pas dans ce tutoriel.
Ici, nous ne parlerons que d'un langage de programmation GPU dit de haut niveau, le GLSL.
Le GLSL a été développé par l'ARB pour l'API graphique OpenGL afin d'offrir une plus grande souplesse dans la programmation de shaders.
DirectX a également développé son propre langage haut niveau pour la programmation de shaders, il s'agit du HLSL, mais il est plutôt hors-sujet, je ne vous en parle qu'à titre de comparaison.

Le GLSL est donc un langage de programmation de shaders de haut niveau, mais à quoi ça ressemble au juste ?
Voici le code source d'un shader écrit en GLSL :) :

void main(void)

{

    gl_TexCoord[0] = gl_MultiTexCoord0;

    gl_Position = gl_Vertex * gl_ModelViewMatrix;

}

Il s'agit là d'un simple vertex shader.

Vertex shader ??

Oui. Il est important de distinguer deux types de shaders différents, remplissant chacun des fonctions bien définies et aucunement identiques :

  • les vertex shaders : ce sont des shaders qui interviennent lors du traitement de chaque sommet. Dans les vertex shaders vous pourrez modifier le calcul des différents attributs de vos sommets;

  • les pixel shaders : aussi appelés fragment shaders, ils permettent de traiter le rendu de chaque pixel qui s'affichera à l'écran. Ces derniers offrent une grande flexibilité dans le domaine du rendu 3D.

J'espère que vous y voyez à présent un peu plus clair ;) Les shaders vous permettent de programmer le traitement de chaque sommet ainsi que de chaque pixel.

Pourquoi faire ?

Les shaders permettent donc de programmer la fonction de traitement d'un vertex ainsi que d'un pixel. Mais à quoi cela rime-t-il ? Quel utilité cela peut-il bien avoir ?

Le traitement d'un vertex et d'un pixel, c'est quoi ?

Voilà une bien bonne question :)
Quand vous envoyez des données de sommet à OpenGL via les commandes glVertex*(), glColor*(), glTexCoord*(), glNormal*(), ... (ou par des tableaux via gl*Pointer() ) OpenGL les stocke et les associe à un ou plusieurs triangles bien définis.

Le traitement de ce triangle se décompose par le traitement de ses 3 sommets, puis par une interpolation des données de ses sommets pour obtenir un triangle plein. Ce sont ces deux dernières étapes qui sont traitées respectivement par le vertex et le pixel shader.

Le traitement d'un vertex consiste à lui appliquer des transformations matricielle (GL_MODELVIEW, GL_TEXTURE, ...) pour obtenir les données des sommets définitives qui seront ensuite interpolées.
Le pixel shader reçoit des données interpolées de couleur et autres attributs traités dans le vertex shader.

Quel est l'intérêt des shaders ?

Pensez bien qu'il y en a un ;) En réalité, il y a deux grands avantages à utiliser les shaders.
Le premier est qu'ils permettent une énorme flexibilité de rendu. En gérant le rendu de chaque pixel vous avez un contrôle quasi absolu sur vos rendus 3D et vous pouvez ainsi réaliser beaucoup d'effets chouettes sans trop vous compliquer la vie.
Le second intérêt réside dans leur principe même. Étant exécutés par la carte graphique, les shaders ne consomment pas de processeur (CPU), ce dernier peut alors souffler un peu et se concentrer sur la gestion de l'IA ou du réseau par exemple. Dans cette optique de décharger le processeur, les shaders ont également un énorme intérêt si l'on utilise un langage assez "gourmand" comme le C# ou le Java, qui sont moins rapides que le C.

Un exemple concret ?

Mais concrètement, qu'est-ce qu'on peut faire avec des shaders ?

Il est temps de vous montrer à quoi cela ressemble.
Voici deux captures d'écran de la même scène, l'une utilisant le FFP standard, l'autre, des shaders.

Image utilisateur

Rendu standard

Image utilisateur

Rendu avec shaders

(source du modèle 3D et des textures : http://mdeverdelhan.developpez.com/tut [...] ht/tutoriel6/)

Les shaders permettent d'ajouter des effets qui peuvent être réalistes, beaux ou encore rigolos, comme le cel-shading (aussi appelé rendu cartoon).

Hey je veux savoir faire ça !

Pas de problème :) Toutefois soyez prévenus, pour aboutir à un résultat tel que vous venez d'en voir, les shaders ne suffisent pas, mais ils constituent une partie importante de la réalisation d'un tel effet.
Et oui, les shaders ça ne fait pas tout, il faudra souvent les associer à des techniques de rendu (rendu offscreen notamment).

Image utilisateur

:'(

Ne pleurez pas, je tâcherai de vous enseigner ces techniques au fur et à mesure à travers d'autres tutoriels ;) Et puis sachez qu'il existe aussi des techniques de rendu qui ne se contentent que des shaders.

Comment faire ?

Malgré quelques explications en début de chapitre, il est important que vous sachiez avec un peu plus de précision comment fonctionne l'implémentation théorique des shaders au sein d'un programme OpenGL.

Programmer un shader, c'est dur ?

Pour peu que vous sachiez raisonner logiquement, la programmation d'un shader ne devrait pas vous poser de problème ;)
Cela n'a en réalité rien de sorcier, et si vous maîtrisez un temps soit peu la programmation d'un langage procédural tel que le C, vous vous apercevrez que le GLSL y ressemble beaucoup ;)

En effet, le GLSL est un langage ressemblant fortement au langage C.

Cependant, il est importantimpératif de distinguer deux choses :

  • la programmation d'un shader en GLSL;

  • son utilisation au sein d'une application OpenGL.

Ces deux choses sont totalement différentes, il est primordial de bien faire leur distinction.
Nous avons d'une part la programmation du shader lui-même, c'est-à-dire le codage de la fonction qu'il remplira, l'effet graphique qu'il produira, d'autre part la définition de son utilisation, quand et comment l'utiliser dans notre application.

Nous pouvons comparer cela à l'utilisation des textures, nous avons d'une part la création de la texture, soit la création de l'image via un logiciel de dessin 2D, et d'autre part le chargement et l'utilisation de cette texture dans notre programme.

L'idée est la même pour les shaders, nous allons tout d'abord programmer un shader, nous placerons son code source dans un fichier, puis nous programmerons notre application OpenGL et nous chargerons via celle-ci le code source de notre shader afin de l'utiliser à notre convenance au sein de notre programme.

Programmer un shader, avec quel IDE ?

Il n'existe pas beaucoup d'éditeurs de texte qui colorent le langage GLSL.

On peut toutefois citer Kate, qui bénéficie du support de la coloration syntaxique du GLSL, il active automatiquement celle-ci pour tout fichier ayant pour extension .vert pour les vertex shader, ou .frag pour les fragment shader (ou pixel shader).

Il existe également QShaderEdit, un éditeur qui semble assez pratique ainsi que portable (bien qu'il utilise QT), mais que je n'ai jamais testé (merci à XT95 pour l'info).

Programmer un shader, avec quel compilateur ?

Aucun ! :p

Vous avez bien lu, il ne vous faut télécharger aucun compilateur. Comme je l'ai déjà dit, les shaders GLSL sont compilés lors de l'exécution de votre application, c'est OpenGL qui s'en charge ;)
Donc rien à faire de particulier ici.

Vous savez à présent qui sont ces fameux shaders, et ce qu'ils permettent de réaliser. Mais vous ne savez pas encore comment le réaliser.
Pour l'instant le plus important est que vous ayez compris leur fonctionnement global, il faut pour cela retenir une chose importante :
les shaders sont des programmes exécutés par la carte graphique.

À partir de cette bonne base, nous allons étudier leur fonctionnement plus en profondeur afin de comprendre comment ils marchent réellement :)

Les spécifications du langage

Pour les adeptes des specs, voici les spécifications du langage GLSL.

Example of certificate of achievement
Example of certificate of achievement