Le pipeline programmable est assez proche du pipeline fixe, sauf que
les développeurs peuvent remplacer le mécanisme de traitement des
vertices par leurs propres programmes. L'avantage principal est une
énorme flexibilité au niveau des algorithmes de rendu, qui tendent de
nos jours à se rapprocher de ce qui est utilisé dans les films en
images de synthèse, même si les performances ne permettent pas de
réaliser la même chose en temps réel. A noter que les noms utilisés
pour les registres sont ceux utilisés par DirectX, bien que le
fonctionnement reste le même pour OpenGL.
Registres
Un vertex shader est composé de différents élements. D'abord, des
registres. Ces registres vont contenir des valeurs. Ils font 128 bits,
et stockent quatre valeurs. En fait, ils sont assez proches des
registres dédiés au SSE présents sur les processeurs de nos machines.
En effet, lorsque le vertex shader effectue des opérations sur ces
registres, elles sont effectuées en parallèle sur chaque groupe de 32
bits.
Ces registres ont pour rôle de contenir des valeurs sous forme de 4
nombres en virgule flottante. Dans le cas des coordonnées, chaque
composante ira à sa place, alors que dans le cas des couleurs, le rouge
correspondra à X, le vert à Y, le bleu à Z et la composante alpha à W.
Certains éléments plus importants (comme le poids du vertex) pourront
être répartis sur plusieurs registres. Il existe différents types de
registres, bien que leur fonctionnement soit identique.
Registre v0-v??

D'abord, il y a les registres qui contiennent les informations du
vertex à traiter et sont appelés les registres d'entrée. Ils vont donc
amener au vertex shader des informations telles que la position du
vertex, sa couleur diffuse et spéculaire, sa normale, etc.
Leur nombre est limité à 16, pour n'importe quelle version des vertex
shaders. Un nombre supérieur serait peu utile, et réduirait
probablement les performances (16 registres représentent déjà 256
bytes).
Registre r0-r?
Second type de registres, les r0-r? vont récupérer différentes valeurs
issues des opérations qui vont être effectuées par le vertex shader.
Ces registres sont appelés les registres temporaires. Ils peuvent
contenir plus ou moins n'importe quelle information.
Bien qu'initialement disponibles en un nombre plutôt limité (12 pour
les vertex shaders 1.0 et 2.0), par la suite un nombre variable fut
disponible (minimum 12 pour les vertex shaders 2.x et 3.0).
Registres c0-c?, i0-i?, b0-b?
Troisième type de registres : les registres constants. Ceux-ci
permettent de définir des valeurs qui ne vont pas changer d'un vertex à
l'autre, mais qui seront globales à l'exécution d'un seul et même
vertex shader. Ces constantes contiennent notamment les matrices
utilisées pour transformer la position des vertices (translation,
rotation, etc.), mais peuvent également contenir tout type d'information
utile au vertex shader (vitesse du vent, contraintes physiques, etc).
Ces registres ont la particularité d'exister en trois versions (excepté
pour les vertex shaders 1.0, qui ne disposent que des registres c??).
Ainsi, les registres c?? pourront contenir des nombres à virgule
flottante, le type de données le plus courant en 3D. Les registres i??
pourront contenir des nombres entiers. Les registres b??, quant à eux,
pourront contenir des valeurs booléennes (vrai ou faux).
Les registres c?? sont probablement les plus nombreux disponibles
(minimum 96 pour les vertex shaders 1.0, minimum 256 pour les vertex
shaders 2.0 et 3.0). Les registres i?? et b??, quant à eux, ne sont
disponibles qu'à partir des vertex shaders 2.0, et sont chacun au
nombre de 16.
Vertex shader de perturbation des vertices (nVIDIA)
Registres s0-s3
Uniquement disponibles dans les vertex shaders 3.0, ces registres
(appelés registres d'échantillonage) n'ont qu'une utilité : permettre à
l'unique nouvelle instruction des vertex shaders 3.0 d'accéder aux
données des textures. Ainsi, chaque registre représente une texture, et
la nouvelle instruction - texldl - peut récupérer les données provenant
de cette texture.
Ces registres ne sont présents qu'en 4 exemplaires, ce qui permet tout
de même d'accéder aux données de quatre textures différentes à partir
d'un vertex shader, alors que précédemment seuls les pixel shaders
pouvaient accéder aux textures.
Registres a0, aL, p0
Ces registres sont un peu spéciaux, et leur fonctionnalité est unique.
De plus, seul a0 est disponible dans toutes les versions des vertex
shaders : aL est apparu avec les vertex shaders 2.0, et p0 avec les
vertex shaders 2.x.
Mais commençons par a0. Il s'agit du registre d'adressage : pour faire
simple, au lieu d'accéder à un registre (r0 par exemple) directement,
le registre a0 va "pointer" vers r0, et on pourra y accéder
indirectement. Il est ainsi possible de choisir selon certaines
conditions un registre ou un autre, sans pour autant devoir doubler la
taille du vertex shader.
Ensuite, aL : le registre compteur de boucle. Il n'existe qu'à partir
des vertex shaders 2.0 parce que les boucles (la possibilité de répéter
des opérations) n'ont été disponibles qu'à partir de cette version. Il
s'agit d'une simple valeur entière qui augmente à chaque itération de
la boucle.
Vient enfin p0, le registre attribut. Il est utilisé avec les
instructions permettant de faire des branchements conditionnels, tels
que "si plus grand que", "si plus petit que" ou "si égal à". Il peut
ensuite être utilisé pour avoir plus de contrôle sur les instructions
traditionnelles.