En esta página

Qt Shader Tools Integración del sistema de compilación

Compila shaders y los añade a un recurso Qt

Introducción

El módulo Qt Shader Tools proporciona un archivo de macros CMake que proporciona funciones útiles que las aplicaciones pueden utilizar en su CMakeLists.txt.

Al utilizar la función qt6_add_shaders, la herramienta qsb será invocada automáticamente por el sistema de compilación, y los archivos .qsb resultantes se añadirán implícitamente al sistema de recursos.

Primer ejemplo

Veamos un ejemplo sencillo. Supongamos que tenemos una aplicación Qt Quick que quiere proporcionar su propio efecto de bamboleo a través de ShaderEffect. El fragment shader está implementado en wobble.frag. La propiedad fragmentShader del elemento ShaderEffect hace referencia a wobble.frag.qsb. ¿Cómo nos aseguramos de que este archivo .qsb se genera en tiempo de compilación?

...
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"
)

Lo anterior es suficiente para permitir que la aplicación acceda a :/wobble.frag.qsb en tiempo de ejecución. El código fuente GLSL original estilo Vulkan (wobble.frag) no está incluido en el ejecutable de la aplicación y no necesita ser enviado. Si hay errores en el código del shader, los mensajes del compilador glslang se imprimen en tiempo de compilación y la compilación falla. Cuando se cambia el archivo fuente del sombreador, los cambios se recogen automáticamente en la siguiente compilación, como lo harían para C++ y otros archivos fuente.

La clave es la función qt6_add_shaders, que comparte similitudes con qt6_add_resources. Sin especificar más parámetros, la función llevará a ejecutar qsb con un conjunto razonable de argumentos por defecto que son adecuados para fragment shaders cuando se apunta a Vulkan, Metal, Direct 3D, y OpenGL u OpenGL ES.

Nota: Cuidado con la línea find_package. Es importante incluir find_package para ShaderTools, de lo contrario qt6_add_shaders no estará disponible.

Nota : El objetivo que se pasa como primer argumento de la función qt6_add_shaders debe existir antes de llamar a la función.

Nota : Se admiten múltiples llamadas a qt6_add_shaders. En aplicaciones complejas no es improbable que diferentes conjuntos de shaders necesiten diferentes ajustes. El nombre después del proyecto ("exampleapp_shaders" en el ejemplo anterior) tiene que ser único para cada llamada.

Configuración

Por defecto qt6_add_shaders invoca qsb de la siguiente manera:

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

Esto significa que el paquete resultante contendrá SPIR-V (para Vulkan 1.0), GLSL ES 100 (para OpenGL ES 2.0 y posteriores), GLSL 120 (para contextos OpenGL de perfil no básico), GLSL 150 (para contextos OpenGL de perfil básico), fuente HLSL para Shader Model 5.0 (para Direct3D 11.1), y fuente Metal Shading Language 1.2 (para Metal).

Este es un buen conjunto de valores por defecto para Qt Quick, y crea aplicaciones que son altamente portables a una amplia variedad de sistemas. Sin embargo, estos valores por defecto no siempre son adecuados. Si el sombreador utiliza funciones o construcciones que no tienen un equivalente en estos objetivos, el proceso, y por tanto la compilación, fallará. Si este es el caso, los objetivos tendrán que ser ajustados, y esto también significa que los requisitos mínimos del sistema de la aplicación se ajustan implícitamente. Como ejemplo, tomemos la función textureLod GLSL que sólo está disponible con OpenGL ES 3.0 y superior (lo que significa GLSL ES 300 o superior). Si se solicita GLSL 300 es en lugar de 100 es, la compilación tendrá éxito, pero la aplicación resultante requerirá ahora OpenGL ES 3.0 o superior y no será compatible con los sistemas basados en OpenGL ES 2.0.

En WebAssembly qt6_add_shaders invoca qsb de la siguiente manera:

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

Esto genera shaders compatibles con WebGL 1 y WebGL 2.

Tipo de shader

