Shader - Définition

Source: Wikipédia sous licence CC-BY-SA 3.0.
La liste des auteurs de cet article est disponible ici.

Exemples d'utilisation des shaders en temps réel

Per-pixel lighting

En temps réel, l'éclairage est souvent calculé au moment du [[T&L]] ou du vertex shader (voir ombrage Gouraud). Il est néanmoins possible d'obtenir un éclairage beaucoup plus précis grâce au per-pixel lighting.

Sa mise en œuvre se fait en deux étapes : le vertex shader calcule la provenance de la lumière pour chaque vertex et l'indique au pipeline, généralement via l'utilisation ainsi détournée des coordonnées de texture.

Le pixel shader récupère ensuite ces données ainsi que la normale virtuelle du pixel en cours de traitement dans le sampler de la bump map. Il connaît alors la normale et la provenance de la lumière, il peut donc calculer l'éclairage du pixel qu'il lui suffira de multiplier avec la couleur provenant de la texture classique.

Toon shading

Le toon shading ou cell-shading consiste à rendre une image en aplats de couleur (similaire aux bandes dessinées).

Structure pour le calcul en temps réel

Plusieurs approches des shader existent en raison des diverses applications technologiques visées. Les langages de shader pour la production de film sont habituellement d'un niveau d’abstraction plus élevé, et évitent d'utiliser du code spécifique pour l'éclairage ou l'ombrage. En revanche, les shader temps réel intègrent le calcul d'ombre et de lumière. Dans ces langages, les lumières sont passées à la fonction de shader en tant que paramètres.

Il existe actuellement deux applications différentes des shaders dans les langages temps réel. Bien que leurs fonctionnalités aient convergé — il est ainsi possible d'écrire un vertex shader en utilisant les mêmes fonctions qu'un fragment shader — les différents rôles imposent des limitations propre à chacun qu’il faut reconnaître.

Vertex shaders

Dans la liste des tâches graphiques séquentielles nécessaires à l'affichage d'une image 3D, la tâche du vertex shader se situe au niveau de la tâche dite de « transformations et éclairage ». En pratique, c'est une tâche au sein du pipeline graphique qui doit calculer la projection de coordonnées des sommets des primitives à partir de l'espace 3D dans l'espace écran.

Contrairement à sa contrepartie « fixe » dans le pipeline, aucune fonction par défaut ne peut être utilisée pour arriver à ce but. Le programmeur se doit donc d'expliciter totalement la procédure de projection à la carte graphique. Pour ce faire, le programmeur se situe dans un environnement de shader avec des registres spécifiques à l'architecture qui définissent aussi les entrées et les sorties du problème.

Un programme shader agit sur un seul sommet unique et isolé. L'architecture hautement parallèle des cartes graphiques actuelles interdit les lectures interdépendantes, c’est-à-dire accéder aux informations d'un sommet voisin par exemple.

Dans les registres d'entrées, on trouve la structure qui a été utilisée lors de l'écriture en mémoire graphique du « vertex buffer » (le tableau des sommets). On y retrouve le plus souvent dans cette structure, un vecteur contenant la position du sommet, parfois une couleur, parfois une coordonnée de texture ou plusieurs, et parfois une normale.

Le shader doit renvoyer une structure de donnée contenant des champs dont la définition est libre qui sera passée en entrée du pixel shader plus tard. Dans la plupart des « vertex programs » on retrouve la fameuse projection 3D vers 2D. En effet selon la formule de mathématique Y=MX (Y vecteur image, M matrice de l'application, X vecteur antécédent), on peut appliquer une transformation linéaire par une multiplication vecteur-matrice. Nous voulons que la matrice M qui effectue la transformation soit ici la matrice de l'application « projection ». On lui donne la dimension 4×4 (la 4e dimension comporte une coordonnée homogène) pour se multiplier avec les vecteurs de la carte graphique qui sont de dimension 4. On utilise une coordonnée homogène car certains problèmes comme la projection ou la translation sont insolubles en algèbre linéaire de dimension 3. Finalement, le « vertex program » le plus courant, en quelque sorte le « hello world » du vertex shader pourrait s'écrire en HLSL tel que suit :

       float4x4 WorldViewProj;             float4 VS_Transform(float4 position: POSITION0)       {           return mul(WorldViewProj, position );       }      

'WorldViewProj' est une variable dite uniforme qui se trouve mappée sur un des registres des constantes lors de la compilation. On l'appelle ainsi car elle est le résultat de la matrice de vue multipliée par la matrice de déplacement du monde, multipliée par la matrice de projection. Ceci permet de placer le point d'observation correctement dans la scène.

Geometry shaders

Les geometry shaders permettent de modifier la géométrie de chaque polygone ainsi que de créer de nouveaux polygones. Ils sont exécutés entre le vertex shader et le fragment shader. Ce type de shader est apparu dans les versions 10 de DirectX et 3.2 de OpenGL (ou OpenGL 1.1 en utilisant l'extension EXT_geometry_shader4).

Un geometry shader reçoit en entrée les données d'une primitive géométrique, et en renvoie une ou plusieurs. Un geometry shader sans effet particulier renvoie simplement la primitive reçue en entrée. En voici un exemple en GLSL :

      #version 120      #extension GL_EXT_geometry_shader4: enable             void main (void)      {        for (int i = 0; i < gl_VerticesIn; ++i)        {          gl_Position = gl_PositionIn[i];          EmitVertex ();        }        EndPrimitive ();      }      

Fragment shaders ou Pixel shaders

Le fragment shader ou pixel shader est un shader dont le but est de calculer la couleur de chaque pixel individuellement. Il prend ainsi en entrée les données de chaque pixel de l'image (position, coordonnées de texture, couleur) et renvoie la couleur de celui-ci.

Voici un exemple de fragment shader en Cg :

      float4 main	(float3 color: COLOR0,      		 float3 texCoords: TEXCOORD0,      		 uniform sampler2D texture)      {      	float3 texColor = tex2D(texture, texCoords).rgb;      	return float4(color * texColor, 1);      }      
Page générée en 0.096 seconde(s) - site hébergé chez Contabo
Ce site fait l'objet d'une déclaration à la CNIL sous le numéro de dossier 1037632
A propos - Informations légales
Version anglaise | Version allemande | Version espagnole | Version portugaise