PySide6.QtQuick.QSGMaterial¶
- class QSGMaterial¶
QSGMaterial类封装了着色器程序的渲染状态。更多…继承自:
QSGVertexColorMaterial,QSGFlatColorMaterial,QSGOpaqueTextureMaterial,QSGTextureMaterial概要¶
方法¶
def
__init__()def
flags()def
setFlag()def
viewCount()
虚拟方法¶
def
compare()def
createShader()def
type()
注意
本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。
详细描述¶
QSGMaterial和QSGMaterialShader子类形成了紧密的关系。对于一个场景图(包括嵌套图),有一个唯一的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:
renderMode –
RenderMode- Return type:
此函数返回一个新的
QSGMaterialShader实现实例,用于渲染特定QSGMaterial实现的几何图形。该函数将针对每种材料类型和
renderMode的组合仅调用一次,并将在内部缓存。对于大多数材料,
renderMode可以忽略。一些材料可能需要针对特定渲染模式进行自定义处理。例如,如果材料实现了抗锯齿,并且在使用 RenderMode3D 时需要考虑到透视变换。返回材料的标志。
如果
on为真,则在此材料上设置标志flags;否则清除该属性。- abstract type()¶
- Return type:
此函数由场景图调用,以查询由
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; }
现在,同一个源文件可以通过
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。在构建时可能会接受较低的版本,但在运行时可能会导致错误,具体取决于OpenGL的实现。为了方便起见,qt_add_shaders() 还提供了一个
MULTIVIEW选项。这个选项首先会正常运行qsb工具,然后将VIEW_COUNT覆盖为2,并将GLSL、HLSL、MSL设置为一些合适的默认值,然后再次运行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场景图渲染器已准备好识别多视图渲染目标。然后,渲染器将视图计数传播到图形管道和材质。