Shader : qu'est-ce que c'est, types de shaders et comment ils fonctionnent

Auteur : IT Sectr Publié le : 2026-06-11 Temps de lecture : 8 min

Shader est un programme exécuté sur le GPU pour traiter des données graphiques : sommets, fragments ou tâches de calcul. Contrairement au code classique sur CPU, le shader fonctionne en parallèle sur des centaines de cœurs, traitant chaque élément indépendamment. Selon le Khronos Group (2025), les shaders sont utilisés dans 100% des applications 3D modernes — des jeux mobiles aux effets d'interface dans les applications système. Les développeurs écrivent des shaders dans des langages spécialisés : GLSL, HLSL, Metal Shading Language ou SPIR-V.

Points clés

  • Shader est un programme pour GPU exécuté en parallèle sur des centaines de cœurs pour chaque élément de la scène.
  • Types de shaders : vertex, fragment, compute, geometry, tessellation et mesh shaders.
  • Langages : GLSL (OpenGL), HLSL (DirectX), MSL (Metal), SPIR-V (Vulkan) — tous compilés en code machine GPU.
  • Shaders dans le développement mobile sont utilisés pour les effets, le post-traitement, l'éclairage et les calculs.
  • Optimisation des shaders : précision mediump, minimisation des branchements et ATF (Adaptive Texture Fetch) pour les GPU mobiles.

Qu'est-ce qu'un Shader ?

Shader est un petit programme écrit dans un langage spécialisé et exécuté sur le GPU. Chaque shader traite un élément de données — sommet, fragment (pixel) ou élément de travail — indépendamment des autres. Le parallélisme du GPU permet d'exécuter des milliers d'instances de shader simultanément.

Le terme a été introduit par Pixar dans les années 1980 pour décrire les programmes contrôlant l'apparence des surfaces dans RenderMan. En temps réel, les shaders sont apparus avec la NVIDIA GeForce 3 (2001) — la première carte graphique avec pipeline programmable. Avant les shaders, les graphiques étaient configurés par des paramètres fixes : couleur, texture, mode de mélange.

Selon Unity Technologies (2025), un jeu mobile moyen utilise 50 à 200 shaders. Chaque shader possède des variantes pour différentes plateformes, niveaux de qualité et configurations d'éclairage. Le nombre de variantes peut atteindre 10 000 par projet.

L'architecture d'un shader se divise en données d'entrée (attributs, variables uniform, textures), code du programme et données de sortie (couleur, position). Les variables uniform sont définies par le CPU avant l'exécution du shader et restent inchangées pour tous les éléments de l'image. Les attributs sont des données par élément (coordonnées du sommet, normale, coordonnées UV).

Modèle d'exécution SIMT

SIMT (Single Instruction, Multiple Threads) est le modèle d'exécution des shaders sur le GPU. Une instruction est chargée une fois et exécutée par des centaines de threads sur des données différentes. Par exemple, un Fragment Shader pour 1000 pixels exécute 1000 threads avec le même code, mais chaque thread reçoit ses propres coordonnées UV et attributs interpolés.

Une conséquence importante du SIMT : les branchements dans les shaders sont coûteux. Si dans un bloc if la moitié des threads suit une branche et l'autre moitié une autre, le GPU exécute les deux branches séquentiellement pour tous les threads. Les performances chutent à 50%. Évitez les branchements dynamiques dans les shaders ou minimisez-les par des calculs préalables sur le CPU.

Types de shaders

Les GPU modernes prennent en charge plusieurs types de shaders, chacun pour son étape du pipeline graphique ou de calcul. Examinons les principaux types : vertex, fragment, compute et les modernes mesh shaders.

Type de shaderÉtape du pipelineTraiteLangage
Vertex ShaderVertexChaque sommetGLSL, HLSL
Fragment ShaderFragmentChaque pixelGLSL, HLSL
Compute ShaderComputeDonnées arbitrairesGLSL, HLSL
Geometry ShaderGéométriePrimitivesGLSL, HLSL
Tessellation ShaderTessellationPatchesGLSL, HLSL
Mesh ShaderPipeline meshTask + MeshHLSL, MSL

Vertex Shader

Vertex Shader traite chaque sommet de la géométrie : transforme les coordonnées, calcule l'éclairage, transmet les données au fragment shader. C'est une étape obligatoire du pipeline graphique — sans elle, les sommets n'atteignent pas l'écran. Le Vertex Shader est appelé pour chaque sommet de chaque image.

