# 着色器元素
对于着色器编程,Qt Quick提供了两个元素:ShaderEffectSource
(着色器效果源)和ShaderEffect
(着色器效果)。 着色器效果,应用自定义的着色器;着色器效果源,将QML项目渲染到纹理中并渲染此纹理。 由于着色器效果可以将自定义着色器应用于其矩形形状,并且可以使用着色器操作的源(As shader effect can apply custom shaders to its rectangular shape and can use sources for the shader operation)。 源可以是图像,它被用于纹理或着色器效果源。
默认着色器使用源并不加修改地渲染它。 下面,首先看这带有两个ShaderEffect
元素的QML文件。 一种没有指定任何着色器,另一种显式指定了默认的顶点着色器和片段着色器。 将很快了解着色器。
import QtQuick
Rectangle {
width: 480; height: 240
color: '#1e1e1e'
Row {
anchors.centerIn: parent
spacing: 20
Image {
id: sourceImage
width: 80; height: width
source: '../assets/tulips.jpg'
}
ShaderEffect {
id: effect
width: 80; height: width
property variant source: sourceImage
}
ShaderEffect {
id: effect2
width: 80; height: width
property variant source: sourceImage
vertexShader: "default.vert.qsb"
fragmentShader: "default.frag.qsb"
}
}
}
在上面的示例中,有一行3张图像。 第一张是真实的图像,第二张使用了默认着色器进行渲染,第三张使用了片段和顶点着色器代码进行渲染,如下所示。 看一下这些着色器。
顶点着色器获取纹理坐标qt_MultiTexCoord0
,并将其传递到qt_TexCoord0
变量。 它还获取qt_Vertex
位置,并将其与Qt的变换矩阵ubuf.qt_Matrix
相乘,并通过gl_Position
变量返回它。 这使屏幕上的纹理和顶点位置保持不变。
#version 440
layout(location=0) in vec4 qt_Vertex;
layout(location=1) in vec2 qt_MultiTexCoord0;
layout(location=0) out vec2 qt_TexCoord0;
layout(std140, binding=0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
} ubuf;
out gl_PerVertex {
vec4 gl_Position;
};
void main() {
qt_TexCoord0 = qt_MultiTexCoord0;
gl_Position = ubuf.qt_Matrix * qt_Vertex;
}
片段着色器从source
2D采样器中获取纹理,纹理位于坐标qt_TexCoord0
处,并将其与Qt不透明度ubuf.qt_Opacity
相乘以计算fragColor
,它是像素要使用的颜色。
#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;
} ubuf;
layout(binding=1) uniform sampler2D source;
void main() {
fragColor = texture(source, qt_TexCoord0) * ubuf.qt_Opacity;
}
请注意,这两个着色器可以用作自己的着色器的样板代码。 这些变量、位置和绑定都是Qt中所期望的。可以在着色器效果文档(Shader Effect Documentation) (opens new window)阅读更多与此相关的确切细节.
在可以使用着色器之前,它们需要被烘焙。 如果着色器是较大Qt项目的一部分并将其作为资源包含在内,则可以自动执行此操作。 但是,当使用着色器和qml
文件时,需要手动显式烘焙它们。 这是使用以下两个命令完成的:
qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -o default.frag.qsb default.frag
qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o default.vert.qsb default.vert
qsb
工具位于Qt 6安装目录下的bin
目录中。
提示
如果不想看到源图像而只想看到效果图像,可以将Image设置为不可见(visible: false
)。 着色器效果仍将使用图像数据,只是Image元素不会被渲染。
在接下来的示例中将使用一些简单的着色器机制。 首先,专注于分析片段着色器,然后将回到分析顶点着色器上。