Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

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.

Supposons que vous vouliez mettre à jour tous les pixels d'une texture à une couleur donnée. En GDScript, votre code utiliserait des boucles for :

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.

In Godot, shaders are made up of main functions called "processor functions". Processor functions are the entry point for your shader into the program. There are seven different processor functions.

  1. The vertex() function runs over all the vertices in the mesh and sets their positions and some other per-vertex variables. Used in canvas_item shaders and spatial shaders.

  2. The fragment() function runs for every pixel covered by the mesh. It uses values output by the vertex() function, interpolated between the vertices. Used in canvas_item shaders and spatial shaders.

  3. The light() function runs for every pixel and for every light. It takes variables from the fragment() function and from its previous runs. Used in canvas_item shaders and spatial shaders.

  4. The start() function runs for every particle in a particle system once when the particle is first spawned. Used in particles shaders.

  5. The process() function runs for every particle in a particle system for each frame. Used in particles shaders.

  6. The sky() function runs for every pixel in the radiance cubemap when the radiance cubemap needs to be updated, and for every pixel on the current screen. Used in sky shaders.

  7. The fog() function runs for every froxel in the volumetric fog froxel buffer that intersects with the FogVolume. Used by fog shaders.

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 also exposes an API for users to write totally custom GLSL shaders. For more information see Using compute shaders.

Types de shader

Instead of supplying a general-purpose configuration for all uses (2D, 3D, particles, sky, fog), you must specify the type of shader you're writing. Different types support different render modes, built-in variables, and processing functions.

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

La fonction de traitement vertex() est appelée une fois pour chaque vertex dans les shaders spatial et canvas_item. Pour les shaders particles, elle est appelé une fois pour chaque particule.

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, canvas_item, and sky 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.