Sur cette page

Intégration du système de construction de Qt Shader Tools

Compile les shaders et les ajoute à une ressource Qt.

Introduction

Le module Qt Shader Tools fournit un fichier macro CMake qui propose des fonctions utiles que les applications peuvent utiliser dans leur CMakeLists.txt.

En utilisant la fonction qt6_add_shaders, l'outil qsb sera invoqué automatiquement par le système de construction, et les fichiers .qsb résultants seront ajoutés au système de ressources de manière implicite.

Premier exemple

Prenons un exemple simple. Supposons que nous ayons une application Qt Quick qui souhaite fournir son propre effet d'oscillation via ShaderEffect. Le fragment shader est implémenté dans wobble.frag. La propriété fragmentShader de l'élément ShaderEffect fait référence à wobble.frag.qsb. Comment s'assurer que ce fichier .qsb est généré au moment de la compilation ?

...
project(exampleapp LANGUAGES CXX)
...
find_package(Qt6 COMPONENTS ShaderTools)
...
qt6_add_executable(exampleapp
    main.cpp
)
...
qt6_add_resources(exampleapp "exampleapp"
    PREFIX
        "/"
    FILES
        "main.qml"
)

qt6_add_shaders(exampleapp "exampleapp_shaders"
    PREFIX
        "/"
    FILES
        "wobble.frag"
)

Ce qui précède est suffisant pour permettre à l'application d'accéder à :/wobble.frag.qsb au moment de l'exécution. Le code source GLSL original de style Vulkan (wobble.frag) n'est pas inclus dans l'exécutable de l'application et n'a pas besoin d'être livré. S'il y a des erreurs dans le code du shader, les messages du compilateur glslang sont affichés au moment de la compilation et celle-ci échoue. Lorsque l'on modifie le fichier source du shader, les changements sont automatiquement pris en compte lors de la prochaine compilation, comme c'est le cas pour le C++ et d'autres fichiers sources.

La clé est la fonction qt6_add_shaders, qui présente des similitudes avec qt6_add_resources. Sans spécifier d'autres paramètres, la fonction conduira à l'exécution de qsb avec un ensemble raisonnable d'arguments par défaut qui conviennent aux nuanceurs de fragments lorsqu'ils ciblent Vulkan, Metal, Direct 3D, et OpenGL ou OpenGL ES.

Note : Attention à la ligne find_package. Il est important d'inclure find_package pour ShaderTools, sinon qt6_add_shaders ne sera pas disponible.

Remarque : la cible transmise en tant que premier argument de la fonction qt6_add_shaders doit exister avant que la fonction ne soit appelée.

Remarque : Les appels multiples à qt6_add_shaders sont pris en charge. Dans les applications complexes, il n'est pas improbable que différents ensembles de shaders nécessitent des paramètres différents. Le nom du projet ("exampleapp_shaders" dans l'exemple ci-dessus) doit être unique pour chaque appel.

Configuration

Par défaut, qt6_add_shaders invoque qsb comme suit :

qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o <output>.qsb <input>

Cela signifie que le paquet résultant contiendra SPIR-V (pour Vulkan 1.0), GLSL ES 100 (pour OpenGL ES 2.0 et plus récent), GLSL 120 (pour les contextes OpenGL non core profile), GLSL 150 (pour les contextes OpenGL core profile), la source HLSL pour Shader Model 5.0 (pour Direct3D 11.1), et la source Metal Shading Language 1.2 (pour Metal).