Fragment Shader

Fragment Shader (ou Pixel Shader) est l'étape la plus gourmande en ressources. Il calcule la couleur finale de chaque fragment en utilisant les textures, l'éclairage et le matériau. Le Fragment Shader est exécuté pour chaque pixel couvert par la géométrie, en tenant compte de toutes les textures et effets appliqués. L'optimisation de ce shader offre le plus grand gain de performances.

Compute Shader

Compute Shader est un shader universel pour des calculs arbitraires sur le GPU. Contrairement aux shaders graphiques, il n'est pas lié à la géométrie ou aux pixels. Le Compute Shader travaille avec des tampons de données arbitraires via des groupes de travail. Il est utilisé pour la physique, la simulation de particules, les post-effets et l'inférence de réseaux de neurones.

Mesh Shader

Mesh Shader est le type de shader le plus récent, apparu avec NVIDIA Turing (2018) et Metal 3. Le Mesh Shader remplace les shaders vertex, geometry et tessellation par un seul pipeline mesh. Il fonctionne avec le Task Shader : le Task Shader décide quels groupes mesh rendre, et le Mesh Shader génère la géométrie à la volée.

Langages pour écrire des shaders

Les shaders sont écrits dans des langages spécialisés qui sont compilés en code machine GPU. Le choix du langage dépend de la plateforme et de l'API. Examinons les principaux langages : GLSL, HLSL, Metal Shading Language et le format intermédiaire SPIR-V.

GLSL (OpenGL Shading Language)

GLSL est le langage de shaders pour OpenGL, OpenGL ES et WebGL. La syntaxe est basée sur le C avec l'ajout de types vectoriels (vec2, vec4, mat4) et de fonctions intégrées (texture, normalize, reflect). GLSL ES est la version pour les appareils mobiles avec une précision limitée (lowp, mediump, highp). Selon Khronos (2025), GLSL reste le langage de shaders le plus répandu grâce à sa nature multiplateforme.

glsl
#version 300 es
precision mediump float;
in vec2 v_texCoord;
uniform sampler2D u_texture;
out vec4 fragColor;

void main() {
    fragColor = texture(u_texture, v_texCoord);
}

Un fragment shader simple lit la couleur de la texture à partir des coordonnées UV. precision mediump indique au GPU d'utiliser la demi-précision pour float — accélère l'exécution sur les appareils mobiles de 25 à 40%.

HLSL (High-Level Shader Language)

HLSL est le langage de shaders de Microsoft pour DirectX. La syntaxe est plus proche du C++ avec le support des classes, structures et templates. HLSL est utilisé dans les applications Windows et, via Shader Model 6.7+, prend en charge le Ray Tracing, les Mesh Shaders et le Sampler Feedback. Pour le développement mobile, HLSL n'est pas utilisé directement, mais il est compilé en SPIR-V pour Vulkan.

Metal Shading Language

MSL (Metal Shading Language) est le langage de shaders d'Apple, basé sur C++14. Contrairement à GLSL et HLSL, MSL est compilé avec l'application, éliminant la compilation JIT sur l'appareil. MSL prend en charge les pointeurs, les templates et la bibliothèque standard C++. Il est utilisé sur tous les appareils Apple : iPhone, iPad, Mac, Apple TV.

cpp
#include <metal_stdlib>
using namespace metal;
struct VertexOut {
    float4 position [[position]];
    float2 texCoord;
};

fragment float4
myFragment(VertexOut in [[stage_in]],
            texture2d<float> tex [[texture(0)]]) {
    constexpr sampler s = sampler(filter::linear);
    return tex.sample(s, in.texCoord);
}

MSL utilise les attributs [[position]], [[stage_in]] et [[texture(N)]] pour la liaison des ressources. Le compilateur Apple génère du code optimisé pour le GPU actuel, en tenant compte du nombre de registres et du cache.

SPIR-V

SPIR-V est un format binaire intermédiaire de shaders, standard pour Vulkan. Les shaders sont écrits en GLSL ou HLSL, compilés en SPIR-V et chargés dans l'application Vulkan. SPIR-V n'est lié à aucun langage spécifique — il existe des compilateurs de Rust, Python, OpenCL C vers SPIR-V.

Shaders dans le développement mobile

