QSGMaterial Class
QSGMaterial 类封装了着色器程序的渲染状态。更多
Header: | #include <QSGMaterial> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Quick) target_link_libraries(mytarget PRIVATE Qt6::Quick) |
qmake: | QT += quick |
继承者 | QSGFlatColorMaterial,QSGOpaqueTextureMaterial, 以及QSGVertexColorMaterial |
- 所有成员(包括继承成员)的列表
- QSGMaterial 是Qt Quick 场景图材质类的一部分。
公共类型
enum | Flag { Blending, RequiresDeterminant, RequiresFullMatrixExceptTranslate, RequiresFullMatrix, NoBatching, CustomCompileStep } |
flags | Flags |
公共函数
virtual int | compare(const QSGMaterial *other) const |
virtual QSGMaterialShader * | createShader(QSGRendererInterface::RenderMode renderMode) const = 0 |
QSGMaterial::Flags | flags() const |
void | setFlag(QSGMaterial::Flags flags, bool on = true) |
virtual QSGMaterialType * | type() const = 0 |
(since 6.8) int | viewCount() const |
详细说明
QSGMaterial 和QSGMaterialShader 子类之间关系密切。对于一个场景图(包括嵌套图),有一个唯一的QSGMaterialShader 实例,该实例封装了场景图用于渲染该材质的着色器,如几何体的平面着色器。每个QSGGeometryNode 都有一个唯一的 QSGMaterial,其中包含绘制该节点时应如何配置着色器,如用于渲染几何体的实际颜色。
QSGMaterial 有两个都需要实现的虚拟函数。type() 函数应为特定子类的所有实例返回一个唯一实例。createShader() 函数应返回 QSGMaterial 子类特有的QSGMaterialShader 的新实例。
一个最小的 QSGMaterial 实现可以是这样的:
class Material : public QSGMaterial { public: QSGMaterialType *type() const override { static QSGMaterialType type; return &type; } QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const override { return new Shader; } };
请参阅自定义材质示例,了解如何通过QSGGeometryNode 和自定义材质实现QQuickItem 子类。
注意: 每个QSGMaterialType 只调用一次createShader() ,以减少着色器准备的冗余工作。如果 QSGMaterial 由多组顶点和片段着色器组合支持,则type() 的实现必须为每个着色器组合返回一个不同的、唯一的QSGMaterialType 指针。
注意: 所有带有 QSG 前缀的类都只能在场景图的渲染线程中使用。更多信息请参见场景图和渲染。
另请参阅 QSGMaterialShader 、场景图 - 自定义材质、场景图 - 两个纹理提供程序和场景图 - 图形。
成员类型文档
枚举 QSGMaterial::Flag
flags QSGMaterial::Flags
常量 | 值 | 说明 |
---|---|---|
QSGMaterial::Blending | 0x0001 | 如果材质要求在渲染时启用混合,则将此标志设为 true。 |
QSGMaterial::RequiresDeterminant | 0x0002 | 如果材质依赖几何体节点矩阵的行列式进行渲染,则将此标志设为 true。 |
QSGMaterial::RequiresFullMatrixExceptTranslate | 0x0004 | RequiresDeterminant | 如果材质依靠几何体节点的全矩阵(平移部分除外)进行渲染,则将此标记设置为 true。 |
QSGMaterial::RequiresFullMatrix | 0x0008 | RequiresFullMatrixExceptTranslate | 如果材质依赖几何体节点的全矩阵进行渲染,则将此标记设为 true。 |
QSGMaterial::NoBatching | 0x0010 | 如果材质使用的着色器与场景图的批处理机制不兼容,则将此标记设为 true。这与某些高级用法有关,例如在顶点着色器中直接操作gl_Position.z 。此类解决方案通常与特定的场景结构相绑定,在使用场景中的任意内容时可能并不安全。因此,只有经过适当调查后才能设置此标记,而且绝大多数材质都不需要设置此标记。设置此标记可能会降低性能,因为必须发出更多的绘制调用。此标记在 Qt 6.3 中引入。 |
QSGMaterial::CustomCompileStep | NoBatching | 在 Qt 6 中,此标记与 NoBatching 相同。请优先使用 NoBatching。 |
Flags 类型是QFlags<Flag> 的类型定义。它存储 Flag 值的 OR 组合。
成员函数文档
[virtual]
int QSGMaterial::compare(const QSGMaterial *other) const
将此材质与other 进行比较,如果两者相等,则返回 0;如果此材质应排序在other 之前,则返回 -1 ;如果other 应排序在 之前,则返回 1。
场景图可以对几何节点重新排序,以尽量减少状态变化。在排序过程中会调用比较函数,以便在每次调用 QSGMaterialShader::updateState() 时对材质进行排序,尽量减少状态变化。
此指针和other 保证具有相同的type() 。
[pure virtual]
QSGMaterialShader *QSGMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
此函数返回QSGMaterialShader 实现的一个新实例,该实现用于为QSGMaterial 的特定实现渲染几何图形。
该函数只对材料类型和renderMode 的每种组合调用一次,并在内部缓存。
对于大多数材料,renderMode 可以忽略。少数材料可能需要针对特定的呈现模式进行自定义处理。例如,在使用 RenderMode3D 时,如果材质实现抗锯齿的方式需要考虑透视变换,就需要使用该函数。
QSGMaterial::Flags QSGMaterial::flags() const
返回材料的标记。
void QSGMaterial::setFlag(QSGMaterial::Flags flags, bool on = true)
如果on 为 true,则设置该材料的标志flags ;否则清除该属性。
[pure virtual]
QSGMaterialType *QSGMaterial::type() const
该函数由场景图调用,用于查询createShader() 所实例化的QSGMaterialShader 的唯一标识符。
对于许多材料来说,典型的方法是返回一个指向静态QSGMaterialType 实例的指针,因此该指针在全局范围内都是可用的。QSGMaterialType 是一个不透明对象。它的作用只是作为一种类型安全、简单的方法来生成唯一的材料标识符。
QSGMaterialType *type() const override { static QSGMaterialType type; return &type; }
[since 6.8]
int QSGMaterial::viewCount() const
如果材质用于多视图渲染,则返回视图数。
注意: 返回值仅在从createShader() 及其后调用时有效。在场景图调用createShader() 之前,该值不一定是最新的。
通常情况下,返回值为1
。视图数大于 2 意味着多视图渲染传递。支持多视图的材质应在createShader() 或其QSGMaterialShader 构造函数中查询 viewCount(),并确保选择了适当的着色器。然后,顶点着色器应使用gl_ViewIndex
来索引模型视图-投影矩阵数组,因为在多视图模式下有多个矩阵。(每个视图一个)
下面以简单的顶点着色器为例:
#version 440 layout(location = 0) in vec4 vertexCoord; layout(location = 1) in vec4 vertexColor; layout(location = 0) out vec4 color; layout(std140, binding = 0) uniform buf { mat4 matrix[2]; float opacity; }; void main() { gl_Position = matrix[gl_ViewIndex] * vertexCoord; color = vertexColor * opacity; }
该着色器用于处理 2 个视图,且仅限 2 个视图。它与其他视图数不兼容。在调节 Shader 时,必须用--view-count 2
调用qsb
工具,如果使用 CMake 集成,则必须在qt_add_shaders()
命令中指定VIEW_COUNT 2
。
注: 每当视图数设置为 2 或更大时,qsb
会自动注入一行#extension GL_EXT_multiview : require
。
我们鼓励开发人员使用自动注入的预处理器变量QSHADER_VIEW_COUNT
来简化对不同视图数的处理。例如,如果需要在同一源文件中同时支持视图数为 2 的非多视图和多视图,可以采用以下方法:
#version 440 layout(location = 0) in vec4 vertexCoord; layout(location = 1) in vec4 vertexColor; layout(location = 0) out vec4 color; layout(std140, binding = 0) uniform buf { #if QSHADER_VIEW_COUNT >= 2 mat4 matrix[QSHADER_VIEW_COUNT]; #else mat4 matrix; #endif float opacity; }; void main() { #if QSHADER_VIEW_COUNT >= 2 gl_Position = matrix[gl_ViewIndex] * vertexCoord; #else gl_Position = matrix * vertexCoord; #endif color = vertexColor * opacity; }
现在,同一源文件可以通过qsb
或qt_add_shaders()
运行两次,一次不指定视图数,另一次视图数设置为 2。然后,材料可以在运行时根据 viewCount() 选择合适的 .qsb 文件。
在 CMake 中,这看起来类似于下面的示例。在此示例中,相应的QSGMaterialShader 将根据 viewCount() 的值在:/shaders/example.vert.qsb
和:/shaders/multiview/example.vert.qsb
之间做出选择。(片段着色器也是如此)
qt_add_shaders(application "application_shaders" PREFIX / FILES shaders/example.vert shaders/example.frag ) qt_add_shaders(application "application_multiview_shaders" GLSL 330,300es HLSL 61 MSL 12 VIEW_COUNT 2 PREFIX / FILES shaders/example.vert shaders/example.frag OUTPUTS shaders/multiview/example.vert shaders/multiview/example.frag )
注: 片段着色器的处理方式应与顶点着色器相同,尽管片段着色器代码不能依赖于视图计数 (gl_ViewIndex
),以实现最大的可移植性。将片段着色器也纳入多视图集有两个原因。一个原因是在同一图形管道中混合使用不同版本的着色器可能会产生问题,这取决于底层图形 API:例如,在 D3D12 中,混合使用着色器模型 5.0 和 6.1 的 HLSL 着色器会产生错误。另一方面,在片段着色器中定义QSHADER_VIEW_COUNT
可能非常有用,例如在顶点和片段阶段之间共享统一的缓冲区布局。
注: 对于 OpenGL,依赖gl_ViewIndex
的顶点着色器的最低 GLSL 版本为330
。更低版本的 GLSL 可能在构建时被接受,但在运行时可能会导致错误,具体取决于 OpenGL 实现。
为方便起见,qt_add_shaders() 还有一个MULTIVIEW
选项。首先正常运行qsb
工具,然后将VIEW_COUNT
覆盖至2
,将GLSL
、HLSL
、MSL
设置为合适的默认值,并再次运行qsb
,这次输出的是带有后缀的 .qsb 文件。然后,材料实现就可以使用QSGMaterialShader::setShaderFileName() 重载,其中包含一个viewCount
参数,它会自动选择正确的 .qsb 文件。
因此,除了不需要指定手动管理的输出文件外,下面的调用与上面的示例调用基本等价。请注意,在某些情况下,自动选择的着色语言版本可能不够充分,在这种情况下,应用程序应继续明确指定所有内容。
qt_add_shaders(application "application_multiview_shaders" MULTIVIEW PREFIX / FILES shaders/example.vert shaders/example.frag )
有关 Qt XML 多视图支持的更多低级细节,请参见QRhi::MultiView 、QRhiColorAttachment::setMultiViewCount() 和QRhiGraphicsPipeline::setMultiViewCount()。当通过QQuickRenderTarget::fromRhiRenderTarget() 或 3D API 特定函数(如fromVulkanImage() 且arraySize
参数大于 1)指定多视图渲染目标时,Qt Quick 场景图渲染器就能识别多视图渲染目标。然后,渲染器会将视图数传播给图形管道和材质。
此函数在 Qt 6.8 中引入。
© 2025 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.