Il s'agit d'un bon ensemble de valeurs par défaut pour Qt Quick, qui permet de créer des applications hautement portables sur une grande variété de systèmes. Ces valeurs par défaut ne conviennent cependant pas toujours. Si le shader utilise des fonctions ou des constructions qui n'ont pas d'équivalent dans ces cibles, le processus, et donc la construction, échouera. Dans ce cas, les cibles devront être ajustées, ce qui signifie également que les exigences minimales du système de l'application sont ajustées implicitement. Prenons l'exemple de la fonction GLSL textureLod qui n'est disponible qu'avec OpenGL ES 3.0 et plus (c'est-à-dire GLSL ES 300 ou plus). Si l'on demande la fonction GLSL 300 es au lieu de 100 es, la compilation réussira, mais l'application résultante nécessitera désormais OpenGL ES 3.0 ou plus et ne sera pas compatible avec les systèmes basés sur OpenGL ES 2.0.

Sur WebAssembly, qt6_add_shaders invoque qsb comme suit :

qsb --glsl "100 es, 300 es" <output>.qsb <input>

Cela génère des shaders compatibles avec WebGL 1 et WebGL 2.

Type de nuanceur

Le type de shader est déduit de l'extension du fichier. Ainsi, l'extension doit être l'une des suivantes :

  • .vert - pour les vertex shaders
  • .tesc - pour les shaders de contrôle de tessellation
  • .tese - pour les nuanceurs d'évaluation de tessellation
  • .frag - pour les nuanceurs de fragments (pixels)
  • .comp - pour les nuanceurs de calcul

Remarque : les shaders de contrôle et d'évaluation de la tessellation ne sont actuellement pas pris en charge par Direct 3D (HLSL). Une solution possible consiste à créer manuellement des shaders de coque et de domaine et à les injecter via la syntaxe de substitution de fichier dans la section FILES.

Cibles

Les mots-clés suivants sont disponibles :

  • GLSL - Demande la génération du code source pour la liste donnée des versions de GLSL. Veillez à ce que la liste respecte la syntaxe qsb séparée par des virgules. Par exemple, un compute shader devra spécifier "310 es,430" ici car les valeurs par défaut ne lui conviennent pas.
  • NOGLSL - Ce mot-clé sans argument désactive la génération des sources GLSL. Il convient aux applications qui ne souhaitent pas du tout fonctionner avec OpenGL.
  • HLSL - Demande la génération du code source pour la liste donnée des versions HLSL (modèle de shader). L'outil qsb suit les numéros de version de style GLSL et donc 50 correspond au Shader Model 5.0, 51 est 5.1.
  • NOHLSL - Ce mot-clé sans argument désactive la génération des sources HLSL. Il convient aux applications qui ne souhaitent pas du tout fonctionner avec Direct 3D.
  • MSL - Demande la génération du code source pour la version donnée du Metal Shading Language. 12 correspond à 1.2, 20 à 2.0.
  • NOMSL - Ce mot-clé sans argument désactive la génération du code source MSL. Il convient aux applications qui ne souhaitent pas du tout fonctionner avec Metal.

Le paramètre le plus souvent ignoré est GLSL. Par exemple, si les shaders de l'application utilisent des fonctionnalités OpenGL 3.x, il est probable qu'il faille spécifier quelque chose de plus élevé que 100 es ou 120:

qt_add_shaders(exampleapp "res_gl3shaders"
    GLSL "300es,330"
    PREFIX
        "/shaders"
    FILES
       shaders/ssao.vert
       shaders/ssao.frag
       shaders/skybox.vert
       shaders/skybox.frag
)

Remarque : l'espace précédant le suffixe es est facultatif.

Tessellation

  • TESSELLATION - Ce mot-clé sans argument indique que les shaders sont utilisés dans un pipeline qui utilise la tessellation. Ceci n'est pertinent que lorsque des vertex shaders sont listés et que la génération de Metal shaders n'est pas désactivée. Voir cet extrait pour un exemple.

    Cette option a été introduite dans Qt 6.5.

  • TESSELLATION_VERTEX_COUNT - Cette option prend un nombre qui indique le nombre de vertex en sortie de l'étape de contrôle de la tessellation. Cette option est obligatoire pour les shaders d'évaluation de tessellation utilisés avec Metal. La valeur par défaut est 3. Si elle ne correspond pas à l'étape de contrôle de la tessellation, le code MSL généré ne fonctionnera pas comme prévu.

    Cette option a été introduite dans Qt 6.5.

  • TESSELLATION_MODE - Cette option spécifie le mode de tessellation. Elle peut prendre l'une des deux valeurs suivantes : "triangles" ou "quads". La valeur par défaut est triangles. L'option doit être spécifiée lorsqu'un shader de contrôle de tessellation figure dans la liste FILES. Elle doit correspondre à l'étape d'évaluation de la tessellation.

    Cette option a été introduite dans Qt 6.5.

Multiview

  • VIEW_COUNT - Cette option spécifie le nombre de vues avec lesquelles un vertex shader est utilisé. Lorsque vous travaillez avec des vues multiples (GL_OVR_multiview2, VK_KHR_multiview, D3D12 view instancing, etc.), spécifiez toujours le VIEW_COUNT correct avec une valeur >= 2 pour les shaders concernés afin de permettre la génération d'un code de shader GLSL correct. Notez cependant qu'il faut éviter de définir VIEW_COUNT pour les vertex shaders qui ne reposent pas sur le multiview, car cette valeur rend le code GLSL généré dépendant du multiview. Pour y remédier, regroupez les vertex shaders en conséquence dans plusieurs appels à qt_add_shaders(). La définition de VIEW_COUNT injecte automatiquement une définition de préprocesseur, QSHADER_VIEW_COUNT, avec la même valeur dans le code source du shader. En outre, la ligne #extension GL_EXT_multiview : require est injectée automatiquement dans les nuanceurs de sommets lorsque le nombre de vues est égal ou supérieur à 2. Notez que pour le multiview, la version minimale de GLSL est 330 et 300 es. Pour HLSL, la version minimale est 61. Il est conseillé aux applications de configurer les cibles linguistiques en conséquence (ou d'utiliser des versions plus récentes).

    Cette option a été introduite dans Qt 6.7.

  • MULTIVIEW - Demande la génération d'un ensemble de shaders non-multivues et d 'un ensemble de shaders à 2 vues. C'est en fait une commodité pour créer manuellement deux appels à qt_add_shaders() avec les arguments GLSL/HLSL/MSL/VIEW_COUNT appropriés. Cette option est principalement destinée à l'usage propre de Qt, mais les applications peuvent également l'utiliser tant que les paramètres implicites pour les variantes multivues sont suffisants pour les shaders de l'application ; ce sont : GLSL 330 300es HLSL 61 MSL 12. VIEW_COUNT est fixé à 2 pour les variantes multivues. Les variantes multivues sont stockées dans des fichiers auxquels a été ajouté le suffixe .mv2qsb (en plus de .qsb).

    Cette option a été introduite dans Qt 6.8.

Qt Quick spécificités

  • BATCHABLE - La spécification de ce mot-clé unique, sans argument, est essentielle pour les nuanceurs de sommets utilisés avec Qt Quick, soit dans un fichier ShaderEffect, soit dans un fichier QSGMaterialShader. Il n'a aucun effet sur les nuanceurs de fragments ou de calculs, et différents types peuvent être inclus sans risque dans la même liste puisque le mot-clé n'est pris en compte que pour les fichiers .vert. Équivalent à l'argument -b de qsb.
  • ZORDER_LOC - Lorsque BATCHABLE est spécifié, une entrée vertex supplémentaire est injectée à l'emplacement 7 par défaut. Ce mot-clé est utilisé pour changer cet emplacement en une autre valeur. Cela peut s'avérer utile si le nuanceur de sommets possède de nombreuses entrées et que 7 d'entre elles sont utilisées et risquent d'entrer en conflit.

Invocation d'outils externes

  • PRECOMPILE - Équivalent aux options -c ou -t de qsb, selon la plate-forme. Lors de la compilation sous Windows, cela conduit à invoquer fxc du SDK Windows pour effectuer la première phase de compilation (source HLSL vers bytecode DXBC) au moment de la compilation plutôt qu'au moment de l'exécution. Le fichier .qsb qui en résulte n'inclura que les résultats de la compilation (le format intermédiaire des shaders), et non le code source original des shaders.
  • OPTIMIZED - Invoque spirv-opt (qui doit être disponible dans le SDK Vulkan ou ailleurs) pour effectuer des optimisations sur le bytecode SPIR-V. Équivalent à l'argument -O de qsb.

Autres paramètres

  • DEFINES - Définit les macros qui sont actives pendant la compilation des shaders. Équivalent à l'argument -D de qsb. La liste a la forme de "name1=value1;name2=value2" ou, comme FILES, elle peut être séparée par des nouvelles lignes.
  • OUTPUTS - Lorsque le nom du fichier .qsb généré doit être différent de celui de la source, par exemple parce qu'un fichier de shaders sert de source à plusieurs fichiers .qsb en raison de la différenciation via DEFINES, cette liste peut contenir une entrée pour chaque élément de FILES, spécifiant un nom de fichier se terminant généralement par .qsb. Le nom spécifié est alors transmis dans l'argument -o à qsb au lieu d'ajouter simplement .qsb au nom du fichier source.
  • ORIGINAL_FILES - Lorsque le fichier .qsb doit dépendre d'un fichier source de shaders différent de FILES, spécifiez ORIGINAL_FILES et une entrée pour chaque élément dans FILES. Lorsqu'il est présent, il modifie le comportement de deux manières : Un argument --orig-file est passé à qsb, ce qui conduit à écrire le nom de fichier de ORGINAL_FILES dans les fichiers de dépendance CMake au lieu du nom de fichier d'entrée correspondant de FILES. De plus, la commande add_custom_command() qui déclenche l'invocation de qsb passera le nom de fichier de ORIGINAL_FILES à sa clause DEPENDS. Ceci est utile lorsque les fichiers passés à qt_add_shaders() sont intermédiaires, génèrent des assets, et que les fichiers .qsb finaux devraient plutôt dépendre des fichiers sources de shaders originaux, dont qt_add_shaders() ne saurait rien sans ORIGINAL_FILES.
  • DEBUGINFO - Permet de générer des informations de débogage complètes pour SPIR-V, permettant ainsi à des outils comme RenderDoc d'afficher la source complète lors de l'inspection d'un pipeline ou lors du débogage des vertex ou des fragments. Équivalent à l'argument -g de qsb. A également un effet pour Direct 3D dans le cas où le mot-clé PRECOMPILE a été spécifié, car fxc est alors chargé d'inclure des informations de débogage dans le bytecode intermédiaire généré.
  • QUIET - Supprime la sortie de débogage et d'avertissement de qsb. Seules les erreurs fatales sont affichées.
  • OUTPUT_TARGETS - Lors de l'utilisation de qt_add_shaders avec des bibliothèques statiques, une ou plusieurs cibles spéciales seront générées. Si vous souhaitez effectuer un traitement supplémentaire sur ces cibles, passez une valeur au paramètre OUTPUT_TARGETS.
  • MEDIUMP - Demande une précision moyenne par défaut pour les flottants dans les nuanceurs de fragments GLSL ES. Ignoré pour toutes les autres cibles, y compris GLSL (non ES).

Substituer des shaders faits à la main

L'intégration de CMake permet également de spécifier des remplacements pour des versions données du nuanceur dans le fichier .qsb résultant. Cela équivaut en fait à exécuter qsb avec l'option de ligne de commande -r.

Cela est possible grâce à la syntaxe spéciale suivante dans la liste FILES :

FILES
    "shaders/externalsampler.frag@glsl,100es,shaders/externalsampler_gles.frag"

Le nom du fichier peut être suivi d'un nombre quelconque de spécifications de remplacement séparées par @. Chacune d'entre elles spécifie le langage d'ombrage, la version et le fichier à partir duquel les données doivent être lues, séparés par des virgules. Voir le manuel QSB pour plus de détails.

Exemple de tessellation

Prenons un pipeline graphique composé de quatre étapes : l'étape des sommets avec le shader vertex.vert, l'étape de contrôle de la tessellation avec le shader tess.tesc, l'étape d'évaluation de la tessellation avec le shader tess.tese, et l'étape des fragments avec le shader fragment.frag.

Pour créer une application entièrement portable capable de fonctionner avec Vulkan, OpenGL, Metal et Direct 3D, il y a deux éléments principaux à prendre en compte : Les versions HLSL des shaders de tessellation doivent être créées manuellement puis injectées. Alors qu'avec Metal, le mot-clé approprié doit être spécifié.

Tout d'abord, les nuanceurs de sommets et de fragments sont listés. Afin de prendre en charge Metal, le mot-clé TESSELLATION est ajouté. Cela permet un traitement spécial et une traduction pour vertex.vert lors de la génération du code du shader Metal. Pour OpenGL, nous limitons la version du langage GLSL car la prise en charge de la tessellation n'est disponible que dans les versions OpenGL les plus récentes.

qt6_add_shaders(project "shaders_tessellation_part1"
    PREFIX
        "/shaders"
    GLSL
        "410,320es"
    TESSELLATION
    FILES
        "vertex.vert"
        "fragment.frag"
)

Deuxièmement, les shaders de tessellation sont listés dans un appel qt6_add_shaders() séparé. Ceci est dû au mot-clé NOHLSL. Les vertex et fragment shaders doivent toujours être traduits en HLSL comme d'habitude, donc garder les quatre shaders dans un seul appel qt6_add_shaders() n'est pas faisable. Pour Metal, certains paramètres de tessellation (nombre de vertex de sortie, mode) sont spécifiés car ils devront être connus à l'avance, contrairement à Vulkan et OpenGL.

qt6_add_shaders(project "shaders_tessellation_part2"
    PREFIX
        "/shaders"
    NOHLSL
    GLSL
        "410,320es"
    TESSELLATION_VERTEX_COUNT
        3
    TESSELLATION_MODE
        "triangles"
    FILES
        "tess.tesc@hlsl,50,tess_hull.hlsl"
        "tess.tese@hlsl,50,tess_domain.hlsl"
)

Remarque : l 'écriture manuelle des shaders HLSL de coque et de domaine n'est recommandée qu'aux utilisateurs avancés. Certaines constructions, telles que les tampons constants, nécessiteront une attention particulière afin que toutes les interfaces de ressources et les dispositions restent compatibles avec les shaders SPIR-V/GLSL/MSL.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.