本页内容

qt_add_shaders

编译着色器并将它们添加到 Qt 资源中。

该命令定义在Qt6 软件包的ShaderTools 组件中,可通过以下方式加载:

find_package(Qt6 REQUIRED COMPONENTS ShaderTools)

语法

qt_add_shaders(<target> <resource_name>
               PREFIX <path>
               FILES <file,...>
               [BASE <path>]
               [GLSL <version,...>]
               [NOGLSL]
               [HLSL <version,...>]
               [NOHLSL]
               [MSL <version,...>]
               [NOMSL]
               [BATCHABLE]
               [ZORDER_LOC <number>]
               [PERTARGETCOMPILE]
               [TESSELLATION]
               [TESSELLATION_VERTEX_COUNT <count>]
               [TESSELLATION_MODE <mode>]
               [VIEW_COUNT <count>]
               [MULTIVIEW]
               [PRECOMPILE]
               [OPTIMIZED]
               [DEBUGINFO]
               [QUIET]
               [DEFINES <name=value,...>]
               [OUTPUTS <file,...>]
               [ORIGINAL_FILES <file,...>]
               [OUTPUT_TARGETS <variable>]
               [MEDIUMP])

如果禁用了无版本号的命令,请改用 `qt6_add_shaders() `。它支持与本命令相同的参数集。

描述

在构建时,针对 `FILES` 中列出的每个着色器源文件调用qsb工具,并将生成的 `.qsb ` 文件添加到 Qt 资源系统中,资源前缀由 `PREFIX` 指定。

生成的资源命名为resource_name ,与qt_add_resources() 的命名方式相同。

默认情况下,qt_add_shaders 会按以下方式调用qsb :

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

这将生成一个包含 SPIR-V(适用于 Vulkan 1.0)、GLSL ES 100(适用于 OpenGL ES 2.0 及更高版本)、GLSL 120(适用于非核心配置的 OpenGL)、GLSL 150(适用于核心配置的 OpenGL)、 适用于着色器模型 5.0(Direct3D 11.1)的 HLSL,以及 Metal 着色语言 1.2(Metal)。

在 WebAssembly 环境中,默认设置变为:

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

这将生成与 WebGL 1 和 WebGL 2 兼容的着色器。

原始着色器源文件不会嵌入到应用程序的可执行文件中,也无需随应用程序发布。glslang 编译器产生的构建错误会在构建时报告,并导致构建失败。与其他源文件一样,对着色器源文件的修改会在下次构建时自动被识别。

注意: 作为第一个参数传递的 target 必须在调用qt_add_shaders 之前就已经存在。

注意: 支持多次 调用qt_add_shaders 。对于同一目标,每次调用resource_name 时,其参数必须是唯一的。

着色器类型

着色器的类型由文件扩展名推断得出:

  • .vert — 顶点着色器
  • .tesc — 细分控制着色器
  • .tese — 细分评估着色器
  • .geom — 几何着色器
  • .frag — 片段(像素)着色器
  • .comp — 计算着色器

注意: Direct 3D(HLSL)目前不支持细分 控制着色器和细分 评估着色器。一种可能的解决方法是手动创建外壳着色器和域着色器,并通过FILES 中的文件替换语法将其注入。

目标语言选项

  • GLSL — 针对给定的以逗号分隔的版本列表请求 GLSL 源代码。例如,计算着色器通常需要"310 es,430" 而不是默认设置。es 后缀前的空格是可选的。
  • NOGLSL — 禁用 GLSL 源代码生成。适用于完全不以 OpenGL 为目标的应用程序。
  • HLSL — 请求为给定的着色器模型版本列表生成 HLSL 源代码。qsb 采用 GLSL 风格的编号方式:50 对应着色器模型 5.0,51 对应 5.1。
  • NOHLSL — 禁用 HLSL 源代码生成。适用于完全不以 Direct 3D 为目标的应用程序。
  • MSL — 请求指定版本的 Metal 着色语言源代码。12 对应 MSL 1.2,20 对应 2.0。
  • NOMSL — 禁用 MSL 源代码生成。适用于完全不针对 Metal 的应用程序。

示例 — 对于使用 OpenGL 3.x 功能的着色器,提高 GLSL 版本:

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

注意: es 后缀前的空格 可选。

Qt Quick 选项

  • BATCHABLE — 对于与 `Qt Quick` 配合使用的顶点着色器(无论是在 `ShaderEffect ` 还是 `QSGMaterialShader` 中),此选项均为必填项。对片段着色器或计算着色器无效;由于该关键字仅适用于 `.vert ` 文件,因此可以在同一 `FILES ` 列表中安全地混合使用不同类型的着色器。相当于 `qsb` 的 `-b ` 参数。
  • ZORDER_LOC — 当指定BATCHABLE 时,默认会在7 位置注入一个额外的顶点输入。使用此关键字可更改该位置,以避免与现有输入发生冲突。

细分选项

  • TESSELLATION — 指示着这些着色器属于一个细分管道。仅当未禁用 MSL 生成时,此选项才对顶点着色器有效;在针对 Metal 时,可为这些着色器启用特殊处理和转换。

    此选项于 Qt 6.5 中引入。

  • TESSELLATION_VERTEX_COUNT — 指定来自细分控制阶段的输出顶点数。对于针对 Metal 的细分评估着色器,此选项为必填项。默认值为 `3`。如果该值与控制阶段不匹配,生成的 MSL 代码将无法正常运行。

    此选项自 Qt 6.5 起引入。

  • TESSELLATION_MODE — 指定细分模式:"triangles" (默认)或"quads" 。当FILES 中列出了细分控制着色器时,必须设置此选项,且其值必须与细分评估阶段一致。

    该选项自 Qt 6.5 起引入。

多视图选项

  • VIEW_COUNT — 指定多视图渲染的视图数量(GL_OVR_multiview2、VK_KHR_multiview、D3D12 视图实例化等)。需将其设置为 2 或更大的值,以便相关顶点着色器生成正确的 GLSL 输出。 将VIEW_COUNT 设为2或更大时,会注入QSHADER_VIEW_COUNT 预处理器定义,并自动在顶点着色器中添加#extension GL_EXT_multiview : require 。使用多视图时的最低语言版本要求:GLSL 330和300 es,HLSL 61。请避免在不使用多视图的顶点着色器上设置VIEW_COUNT ;应将其分组为单独的qt_add_shaders() 调用。

    此选项于 Qt 6.7 中引入。

  • MULTIVIEW — 同时生成一组非多视图着色器和一组视图数为 2 的着色器。这是一种便捷写法,相当于使用适当的 GLSL/HLSL/MSL/VIEW_COUNT 参数分别调用两次 `qt_add_shaders() `。 多视图变体的隐式设置分别为:GLSL330,300es 、HLSL61 、MSL21 以及 VIEW_COUNT2 。多视图变体以.mv2qsb 作为后缀附加到.qsb 文件名后进行存储。

    此选项于 Qt 6.8 中引入。

外部工具选项

  • PRECOMPILE — 在 Windows 系统上(当 HLSL 未被禁用时),调用 Windows SDK 中的fxc ,以便在构建时(而非运行时)将 HLSL 源代码编译为 DXBC 字节码。生成的.qsb 文件包含编译后的中间字节码,而非原始的 HLSL 源代码。 相当于qsb 中的-c 参数。在非 Windows 平台上无效。
  • OPTIMIZED — 调用 Vulkan SDK 中的spirv-opt 来对 SPIR-V 字节码进行优化。等同于qsb 的-O 参数。

其他选项

  • BASE — 用于计算生成的.qsb 文件的别名(资源内名称)的路径前缀。当设置BASE 时,每个输出路径将相对于BASE 进行计算,而非保持原样。这类似于qt_add_resources()函数的BASE 参数。
  • DEFINES — 以"name1=value1;name2=value2" 的形式定义在着色器编译期间生效的宏。此外,条目也可以像FILES 那样用换行符分隔。这等同于qsb 的-D 参数。
  • OUTPUTS — 当生成的.qsb 文件名必须与源文件名不同时(例如,当一个着色器文件作为多个.qsb 文件的源文件,且这些文件通过DEFINES 进行区分),请为FILES 中的每个条目提供一个输出文件名。每个名称将通过-o 参数传递给qsb ,而不是在源文件名后附加.qsb 。
  • ORIGINAL_FILES — 当.qsb 文件应依赖于与FILES 中不同的着色器源文件时,请在此为每个FILES 条目提供一个条目。若存在该条目,相应的ORIGINAL_FILES 条目将通过--orig-file 写入 CMake 依赖文件,并被添加到底层add_custom_command() 的DEPENDS 子句中。当传递给qt_add_shaders() 的文件是生成的中间资产,而最终的.qsb 文件应追踪原始源文件时,此方法非常有用。
  • PERTARGETCOMPILE — 编译为 SPIR-V,并分别转换为各输出语言版本,每种目标语言仅执行一次。此方法比默认的单遍处理方式速度更慢,但支持通过QSHADER_<LANG>[_VERSION] 预处理器宏进行条件编译。相当于qsb 的-p 参数。
  • DEBUGINFO — 为 SPIR-V 生成完整的调试信息,使RenderDoc等工具在检查管道或执行顶点/片段调试时能够显示完整的源代码。当同时设置PRECOMPILE 时,会指示fxc 将调试信息嵌入生成的 DXBC 字节码中。等同于qsb 的-g 参数。
  • QUIET — 抑制来自qsb 的调试和警告输出。仅打印致命错误。等同于qsb 的-s 参数。
  • OUTPUT_TARGETS — 当使用qt_add_shaders 处理静态库时,会生成一个或多个特殊目标。传递一个变量名以获取这些目标以便进一步处理。
  • MEDIUMP — 要求在 GLSL ES 片段着色器中默认使用中精度浮点数。对其他目标(包括非 ES 格式的 GLSL)无效。

替换手动编写的光栅化着色器

FILES 列表支持一种特殊语法,用于将.qsb 包中的特定着色器变体替换为手工编写的文件。这相当于qsb 的-r 选项:

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

文件名后可跟任意数量的、以@ 分隔的替换规范。每条规范都指定着着色语言、版本以及要读取的文件,各部分以逗号分隔。文件名或目录路径中的@ 字符会被正确处理,且不会影响解析。详情请参阅QSB手册。

示例

基本用法

find_package(Qt6 COMPONENTS ShaderTools)

qt6_add_executable(exampleapp main.cpp)

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

这会在运行时提供:/wobble.frag.qsb 支持。原始的wobble.frag 源代码不会包含在可执行文件中。

细分

可以按以下方式设置一个包含四个阶段的图形管道:顶点(vertex.vert )、细分控制(tess.tesc )、细分评估(tess.tese )和片段(fragment.frag )。

首先编译顶点着色器和片段着色器。TESSELLATION 启用了顶点着色器的特殊 Metal 转换,并且由于曲面细分需要 OpenGL 4.x 或 ES 3.2,因此提高了 GLSL 版本。

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

曲面细分着色器被列在单独的调用中,因为它们需要NOHLSL ——HLSL 曲面细分着色器必须手动编写并注入。Metal 曲面细分参数被显式指定。

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

注意: 仅建议高级用户手动编写 外壳和域 HLSL 着色器。对于常量缓冲区等结构,需要特别注意以确保资源接口和布局与 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.