Les shaders sur les plateformes mobiles ont des limitations par rapport au desktop : moins de registres, précision limitée et absence de support pour certaines instructions. Examinons les spécificités des shaders sur Android (Vulkan/OpenGL ES) et iOS (Metal).

Shaders sur Android

Android utilise GLSL ES pour OpenGL et SPIR-V pour Vulkan. OpenGL ES 3.2 prend en charge les shaders avec mediump par défaut. Vulkan nécessite une compilation explicite de GLSL en SPIR-V via glslangValidator. Sur Android, les shaders sont chargés à partir de ressources chaîne ou de fichiers SPIR-V compilés.

Qualcomm Adreno optimise les shaders au niveau du pilote. Recommandations : utilisez mediump pour la couleur et les UV, highp uniquement pour les positions ; évitez les échantillonnages de texture dans les vertex shaders ; regroupez les calculs en vecteurs (vec4 au lieu de 4x float). Selon Qualcomm (2025), ces optimisations offrent un gain de 30 à 50%.

Shaders sur iOS

iOS utilise exclusivement Metal Shading Language. Les shaders sont compilés en code machine avec l'application via Xcode. Metal fournit Shader Debugger et GPU Capture pour le profilage des shaders. Le GPU Apple (TBDR) a des optimisations spécifiques : early fragment test, render targets sans mémoire et blending programmable.

Selon l'Apple WWDC 2024, pour les shaders iOS, il est critique d'utiliser half au lieu de float, de limiter la pression sur les registres (max 64 registres) et d'éviter les échantillonnages de texture dépendants. Les shaders iOS doivent être compacts — taille optimale de 50 à 100 instructions ALU.

Shaders dans Unity et Unreal Engine

Les moteurs de jeu Unity et Unreal Engine fournissent des éditeurs visuels de shaders (Shader Graph, Material Editor) et des langages abstraits (ShaderLab, USF). Le développeur écrit le shader dans un langage de haut niveau, et le moteur compile pour la plateforme cible. Unity utilise HLSL comme langage intermédiaire, Unreal utilise USF (Unreal Shader Format).

Optimisation des shaders

L'optimisation des shaders est une étape clé du développement graphique pour les appareils mobiles. Un shader mal écrit peut faire chuter le FPS de 60 à 20. Examinons les principales règles et techniques d'optimisation.

Précision des calculs

Utilisez la précision minimale suffisante : lowp pour la couleur et les UV, mediump pour les normales et l'éclairage, highp uniquement pour les positions et les matrices. Selon ARM (2025), les opérations mediump sont 2 fois plus rapides que highp sur les GPU Mali. Dans GLSL ES, cela se définit via des qualificateurs de précision.

Minimisation des échantillonnages de texture

Les échantillonnages de texture sont l'opération la plus coûteuse dans un shader (10 à 30 cycles contre 1 à 2 pour une instruction ALU). Réduisez le nombre d'échantillonnages : combinez les textures en atlas, stockez les données dans des tableaux uniform au lieu de textures, mettez en cache les résultats des pixels voisins via des instructions de dérivée.

Évitez les branchements

Les branchements dynamiques (if avec variable uniform) réduisent les performances du pipeline SIMT. Remplacez les branchements par des fonctions mathématiques : mix(), step(), smoothstep() et clamp(). Ces fonctions s'exécutent en 1 à 2 instructions, alors qu'un branchement peut coûter 8 à 16 instructions en raison de la divergence des threads.

glsl
// Mauvais : branchement dynamique dans le shader
if (u_enableLight) {
    color *= computeLighting(normal);
}

// Bon : remplacement mathématique de branchement
color *= mix(1.0, computeLighting(normal),
              float(u_enableLight));

mix() effectue une interpolation linéaire entre deux valeurs. Quand u_enableLight=0, il retourne 1.0 — la couleur ne change pas. Quand u_enableLight=1, il retourne le résultat de l'éclairage. Pas de branchement — tous les threads exécutent le même code.

Exemples de shaders

Examinons des exemples pratiques de shaders pour le développement mobile — de l'ombrage simple à la génération procédurale de textures. Chaque exemple démontre une technique spécifique.

Ombrage Phong (vertex shader)

Le modèle Phong est le modèle d'éclairage classique avec des composantes diffuse et spéculaire. Le Vertex Shader calcule l'éclairage pour chaque sommet, le Fragment Shader n'interpole que le résultat (Gouraud shading). Adapté aux appareils mobiles grâce à son faible coût.

