Тип QML ShaderEffect
Применяет пользовательские шейдеры к прямоугольнику. Подробнее...
| Выражение импорта: | import QtQuick 2.0 |
| Наследует: |
Свойства
- blending : bool
- cullMode : перечисление
- fragmentShader : url
- log : строка
- mesh : значение
- status : перечисление
- supportsAtlasTextures : bool
- vertexShader : url
Подробное описание
Тип ShaderEffect применяет пользовательский шейдер вершины и фрагмента (пикселя) к прямоугольнику. Он позволяет добавлять эффекты, такие как тень, размытие, изменение цвета и перелистывание страницы, в сцену QML.
Примечание: В зависимости от используемого бэкенда Qt Quick, тип ShaderEffect может быть не поддерживается. Например, с бэкендом software эффекты вообще не будут отрисовываться.
Шейдеры
В Qt 5 эффекты предоставлялись в виде кода GLSL (OpenGL Shading Language), часто встроенного в виде строк в QML. Начиная с Qt 5.8, стала возможной ссылка на файлы, как локальные, так и в системе ресурсов Qt.
В Qt 6 Qt Quick поддерживает графические API, такие как Vulkan, Metal и Direct3D 11. Поэтому работа со строками исходного кода GLSL больше невозможна. Вместо этого новая конвейерная система шейдеров основана на компиляции совместимого с Vulkan кода GLSL в SPIR-V, за которым следует сбор информации о рефлексии и перевод на другие языки шейдеров, такие как HLSL, Metal Shading Language и различные версии GLSL. Результирующие ресурсы упаковываются в единый пакет, обычно хранящийся в файлах с расширением .qsb. Этот процесс выполняется автономно или во время сборки приложения. Во время выполнения, сценарий сцены и лежащий в основе графический абстракция используют эти .qsb файлы. Поэтому ShaderEffect ожидает ссылки на файлы (локальные или qrc) в Qt 6 вместо встроенного кода шейдера.
Свойства vertexShader и fragmentShader являются URL-адресами в Qt 6 и работают очень похоже на Image.source, например. Однако поддерживаются только схемы file и qrc. Также можно опустить схему file, что позволяет удобно указывать относительный путь. Такой путь разрешается относительно расположения компонента (файла .qml).
Входы и ресурсы шейдеров
Есть два типа входов в vertexShader: униформы и входные вершины.
Определены следующие входы:
- vec4 qt_Vertex - позиция вершины, верхняя левая вершина имеет координаты (0, 0), нижняя правая (ширина, высота).
- vec2 qt_MultiTexCoord0 - текстурные координаты, верхняя левая координата (0, 0), нижняя правая (1, 1). Если supportsAtlasTextures равно true, координаты будут основаны на положении в атласе.
Определены следующие униформы:
- mat4 qt_Matrix - комбинированная матрица преобразования, произведение матриц от корневого элемента до этого ShaderEffect и ортогональной проекции.
- float qt_Opacity - комбинированная непрозрачность, произведение непрозрачностей от корневого элемента до этого ShaderEffect.
Примечание: В GLSL в стиле Vulkan нет отдельных переменных униформы. Вместо этого шейдеры всегда должны использовать блок униформы с точкой привязки 0.
Примечание: Квалификатор макета блока униформы должен всегда быть std140.
Кроме того, любая свойство, которая может быть отображена на тип GLSL, может быть сделана доступной для шейдеров. Следующий список показывает, как свойства отображаются:
- bool, int, qreal -> bool, int, float - Если тип в шейдере не совпадает с типом в QML, значение преобразуется автоматически.
- QColor -> vec4 - При передаче цветов в шейдер они сначала преумножаются. Таким образом, Qt.rgba(0.2, 0.6, 1.0, 0.5) становится vec4(0.1, 0.3, 0.5, 0.5) в шейдере, например.
- QRect, QRectF -> vec4 - Qt.rect(x, y, w, h) становится vec4(x, y, w, h) в шейдере.
- QPoint, QPointF, QSize, QSizeF -> vec2
- QVector3D -> vec3
- QVector4D -> vec4
- QTransform -> mat3
- QMatrix4x4 -> mat4
-
QQuaternion -> vec4, скалярное значение равно
w. - Image -> sampler2D - Начало в верхнем левом углу, а цветовые значения умножены на альфа-канал. Текстура предоставляется как есть, за исключением режима заполнения элемента Image. Чтобы включить режим заполнения, используйте ShaderEffectSource или Image::layer::enabled.
- ShaderEffectSource -> sampler2D - Начало в верхнем левом углу, а цветовые значения умножены на альфа-канал.
Сэмплеры по-прежнему объявляются как отдельные переменные униформы в коде шейдера. Шейдеры могут выбирать любую точку привязки для них, кроме 0, поскольку она зарезервирована для блока униформы.
Некоторые языки шейдеров и API имеют понятие отдельных объектов изображения и сэмплера. Qt Quick всегда работает с комбинированными объектами сэмплера изображения в шейдерах, как поддерживается SPIR-V. Поэтому шейдеры, предоставляемые для ShaderEffect, всегда должны использовать layout(binding = 1) uniform sampler2D tex; стиль объявлений сэмплера. Подлежащий слой абстракции и конвейер шейдеров позаботятся о том, чтобы это работало для всех поддерживаемых API и языков шейдеров, прозрачно для приложений.
Бэкенд QML-сцены может выбрать выделение текстур в атласе текстур. Если текстура, выделенная в атласе, передается в ShaderEffect, по умолчанию она копируется из атласа текстур в отдельную текстуру, чтобы текстурные координаты охватывали диапазон от 0 до 1, и вы получаете ожидаемые режимы обрезки. Однако это увеличит использование памяти. Чтобы избежать копирования текстуры, установите supportsAtlasTextures для простых шейдеров, использующих qt_MultiTexCoord0, или для каждого "uniform sampler2D <name>" объявите "uniform vec4 qt_SubRect_<name>", который будет назначен нормализованным прямоугольником источника текстуры. Для автономных текстур прямоугольник источника - [0, 1]x[0, 1]. Для текстур в атласе прямоугольник источника соответствует части атласа текстур, где хранится текстура. Правильный способ вычисления текстурных координат для текстуры с именем «источник» в атласе текстур - «qt_SubRect_source.xy + qt_SubRect_source.zw * qt_MultiTexCoord0».
Вывод из fragmentShader должен быть предварительно умножен. Если blending включен, используется режим смешивания source-over. Однако режим смешивания additive может быть достигнут путем вывода нуля в альфа-канале.
END_OF_DOCUMENT_MARKER ```
import QtQuick 2.0
Rectangle {
width: 200; height: 100
Row {
Image { id: img;
sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
ShaderEffect {
width: 100; height: 100
property variant src: img
vertexShader: "myeffect.vert.qsb"
fragmentShader: "myeffect.frag.qsb"
}
}
} |
Пример предполагает, что myeffect.vert и myeffect.frag содержат код GLSL в стиле Vulkan, обработанный инструментом qsb, для генерации файлов .qsb.
#version 440
layout(location = 0) in vec4 qt_Vertex;
layout(location = 1) in vec2 qt_MultiTexCoord0;
layout(location = 0) out vec2 coord;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
};
out gl_PerVertex { vec4 gl_Position; };
void main() {
coord = qt_MultiTexCoord0;
gl_Position = qt_Matrix * qt_Vertex;
} #version 440
layout(location = 0) in vec2 coord;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
};
layout(binding = 1) uniform sampler2D src;
void main() {
vec4 tex = texture(src, coord);
fragColor = vec4(vec3(dot(tex.rgb, vec3(0.344, 0.5, 0.156))), tex.a) * qt_Opacity;
} Примечание: Текстуры Графа сцены имеют начало в верхнем левом углу, а не в нижнем левом, как это обычно используется в OpenGL.
Использование только одного шейдера
Указание как vertexShader, так и fragmentShader не является обязательным. Многие реализации ShaderEffect на практике будут использовать только фрагментный шейдер, полагаясь на стандартный встроенный вершинный шейдер.
Стандартный вершинный шейдер передаёт координату текстуры фрагментном шейдеру в качестве vec2 qt_TexCoord0 в локации 0.
Стандартный фрагментный шейдер ожидает получения координаты текстуры от вершинного шейдера в качестве vec2 qt_TexCoord0 в локации 0, и он берёт образец из sampler2D под названием source в точке привязки 1.
Предупреждение: При использовании только одного из шейдеров, разработчик шейдера должен учитывать ожидаемую структуру блока переменных для стандартных шейдеров: qt_Matrix должен быть в смещении 0, а за ним — qt_Opacity в смещении 64. Все пользовательские переменные должны размещаться после этих двух. Это обязательно, даже если приложение не использует матрицу или непрозрачность, так как во время выполнения существует единый буфер переменных, доступный и для вершинного, и для фрагментного шейдера.
ShaderEffect и слои элементов
Тип ShaderEffect может быть использован совместно с слоистыми элементами.
|
Слой с отключенным эффектом |
|
Слой с включённым эффектом |
Item {
id: layerRoot
layer.enabled: true
layer.effect: ShaderEffect {
fragmentShader: "effect.frag.qsb"
} #version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
};
layout(binding = 1) uniform sampler2D source;
void main() {
vec4 p = texture(source, qt_TexCoord0);
float g = dot(p.xyz, vec3(0.344, 0.5, 0.156));
fragColor = vec4(g, g, g, p.a) * qt_Opacity;
} |
Также можно объединять несколько слоёв:
Rectangle {
id: gradientRect;
width: 10
height: 10
gradient: Gradient {
GradientStop { position: 0; color: "white" }
GradientStop { position: 1; color: "steelblue" }
}
visible: false; // should not be visible on screen.
layer.enabled: true;
layer.smooth: true
}
Text {
id: textItem
font.pixelSize: 48
text: "Gradient Text"
anchors.centerIn: parent
layer.enabled: true
// This item should be used as the 'mask'
layer.samplerName: "maskSource"
layer.effect: ShaderEffect {
property var colorSource: gradientRect;
fragmentShader: "mask.frag.qsb"
}
} #version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
};
layout(binding = 1) uniform sampler2D colorSource;
layout(binding = 2) uniform sampler2D maskSource;
void main() {
fragColor = texture(colorSource, qt_TexCoord0)
* texture(maskSource, qt_TexCoord0).a
* qt_Opacity;
} |
Примечания к другим моментам
По умолчанию ShaderEffect состоит из четырёх вершин, по одной для каждого угла. Для нелинейных преобразований вершин, таких как загибание страницы, можно указать тонкую сетку вершин, задав разрешение сетки сетки.
См. также Слои элементов.
Документация по свойствам
смешение : bool
Если это свойство имеет значение true, выходные данные из fragmentShader смешиваются с фоном с помощью режима смешивания source-over. Если false, фон игнорируется. Смешение снижает производительность, поэтому следует установить это свойство в false, когда смешение не требуется. Значение по умолчанию — true.
cullMode : перечисление
Это свойство определяет, какие стороны элемента должны быть видны.
- ShaderEffect.NoCulling — Обе стороны видны
- ShaderEffect.BackFaceCulling — Видна только лицевая сторона
- ShaderEffect.FrontFaceCulling — Видна только задняя сторона
Значение по умолчанию — NoCulling.
fragmentShader : url
Это свойство содержит ссылку на файл с предварительно обработанным фрагментным шейдером, как правило, с расширением .qsb. Значение обрабатывается как URL, аналогично другим типам QML, таким как Image. Это должен быть либо локальный файл, либо файл, используемый со схемой qrc для доступа к файлам, встроенным через Qt-ресурсную систему. URL может быть абсолютным или относительным по отношению к URL компонента.
См. также vertexShader.
журнал : строка
Это свойство содержит журнал предупреждений и ошибок, полученных при последней попытке компиляции шейдеров. Оно обновляется одновременно с обновлением статуса на Compiled или Error.
Примечание: В Qt 6, система шейдеров поощряет компиляцию и перевод шейдеров GLSL в стиле Vulkan автономно или на этапе построения. Это не обязательно означает, что компиляция шейдеров не происходит во время выполнения, но даже если это происходит, ShaderEffect в этом не участвует, и синтаксические и подобные ошибки больше не должны возникать на этом этапе. Поэтому значение этого свойства обычно пустое.
См. также статус.
сетка : вариант
Это свойство определяет сетку, используемую для отрисовки ShaderEffect. Оно может содержать любой объект GridMesh. Если свойству присвоено значение размера, ShaderEffect неявно использует GridMesh с указанным значением в качестве разрешения сетки. По умолчанию это свойство имеет размер 1x1.
См. также GridMesh.
статус : перечисление
Это свойство отображает текущий статус шейдеров.
- ShaderEffect.Compiled — Программа шейдеров была успешно скомпилирована и связана.
- ShaderEffect.Uncompiled — Программа шейдеров еще не скомпилирована.
- ShaderEffect.Error — Программа шейдеров не смогла быть скомпилирована или связана.
При установке исходного кода фрагментного или вершинного шейдеров статус становится Uncompiled. В первый раз, когда ShaderEffect отрисовывается с новым исходным кодом шейдеров, шейдеры компилируются и связываются, а статус обновляется на Compiled или Error.
Когда компиляция во время выполнения не используется, а свойства шейдеров ссылаются на файлы с байткодом, статус всегда Compiled. Содержимое шейдера не проверяется (кроме базовой рефлексии для обнаружения элементов входных данных вершины и данных буфера констант) до более позднего этапа в конвейере рендеринга, поэтому потенциальные ошибки (например, несоответствия макета или сигнатуры корня) будут обнаружены только на более позднем этапе.
См. также журнал.
[since QtQuick 2.4] поддерживаетАтласТекстур : bool
Установите это свойство в значение true, чтобы подтвердить, что ваш код шейдера не зависит от qt_MultiTexCoord0, изменяющегося от (0,0) до (1,1) относительно сетки. В этом случае диапазон qt_MultiTexCoord0 будет основан на положении текстуры в атласе. Это свойство в настоящее время не влияет, если используется меньше или больше одного унифицированного саплера в качестве входных данных для вашего шейдера.
Это отличается от предоставления унифицированных данных qt_SubRect_<имя>, так как последнее позволяет рисовать одну или несколько текстур из атласа в одном элементе ShaderEffect, в то время как supportsAtlasTextures позволяет нескольким экземплярам компонента ShaderEffect, использующим различные исходные изображения из атласа, быть объединёнными в одном рисовании. Оба подхода предотвращают копирование текстуры из атласа, когда на неё ссылается элемент ShaderEffect.
Значение по умолчанию — false.
Это свойство было введено в QtQuick 2.4.
vertexShader : url
Это свойство содержит ссылку на файл с предварительно обработанным пакетом вершинного шейдера, обычно с расширением .qsb. Значение обрабатывается как URL, аналогично другим типам QML, таким как Image. Оно должно быть либо локальным файлом, либо использовать схему qrc для доступа к файлам, встроенным через систему ресурсов Qt. URL может быть абсолютным или относительным к URL компонента.
См. также fragmentShader.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.0/qml-qtquick-shadereffect.html