Интеграция системы сборки 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 Language 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. Обратите внимание, что список следует синтаксису разделения запятымиqsb. Например, вычислительный шейдер захочет указать"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. Указанное имя затем передаётся в аргумент-oк qsb вместо простого добавления.qsbк имени файла исходника. -
DEBUGINFO- Включает генерацию полной отладочной информации для SPIR-V, что позволяет инструментам, таким как RenderDoc, отображать полный исходный код при просмотре конвейера или при отладке вершинного или фрагментного шейдера. Эквивалентно аргументу-gинструмента qsb. Также оказывает влияние на Direct 3D в случае, если было указано ключевое словоPRECOMPILE, так какfxcполучает указание включать отладочную информацию в сгенерированный промежуточный байт-код.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/qtshadertools-build.html