glsl
#version 300 es
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_normal;
uniform mat4 u_mvp;
uniform mat4 u_modelView;
out vec3 v_color;

void main() {
    vec3 normal = normalize(mat3(u_modelView) * a_normal);
    vec3 lightDir = normalize(vec3(0.0, 1.0, 1.0));
    float diff = max(dot(normal, lightDir), 0.0);
    v_color = vec3(0.8, 0.2, 0.2) * (0.3 + diff * 0.7);
    gl_Position = u_mvp * a_position;
}

Le shader calcule l'éclairage diffus : produit scalaire de la normale avec la direction de la lumière. Le résultat est mélangé avec les composantes ambiante (0.3) et diffuse (0.7). Exécute 10 à 15 instructions ALU par sommet — acceptable pour 100 000 polygones à 60 FPS sur un GPU mobile.

Texture procédurale (fragment shader)

Les textures procédurales sont générées dans le Fragment Shader sans chargement depuis un fichier. Économise la mémoire vidéo et simplifie l'animation. Exemple — un damier avec une taille de cellule ajustable. Seulement quelques instructions ALU — charge minimale sur le GPU.

glsl
#version 300 es
precision mediump float;
in vec2 v_uv;
uniform float u_cells;
out vec4 fragColor;

void main() {
    vec2 cell = floor(v_uv * u_cells);
    float isWhite = mod(cell.x + cell.y, 2.0);
    fragColor = mix(vec4(0.1, 0.1, 0.1, 1.0),
                     vec4(0.9, 0.9, 0.9, 1.0),
                     isWhite);
}

8 instructions ALU — un shader idéal pour les appareils mobiles. u_cells définit le nombre de cellules par axe. floor et mod sont des opérations peu coûteuses, exécutées en 1 cycle sur tous les GPU mobiles.

Questions fréquentes

Quelle est la différence entre un shader et un programme C++ classique ?

Shader est exécuté sur le GPU en mode SIMT — une instruction pour des centaines de threads. Un programme C++ classique s'exécute sur le CPU en mode MIMD. Le shader n'a pas accès au système de fichiers, aux E/S ou à la mémoire dynamique. Il reçoit des données via des tampons et des textures et retourne une position ou une couleur.

Quel langage de shaders apprendre pour le développement mobile ?

GLSL — pour OpenGL ES et WebGL, multiplateforme. Metal Shading Language — pour iOS. HLSL — base pour Unity et Unreal Engine. Commencez par GLSL — la compréhension des fondamentaux est transférable à tout langage de shaders.

Pourquoi les shaders sont-ils lents sur les appareils mobiles ?

Principales causes : haute précision (highp au lieu de mediump), échantillonnages excessifs de texture, branchements dynamiques et dépassement de la limite de registres. Utilisez RenderDoc ou Xcode GPU Frame Debugger pour l'analyse des shaders.

Qu'est-ce qu'un compute shader et à quoi sert-il ?

Compute Shader est un shader pour des calculs arbitraires sur le GPU : physique des particules, traitement d'image, simulation de tissus. Contrairement au Fragment Shader, il n'est pas lié aux pixels et peut écrire dans des tampons arbitraires.

Peut-on écrire des shaders sans connaître de langage de programmation ?

Oui, via des éditeurs visuels : Shader Graph dans Unity, Material Editor dans Unreal Engine ou Metal Shader Converter. Ils génèrent du code shader à partir d'un schéma de nœuds. Pour une optimisation approfondie, une compréhension du langage shader est nécessaire.

Résumé

  • Shader est un programme parallèle pour GPU qui traite en masse des sommets, fragments ou données arbitraires.
  • Types de shaders : Vertex, Fragment, Compute, Geometry, Tessellation et Mesh — chacun responsable de son étape du pipeline.
  • Langages : GLSL (OpenGL), HLSL (DirectX), MSL (Metal), SPIR-V (Vulkan) — compilés en code machine GPU.
  • Spécificité mobile : précision mediump, minimum d'échantillonnages de texture, absence de branchements dynamiques.
  • Optimisation : mix() au lieu de if, précision half, ATF, combinaison de textures en atlas et calculs préalables sur CPU.
  • Applications : éclairage Phong, textures procédurales, post-effets, physique des particules et effets d'interface.
  • Outils : RenderDoc, Xcode GPU Debugger, Qualcomm Adreno Profiler et Mali Offline Compiler pour l'analyse de shaders.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi