Интеграция системы сборки Qt Shader Tools
Введение
Модуль Qt Shader Tools предоставляет файл макроса CMake, который обеспечивает полезные функции, которые приложения могут использовать в своём CMakeLists.txt.
При использовании функции qt6_add_shaders, инструмент qsb будет автоматически вызван системой сборки, а полученные файлы .qsb будут неявно добавлены в систему ресурсов.
Первый пример
Рассмотрим простой пример. Предположим, у нас есть приложение Qt Quick, которое хочет предоставить собственный эффект мерцания через ShaderEffect. Фрагментный шейдер реализован в wobble.frag. Свойство fragmentShader элемента ShaderEffect ссылается на wobble.frag.qsb. Как обеспечить генерацию этого файла .qsb во время сборки?
...
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"
) Вышеприведённого достаточно, чтобы приложение могло получить доступ к :/wobble.frag.qsb во время выполнения. Исходный код шейдера GLSL в стиле Vulkan (wobble.frag) не включён в исполняемый файл приложения и не должен распространяться. Если в коде шейдера есть ошибки, сообщения об ошибках компилятора glslang будут выведены во время сборки, и сборка завершится неудачно. При изменении файла исходного кода шейдера изменения автоматически учитываются при следующей сборке, как и для файлов C++ и других исходных файлов.
Ключевой является функция qt6_add_shaders, которая имеет сходство с qt6_add_resources. Без указания дополнительных параметров функция вызовет qsb с набором разумных параметров по умолчанию, которые подходят для фрагментных шейдеров при нацеливании на Vulkan, Metal, Direct 3D и OpenGL или OpenGL ES.
Примечание: Обратите внимание на строку find_package. Важно включить find_package для ShaderTools, в противном случае qt6_add_shaders не будет доступен.
Примечание: Поддерживается несколько вызовов qt6_add_shaders. В сложных приложениях не исключено, что разным наборам шейдеров нужны разные настройки. Имя после проекта ("exampleapp_shaders" в приведённом примере) должно быть уникальным для каждого вызова.
Настройка
По умолчанию qt6_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 с ядром), исходный код HLSL для Shader Model 5.0 (для Direct3D 11.1) и исходный код языка Metal Shading 1.2 (для Metal).
Это хороший набор значений по умолчанию для Qt Quick и создаёт приложения, которые хорошо переносятся на самые разные системы. Однако эти значения по умолчанию не всегда подходят. Если шейдер использует функции или конструкции, у которых нет эквивалента в этих целевых платформах, процесс, а значит, и сборка, завершатся неудачно. В таком случае, целевые платформы необходимо настроить, а это также означает, что минимальные системные требования приложения неявно изменяются. Например, рассмотрим функцию GLSL textureLod, которая доступна только с OpenGL ES 3.0 и выше (то есть GLSL ES 300 или выше). При запросе GLSL 300 es вместо 100 es, сборка завершится успешно, но результирующее приложение теперь будет требовать OpenGL ES 3.0 или выше и не будет совместимо с системами на базе OpenGL ES 2.0.
Тип шейдера
Тип шейдера определяется по расширению файла. Таким образом, расширение должно быть одним из следующих:
-
.vert- для вершинных шейдеров -
.frag- для фрагментных (пиксельных) шейдеров -
.comp- для шейдеров вычислений
Целевые платформы
Доступны следующие ключевые слова:
-
GLSL- Запрашивает генерацию исходного кода для заданного списка версий GLSL. Обратите внимание, что список следует синтаксису с разделителем запятая. Например, шейдер вычислений захочет указать"310 es,430"здесь, так как значения по умолчанию для него не подходят. -
NOGLSL- Это ключевое слово без аргументов отключает генерацию исходного кода GLSL. Подходит для приложений, которые вообще не хотят работать с OpenGL. -
HLSL- Запрашивает генерацию исходного кода для заданного списка версий HLSL (модели шейдера). Инструментqsbследует за номерами версий в стиле GLSL, поэтому50соответствует Shader Model 5.0, а51— 5.1. -
NOHLSL- Это ключевое слово без аргументов отключает генерацию исходного кода HLSL. Подходит для приложений, которые вообще не хотят работать с Direct 3D. -
MSL- Запрашивает генерацию исходного кода для заданной версии языка Metal Shading Language.12соответствует 1.2, а20— 2.0. -
NOMSL- Это ключевое слово без аргументов отключает генерацию исходного кода MSL. Подходит для приложений, которые вообще не хотят работать с Metal.
Наиболее часто переопределяемой настройкой является GLSL. Например, если шейдеры приложения используют функции OpenGL 3.x, скорее всего, потребуется указать значение выше 100 es или 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
) Примечание: Пробел перед суффиксом es необязателен.
Особенности Qt Quick
-
BATCHABLE- Указание этого единственного ключевого слова без аргументов необходимо для вершинных шейдеров, используемых с Qt Quick, как в ShaderEffect, так и в QSGMaterialShader. Оно не влияет на фрагментные или шейдеры вычислений, и различные типы можно безопасно включать в один и тот же список, поскольку ключевое слово учитывается только для файлов.vert. Эквивалентно аргументу-bинструмента qsb.
Вызов внешних инструментов
-
PRECOMPILE- Эквивалентно параметрам-cили-tинструмента qsb, в зависимости от платформы. При сборке на Windows это приводит к вызовуfxcиз Windows SDK для выполнения первой фазы компиляции (исходный код HLSL в байткод DXBC) во время сборки вместо выполнения во время выполнения. На macOS используется инструмент Metal для генерации библиотеки Metal. В любом случае результирующий файл.qsbбудет содержать только результаты компиляции, а не исходный код HLSL или MSL. -
OPTIMIZED- Вызываетspirv-opt(который должен быть доступен из Vulkan SDK или откуда-то ещё) для выполнения оптимизаций байткода SPIR-V. Эквивалентно аргументу-Oинструмента qsb.
Другие настройки
-
DEFINES- Определяет макросы, которые активны во время компиляции шейдеров. Эквивалентно аргументу-Dинструмента qsb. Список имеет вид"name1=value1;name2=value2". В качестве альтернативы, так же какFILES, список можно разделять переводом строки. -
OUTPUTS- Если имя сгенерированного файла .qsb должно отличаться от исходного, например, потому что один файл шейдера служит источником для нескольких файлов .qsb из-за дифференциации черезDEFINES, этот список может содержать запись для каждого элемента вFILES, определяя имя файла, обычно заканчивающееся на.qsb. Указанное имя передаётся в аргумент-oqsb вместо простого добавления.qsbк имени исходного файла. -
DEBUGINFO- Включает генерацию полной отладочной информации для SPIR-V, что позволяет инструментам, таким как RenderDoc, отображать весь исходный код при просмотре конвейера или отладке вершинного или фрагментного шейдеров. Эквивалентно аргументу-gинструмента qsb. Также влияет на Direct 3D в случае, если указано ключевое словоPRECOMPILE, так какfxcполучает указание включать отладочную информацию в сгенерированный промежуточный байткод. -
QUIET- Подавляет вывод отладочных и предупреждающих сообщений из qsb. Выводятся только фатальные ошибки.
Замена вручную созданных шейдеров
Интеграция CMake также поддерживает указание замен для заданных версий шейдеров в результирующем файле .qsb. Это по сути эквивалентно запуску qsb с параметром командной строки -r.
Это активируется следующим специальным синтаксисом в списке FILES:
FILES
"shaders/externalsampler.frag@glsl,100es,shaders/externalsampler_gles.frag" Имя файла может быть дополнено любым количеством спецификаций замены, разделённых @. Каждая из них указывает язык шейдеров, версию и файл, из которого нужно читать данные, разделённые запятыми. Подробности см. в Руководстве по QSB.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/qtshadertools-build.html