El tipo de shader se deduce de la extensión del fichero. Así, la extensión debe ser una de las siguientes

  • .vert - para sombreadores de vértices
  • .tesc - para shaders de control de teselación
  • .tese - para shaders de evaluación de teselación
  • .frag - para sombreadores de fragmentos (píxeles)
  • .comp - para sombreadores de cálculo

Nota: Los shaders de control y evaluación de teselación no son compatibles actualmente con Direct 3D (HLSL). Una posible solución es crear manualmente shaders de casco y dominio e inyectarlos mediante la sintaxis de subsitución de archivos de la sección FILES.

Objetivos

Están disponibles las siguientes palabras clave:

  • GLSL - Solicita generar código fuente para la lista dada de versiones GLSL. Vigila que la lista siga la sintaxis qsb separada por comas. Por ejemplo, un sombreador de cómputo querrá especificar "310 es,430" aquí ya que los valores por defecto no son adecuados para él.
  • NOGLSL - Esta palabra clave sin argumento desactiva la generación del código fuente GLSL. Adecuada para aplicaciones que no desean funcionar con OpenGL en absoluto.
  • HLSL - Solicita la generación de código fuente para la lista dada de versiones HLSL (shader model). La herramienta qsb sigue los números de versión del estilo GLSL y, por tanto, 50 corresponde a Shader Model 5.0, 51 es 5.1.
  • NOHLSL - Esta palabra clave sin argumento desactiva la generación del código fuente HLSL. Adecuada para aplicaciones que no desean funcionar con Direct 3D en absoluto.
  • MSL - Solicita la generación de código fuente para la versión dada de Metal Shading Language. 12 corresponde a 1.2, 20 a 2.0.
  • NOMSL - Esta palabra clave sin argumento desactiva la generación del código fuente MSL. Es adecuada para aplicaciones que no desean funcionar con Metal en absoluto.

El ajuste más comúnmente anulado es GLSL. Por ejemplo, si los sombreadores de la aplicación utilizan funciones de OpenGL 3.x, es probable que desee especificar algo superior a 100 es o 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
)

Nota: El espacio antes del sufijo es es opcional.

Teselación

  • TESSELLATION - Esta palabra clave sin argumento indica que los sombreadores se utilizan en un canal que utiliza teselación. Esto sólo es relevante cuando hay sombreadores de vértices en la lista y la generación de sombreadores Metal no está desactivada. Véase este fragmento para ver un ejemplo.

    Esta opción se introdujo en Qt 6.5.

  • TESSELLATION_VERTEX_COUNT - Esta opción toma un número que indica el recuento de vértices de salida de la etapa de control de teselación. Su especificación es obligatoria para los sombreadores de evaluación de teselación utilizados con Metal. El valor por defecto es 3. Si no coincide con la etapa de control de teselación, el código MSL generado no funcionará como se espera.

    Esta opción se introdujo en Qt 6.5.

  • TESSELLATION_MODE - Esta opción especifica el modo de teselado. Puede tomar uno de estos dos valores: "triangles" o "quads". El valor por defecto es triangles. La opción debe especificarse cuando hay un sombreador de control de teselación en la lista FILES. Debe coincidir con la etapa de evaluación de la teselación.

    Esta opción se introdujo en Qt 6.5.

