PySide6.QtQuick.QSGMaterial

class QSGMaterial

QSGMaterial 类封装了着色器程序的渲染状态。更多

继承自: QSGVertexColorMaterial, QSGFlatColorMaterial, QSGOpaqueTextureMaterial, QSGTextureMaterial

概要

方法

虚拟方法

注意

本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。

详细描述

QSGMaterialQSGMaterialShader 子类形成了紧密的关系。对于一个场景图(包括嵌套图),有一个唯一的 QSGMaterialShader 实例,它封装了场景图用于渲染该材质的着色器,例如用于几何体平面着色的着色器。每个 QSGGeometryNode 可以有一个唯一的 QSGMaterial,其中包含绘制该节点时应如何配置着色器的信息,例如用于渲染几何体的实际颜色。

QSGMaterial 有两个虚函数,都需要实现。函数 type() 应该为特定子类的所有实例返回一个唯一的实例。createShader() 函数应该返回一个新的 QSGMaterialShader 实例,特定于 QSGMaterial 的那个子类。

一个最小的 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子类。

注意

createShader() 每个 QSGMaterialType 只调用一次,以减少着色器准备中的冗余工作。如果一个 QSGMaterial 由多组顶点和片段着色器组合支持,type() 的实现必须为每种着色器组合返回一个不同的、唯一的 QSGMaterialType 指针。

注意

所有带有QSG前缀的类应仅在场景图的渲染线程上使用。有关更多信息,请参见场景图和渲染

另请参阅

QSGMaterialShader 场景图 - 自定义材质 场景图 - 两个纹理提供者 场景图 - 图

class Flag

常量

描述

QSGMaterial.Blending

(继承自 enum.Flag) 如果材质在渲染过程中需要启用混合,请将此标志设置为 true。

QSGMaterial.RequiresDeterminant

如果材质依赖于几何节点矩阵的行列式进行渲染,请将此标志设置为true。

QSGMaterial.RequiresFullMatrixExceptTranslate

如果材质依赖于几何节点的完整矩阵进行渲染,除了平移部分,请将此标志设置为true。

QSGMaterial.RequiresFullMatrix

如果材质依赖于几何节点的完整矩阵进行渲染,请将此标志设置为true。

QSGMaterial.NoBatching

如果材质使用的着色器与场景图的分批机制不兼容,请将此标志设置为true。这在某些高级用法中很重要,例如,在顶点着色器中直接操作gl_Position.z。此类解决方案通常与特定的场景结构相关联,并且在场景中使用任意内容时可能不安全。因此,只有在适当的调查后才能设置此标志,并且绝大多数材质都不需要此标志。设置此标志可能会导致性能下降,因为需要发出更多的绘制调用。此标志在Qt 6.3中引入。

QSGMaterial.CustomCompileStep

在 Qt 6 中,此标志与 NoBatching 相同。建议使用 NoBatching 代替。

__init__()
compare(other)
Parameters:

其他QSGMaterial

Return type:

整数

将此材料与other进行比较,如果它们相等则返回0;如果此材料应排在other之前则返回-1;如果other应排在此材料之前则返回1。

场景图可以重新排序几何节点以最小化状态更改。在排序过程中调用比较函数,以便可以对材质进行排序,以最小化每次调用QSGMaterialShader::updateState()时的状态更改。

this指针和other保证具有相同的type()

abstract createShader(renderMode)
Parameters:

renderModeRenderMode

Return type:

QSGMaterialShader

此函数返回一个新的QSGMaterialShader实现实例,用于渲染特定QSGMaterial实现的几何图形。

该函数将针对每种材料类型和renderMode的组合仅调用一次,并将在内部缓存。

对于大多数材料,renderMode 可以忽略。一些材料可能需要针对特定渲染模式进行自定义处理。例如,如果材料实现了抗锯齿,并且在使用 RenderMode3D 时需要考虑到透视变换。

flags()
Return type:

Flag的组合

返回材料的标志。

setFlag(flags[, on=true])
Parameters:
  • flagsFlag 的组合

  • on – 布尔值

如果 on 为真,则在此材料上设置标志 flags;否则清除该属性。

abstract type()
Return type:

QSGMaterialType

此函数由场景图调用,以查询由createShader()实例化的QSGMaterialShader的唯一标识符。

对于许多材料,典型的方法将是返回一个指向静态的、因此全局可用的QSGMaterialType实例的指针。QSGMaterialType是一个不透明的对象。其目的仅作为类型安全的、简单的方式来生成唯一的材料标识符。

QSGMaterialType *type() const override
{
    static QSGMaterialType type;
    return &type;
}
viewCount()
Return type:

整数

返回在材料用于多视图渲染时的视图数量。

注意

返回值仅在从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个视图。它不兼容其他视图数量。在配置着色器时,必须使用qsb工具调用--view-count 2,或者如果使用CMake集成,则必须在qt_add_shaders()命令中指定VIEW_COUNT 2

注意

当设置了2个或更多的视图计数时,#extension GL_EXT_multiview : require 这一行会自动由 qsb 注入。

鼓励开发者使用自动注入的预处理器变量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;
}

现在,同一个源文件可以通过qsbqt_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。在构建时可能会接受较低的版本,但在运行时可能会导致错误,具体取决于OpenGL的实现。

为了方便起见,qt_add_shaders() 还提供了一个 MULTIVIEW 选项。这个选项首先会正常运行 qsb 工具,然后将 VIEW_COUNT 覆盖为 2,并将 GLSLHLSLMSL 设置为一些合适的默认值,然后再次运行 qsb,这次会输出带有后缀的 .qsb 文件。然后,材质实现可以使用带有 viewCount 参数的 setShaderFileName() 重载,自动选择正确的 .qsb 文件。

因此,以下内容与上面显示的示例调用大致相同,只是不需要手动指定输出文件。请注意,在某些情况下,自动选择的着色语言版本可能不够,此时应用程序应继续明确指定所有内容。

qt_add_shaders(application "application_multiview_shaders"
    MULTIVIEW
    PREFIX
        /
    FILES
        shaders/example.vert
        shaders/example.frag
)

有关Qt中多视图支持的更多底层细节,请参见QRhi::MultiView、QRhiColorAttachment::setMultiViewCount()和QRhiGraphicsPipeline::setMultiViewCount()。当通过fromRhiRenderTarget()或特定于3D API的函数(例如带有大于1的arraySize参数的fromVulkanImage())指定时,Qt Quick场景图渲染器已准备好识别多视图渲染目标。然后,渲染器将视图计数传播到图形管道和材质。