Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Introduction aux shaders

Cette page explique ce que sont les shaders et vous donnera un aperçu de leur fonctionnement dans Godot. Pour une référence détaillée du langage de shader du moteur, voir Langue de shading.

Les shaders sont un type particulier de programme qui fonctionne sur les unités de traitement graphique (GPU). Ils étaient initialement utilisés pour ombrer les scènes 3D mais peuvent aujourd'hui faire beaucoup plus. Vous pouvez les utiliser pour contrôler la façon dont le moteur dessine la géométrie et les pixels à l'écran, ce qui vous permet d'obtenir toutes sortes d'effets.

Les moteurs de rendu modernes comme Godot dessinent tout avec des shaders : les cartes graphiques peuvent exécuter des milliers d'instructions en parallèle, ce qui permet une vitesse de rendu incroyable.

Cependant, en raison de leur nature parallèle, les shaders ne traitent pas les informations comme le fait un programme classique. Le code du shader s'exécute sur chaque sommet ou pixel de manière isolée. Vous ne pouvez pas non plus stocker des données entre les images. Par conséquent, lorsque vous travaillez avec des shaders, vous devez coder et penser différemment des autres langages de programmation.

Suppose you want to update all the pixels in a texture to a given color. In GDScript, your code would use for loops:

for x in range(width):
    for y in range(height):
        set_color(x, y, some_color)

Votre code fait déjà partie d'une boucle dans un shader, donc le code correspondant ressemblerait à ceci.

void fragment() {
    COLOR = some_color;
}

Note

La carte graphique appelle la fonction fragment() une fois ou plus pour chaque pixel qu'elle doit dessiner. Nous y reviendrons plus loin.

Shaders dans Godot

Godot fournit un langage de shader basé sur le populaire langage de shader OpenGL (GLSL), mais simplifié. Le moteur gère une partie du travail d'initialisation de bas niveau pour vous, ce qui facilite l'écriture de shaders complexes.

Dans Godot, les shaders sont faits de fonctions principales appelées "fonctions de traitement". Ces fonctions de traitement sont les points d'entré de vos shaders dans le processus. Il y a sept fonctions de traitement différentes.

  1. La fonction vertex() s'exécute sur tous les sommets du maillage et définit leurs positions ainsi que d'autres attributs propres aux sommets. Utilisée dans les shaders canvas_item et spatiaux.

  2. La fonction fragment() s'exécute sur chaque pixel couvert par le maillage. Elle utilise les valeurs de sorties de la fonction vertex(), interpolées entre les sommets. Utilisée dans les shader canvas_item et spatiaux.

  3. La fonction light() s'exécute sur chaque pixel et sur chaque lumière. Elle prend des variables de la fonction fragment() et de ses exécutions précédentes. Utilisée dans les shaders canvas_item et spatiaux.

  4. La fonction start() s'exécute pour chaque particule dans un système de particules une fois que la particule est créée. Utilisé dans les shaders de particule.

  5. La fonction process() s'exécute pour chaque particule dans un système de particules à chaque trame. Utilisé dans les shaders de particule.

  6. La fonction sky() s'exécute pour chaque pixel dans la cubemap de radiance lorsque la cubemap de radiance doit être mise à jour, et pour chaque pixel sur l'écran actuel. Utilisé dans les shaders de ciel.

  7. La fonction fog() s'exécute pour chaque froxel dans le buffer de froxel du brouillard volumétrique qui intersecte avec le FogVolume. Utilisé par shaders de brouillard.

Avertissement

La fonction light() ne sera pas exécutée si le mode de rendu vertex_lighting est activé, ou si Rendering > Quality > Shading > Force Vertex Shading est activé dans les paramètres du projet. C'est activée par défaut sur les plateformes mobiles.

Note

Godot expose également une API pour que les utilisateurs puisse écrire des shaders de calcul totalement personnalisés. Pour plus d'informations, voir Utiliser les shaders de calcul.

Types de shader

Au lieu de fournir une configuration générale pour tous les usages (2D, 3D, particules, ciel, brouillard), vous devez spécifier le type de shader que vous écrivez. Différents types supportent différents modes de rendu, variables intégrées et fonctions de traitement.

Dans Godot, tous les shaders doivent spécifier leur type dans la première ligne, comme ceci :

shader_type spatial;

Voici les types disponibles :

Mode de rendu

Les shaders ont des modes de rendu optionnels que vous pouvez spécifier sur la deuxième ligne, après le type de shader, comme suit :

shader_type spatial;
render_mode unshaded, cull_disabled;

Les modes de rendu modifient la façon dont Godot applique le shader. Par exemple, le mode unshaded fait ignorer au moteur la fonction intégrée de processeur de lumière.

Chaque type de shader possède différents modes de rendu. Consultez la référence de chaque type de shader pour obtenir une liste complète des modes de rendu.

Processeur de sommet

The vertex() processing function is called once for every vertex in spatial and canvas_item shaders.

Chaque sommet de la géométrie de votre monde possède des propriétés telles qu'une position et une couleur. Cette fonction modifie ces valeurs et les transmet à la fonction fragment. Vous pouvez également l'utiliser pour envoyer des données supplémentaires à la fonction fragment en utilisant des varyings.

Par défaut, Godot transforme vos informations de vertex pour vous, ce qui est nécessaire pour projeter la géométrie sur l'écran. Vous pouvez utiliser les modes de rendu pour transformer les données vous-même ; voir le Spatial shader doc pour un exemple.

Processeur de fragments

The fragment() processing function is used to set up the Godot material parameters per pixel. This code runs on every visible pixel the object or primitive draws. It is only available in spatial and canvas_item shaders.

L'utilisation standard de la fonction de fragment consiste à définir les propriétés des matériaux qui seront utilisées pour calculer l'éclairage. Par exemple, vous pouvez définir des valeurs pour ROUGHNESS, RIM, ou TRANSMISSION qui indiquent à la fonction de lumière comment les lumières réagissent à ce fragment. Cela permet de contrôler un pipeline de shading complexe sans que l'utilisateur n'ait à écrire beaucoup de code. Si vous n'avez pas besoin de cette fonctionnalité intégrée, vous pouvez l'ignorer et écrire votre propre fonction de traitement de la lumière et Godot l'optimisera. Par exemple, si vous n'écrivez pas de valeur à RIM, Godot ne calculera pas l'éclairage rim. Lors de la compilation, Godot vérifie si RIM est utilisé ; si ce n'est pas le cas, il coupe tout le code correspondant. Par conséquent, vous ne gaspillerez pas les calculs sur des effets que vous n'utilisez pas.

Processeur de lumière

Le traitement light() fonctionne également par pixel, et il s'exécute une fois pour chaque lumière qui affecte l'objet. Il ne s'exécute pas si aucune lumière n'affecte l'objet. Il existe sous la forme d'une fonction appelée à l'intérieur du traitement fragment() et opère généralement sur les propriétés du matériau configurées à l'intérieur de la fonction fragment().

Le traitement light() fonctionne différemment en 2D et en 3D ; pour une description du fonctionnement de chacun, consultez leur documentation, CanvasItem shaders et Spatial shaders, respectivement.