Multivista

  • VIEW_COUNT - Esta opción especifica el número de vistas con las que se utiliza un sombreador de vértices. Cuando trabajes con multiview (GL_OVR_multiview2, VK_KHR_multiview, D3D12 view instancing, etc.), especifica siempre el VIEW_COUNT correcto con un valor >= 2 para los shaders relevantes para permitir la generación de código shader GLSL correcto. Tenga en cuenta, sin embargo, que la configuración de VIEW_COUNT debe evitarse para los sombreadores de vértices que no dependen de la vista múltiple, ya que la configuración del valor hace que el código GLSL generado dependa de la vista múltiple. Para superar esto, agrupa los sombreadores de vértices en múltiples llamadas qt_add_shaders(). Establecer VIEW_COUNT inyecta automáticamente una definición de preprocesador, QSHADER_VIEW_COUNT, con el mismo valor en el código fuente del sombreador. Además, la línea #extension GL_EXT_multiview : require se inyecta automáticamente en los sombreadores de vértices cuando se establece un recuento de vistas de 2 o superior. Tenga en cuenta que para multivista la versión GLSL mínima es 330 y 300 es. Para HLSL, la versión mínima es 61. Se aconseja a las aplicaciones que configuren los objetivos de lenguaje en consecuencia (o a versiones más recientes).

    Esta opción se introdujo en Qt 6.7.

  • MULTIVIEW - Solicita la generación de un conjunto de shaders no multivista y de un conjunto de shaders con recuento de vistas 2. Esto es efectivamente una conveniencia para crear manualmente dos llamadas qt_add_shaders() con los argumentos GLSL/HLSL/MSL/VIEW_COUNT apropiados. Esta opción está pensada principalmente para el propio uso de Qt, pero las aplicaciones pueden utilizarla también siempre que los ajustes implícitos para las variantes multivista sean suficientes para los sombreadores de la aplicación; estos son: GLSL 330,300es HLSL 61 MSL 12. VIEW_COUNT se establece en 2 para las variantes multivista. Las variantes multivista se almacenan en archivos a los que se añade el sufijo .mv2qsb (además de .qsb).

    Esta opción se introdujo en Qt 6.8.

Qt Quick especificaciones

  • BATCHABLE - Especificar esta palabra clave única y sin argumentos es esencial para los sombreadores de vértices que se utilizan con Qt Quick, ya sea en un ShaderEffect o en un QSGMaterialShader. No tiene ningún efecto para los sombreadores de fragmentos o de cálculo, y se pueden incluir con seguridad diferentes tipos en la misma lista, ya que la palabra clave sólo se tiene en cuenta para los archivos .vert. Equivale al argumento -b de qsb.
  • ZORDER_LOC - Cuando se especifica BATCHABLE, se inyecta una entrada de vértice adicional con la ubicación 7 por defecto. Esta palabra clave se utiliza para cambiar esta ubicación a otro valor. Esto es relevante si el sombreador de vértices tiene muchas entradas y 7 está en uso y podría chocar.

Invocación de herramientas externas

  • PRECOMPILE - Equivale a las opciones -c o -t de qsb, dependiendo de la plataforma. Cuando se compila en Windows, se invoca a fxc desde el SDK de Windows para realizar la primera fase de compilación (código fuente HLSL a bytecode DXBC) en tiempo de compilación en lugar de en tiempo de ejecución. El archivo .qsb resultante sólo incluirá los resultados de la compilación (el formato intermedio del shader), no el código fuente original del shader.
  • OPTIMIZED - Invoca a spirv-opt (que debe estar disponible en el SDK de Vulkan o en otro lugar) para realizar optimizaciones en el bytecode de SPIR-V. Equivale al argumento -O de qsb.

Otros ajustes

  • DEFINES - Define las macros que están activas durante la compilación de shaders. Equivalente al argumento -D de qsb. La lista tiene la forma de "name1=value1;name2=value2". Alternativamente, al igual que FILES, la lista puede ir separada por nuevas líneas.
  • OUTPUTS - Cuando el nombre del archivo .qsb generado tiene que ser diferente de la fuente, por ejemplo, porque un archivo shader sirve como fuente para múltiples archivos .qsb debido a la diferenciación a través de DEFINES, esta lista puede contener una entrada para cada elemento en FILES, especificando un nombre de archivo que normalmente termina en .qsb. El nombre especificado se pasa entonces en el argumento -o a qsb en lugar de simplemente añadir .qsb al nombre del archivo fuente.
  • ORIGINAL_FILES - Cuando el archivo .qsb debe depender de un archivo fuente shader que es diferente de FILES, especifique ORIGINAL_FILES y una entrada para cada elemento en FILES. Cuando está presente, cambia el comportamiento de dos maneras: Se pasa un argumento --orig-file a qsb, lo que lleva a escribir el nombre de archivo de ORGINAL_FILES en los archivos de dependencia de CMake en lugar del correspondiente nombre de archivo de entrada de FILES. Además, el add_custom_command() que activa la invocación de qsb pasará el nombre de archivo de ORIGINAL_FILES a su cláusula DEPENDS. Esto es útil cuando los archivos pasados a qt_add_shaders() son intermedios, generan activos, y los archivos .qsb finales deberían depender más bien de los archivos fuente originales de los shaders, de los que qt_add_shaders() no sabría nada sin ORIGINAL_FILES.
  • DEBUGINFO - Permite generar información de depuración completa para SPIR-V, permitiendo así que herramientas como RenderDoc muestren el código fuente completo al inspeccionar un pipeline o al realizar depuración de vértices o fragmentos. Equivale al argumento -g de qsb. También tiene efecto para Direct 3D en caso de que se haya especificado la palabra clave PRECOMPILE, ya que entonces se ordena a fxc que incluya información de depuración en el bytecode intermedio generado.
  • QUIET - Suprime la salida de depuración y advertencia de qsb. Sólo se imprimen los errores fatales.
  • OUTPUT_TARGETS - Al utilizar qt_add_shaders con bibliotecas estáticas, se generarán uno o más objetivos especiales. Si desea realizar un procesamiento adicional en estos objetivos pase un valor al parámetro OUTPUT_TARGETS.
  • MEDIUMP - Solicita por defecto precisión media para floats en fragment shaders GLSL ES. Ignorado para cualquier otro objetivo, incluyendo GLSL (no ES).

Sustitución de sombreadores hechos a mano

La integración con CMake también permite especificar sustitutos para determinadas versiones del sombreador en el archivo .qsb resultante. En efecto, esto equivale a ejecutar qsb con la opción de línea de comandos -r.

Esto se habilita mediante la siguiente sintaxis especial en la lista FILES:

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

El nombre del archivo puede ir seguido de cualquier número de especificaciones de sustitución separadas por @. Cada una de ellas especifica el lenguaje de sombreado, la versión y el archivo del que deben leerse los datos, separados por comas. Para más detalles, consulte el Manual QSB.

Ejemplo de teselación

Tomemos un pipeline gráfico que consta de cuatro etapas, la etapa de vértices con el shader vertex.vert, la etapa de control de teselación con el shader tess.tesc, la etapa de evaluación de teselación con el shader tess.tese, y la etapa de fragmentos con el shader fragment.frag.

Para construir una aplicación totalmente portable que sea capaz de funcionar con cualquiera de Vulkan, OpenGL, Metal y Direct 3D, hay dos cosas principales de las que ocuparse: Las versiones HLSL de los sombreadores de teselación deben crearse manualmente y luego inyectarse. Mientras que con Metal, hay que especificar la palabra clave adecuada.

En primer lugar, se enumeran los sombreadores de vértices y fragmentos. Para ser compatible con Metal, se añade la palabra clave TESSELLATION. Esto permite un procesamiento y traducción especiales para vertex.vert al generar el código del sombreador Metal. Para OpenGL, restringimos la versión del lenguaje GLSL, ya que el soporte de teselación sólo está disponible en las versiones más recientes de OpenGL.

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

En segundo lugar, los sombreadores de teselación se enumeran en una llamada qt6_add_shaders() independiente. Esto se debe a la palabra clave NOHLSL. Los sombreadores de vértices y fragmentos deben seguir traduciéndose a HLSL como de costumbre, por lo que mantener los cuatro sombreadores en una sola llamada qt6_add_shaders() no es factible. Para Metal, se especifican algunos ajustes de teselación (número de vértices de salida, modo), ya que será necesario conocerlos de antemano, a diferencia de Vulkan y 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"
)

Nota: La escritura manual de sombreadores HLSL de casco y dominio sólo se recomienda a usuarios avanzados. Ciertas construcciones, como los buffers constantes, necesitarán un cuidado especial para que todas las interfaces de recursos y diseños sigan siendo compatibles con los 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.