QSGMaterial Class

Die Klasse QSGMaterial kapselt den Rendering-Status für ein Shader-Programm. Mehr...

Kopfzeile: #include <QSGMaterial>
CMake: find_package(Qt6 REQUIRED COMPONENTS Quick)
target_link_libraries(mytarget PRIVATE Qt6::Quick)
qmake: QT += quick
Vererbt von:

QSGFlatColorMaterial, QSGOpaqueTextureMaterial, und QSGVertexColorMaterial

Öffentliche Typen

enum Flag { Blending, RequiresDeterminant, RequiresFullMatrixExceptTranslate, RequiresFullMatrix, NoBatching, CustomCompileStep }
flags Flags

Öffentliche Funktionen

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

Detaillierte Beschreibung

QSGMaterial und QSGMaterialShader Unterklassen bilden eine enge Beziehung. Für einen Szenengraphen (einschließlich verschachtelter Graphen) gibt es eine eindeutige QSGMaterialShader -Instanz, die die Shader kapselt, die der Szenengraphen zum Rendern dieses Materials verwendet, z. B. einen Shader zur flachen Einfärbung der Geometrie. Jedes QSGGeometryNode kann ein eindeutiges QSGMaterial haben, das enthält, wie der Shader beim Zeichnen dieses Knotens konfiguriert werden soll, z. B. die tatsächliche Farbe, die zum Rendern der Geometrie verwendet wird.

QSGMaterial hat zwei virtuelle Funktionen, die beide implementiert werden müssen. Die Funktion type() sollte eine eindeutige Instanz für alle Instanzen einer bestimmten Unterklasse zurückgeben. Die Funktion createShader() sollte eine neue Instanz von QSGMaterialShader zurückgeben, die spezifisch für diese Unterklasse von QSGMaterial ist.

Eine minimale QSGMaterial-Implementierung könnte wie folgt aussehen:

class Material : public QSGMaterial
{
public:
    QSGMaterialType *type() const override { static QSGMaterialType type; return &type; }
    QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const override { return new Shader; }
};

Siehe das Beispiel für benutzerdefiniertes Material für eine Einführung in die Implementierung einer QQuickItem Unterklasse, die durch ein QSGGeometryNode und ein benutzerdefiniertes Material unterstützt wird.

Hinweis: createShader() wird nur einmal pro QSGMaterialType aufgerufen, um redundante Arbeit bei der Shader-Vorbereitung zu reduzieren. Wenn ein QSGMaterial durch mehrere Sätze von Vertex- und Fragment-Shader-Kombinationen unterstützt wird, muss die Implementierung von type() einen anderen, eindeutigen QSGMaterialType Zeiger für jede Kombination von Shadern zurückgeben.

Hinweis: Alle Klassen mit QSG-Präfix sollten nur im Rendering-Thread des Szenegraphs verwendet werden. Siehe Scene Graph und Rendering für weitere Informationen.

Siehe auch QSGMaterialShader, Scene Graph - Custom Material, Scene Graph - Two Texture Providers, und Scene Graph - Graph.

Dokumentation der Mitgliedstypen

enum QSGMaterial::Flag
flags QSGMaterial::Flags

KonstanteWertBeschreibung
QSGMaterial::Blending0x0001Setzt dieses Flag auf true, wenn das Material erfordert, dass das Blending während des Renderings aktiviert ist.
QSGMaterial::RequiresDeterminant0x0002Setzen Sie dieses Flag auf true, wenn das Material beim Rendering auf die Determinante der Matrix der Geometrieknoten angewiesen ist.
QSGMaterial::RequiresFullMatrixExceptTranslate0x0004 | RequiresDeterminantSetzen Sie dieses Flag auf true, wenn das Material die gesamte Matrix der Geometrieknoten für das Rendering verwendet, mit Ausnahme des Translationsteils.
QSGMaterial::RequiresFullMatrix0x0008 | RequiresFullMatrixExceptTranslateSetzen Sie dieses Flag auf true, wenn das Material die gesamte Matrix der Geometrieknoten für das Rendering verwendet.
QSGMaterial::NoBatching0x0010Setzen Sie dieses Flag auf true, wenn das Material Shader verwendet, die nicht mit dem Batching-Mechanismus des Szenegraphen kompatibel sind. Dies ist bei bestimmten fortgeschrittenen Anwendungen relevant, wie z.B. bei der direkten Bearbeitung von gl_Position.z im Vertex-Shader. Solche Lösungen sind oft an eine bestimmte Szenenstruktur gebunden und sind wahrscheinlich nicht sicher für die Verwendung mit beliebigen Inhalten in einer Szene. Daher sollte dieses Flag nur nach entsprechender Prüfung gesetzt werden und wird für die große Mehrheit der Materialien nie benötigt. Das Setzen dieses Flags kann zu Leistungseinbußen führen, da mehr Zeichenaufrufe getätigt werden müssen. Dieses Flag wurde in Qt 6.3 eingeführt.
QSGMaterial::CustomCompileStepNoBatchingIn Qt 6 ist dieses Flag identisch mit NoBatching. Verwenden Sie stattdessen lieber NoBatching.

Der Typ Flags ist ein Typedef für QFlags<Flag>. Er speichert eine OR-Kombination von Flag-Werten.

Dokumentation der Mitgliedsfunktionen

[virtual] int QSGMaterial::compare(const QSGMaterial *other) const

Vergleicht dieses Material mit other und gibt 0 zurück, wenn sie gleich sind; -1, wenn dieses Material vor other sortiert werden soll und 1, wenn other vorher sortiert werden soll.

Der Szenegraph kann Geometrieknoten neu anordnen, um Zustandsänderungen zu minimieren. Die Vergleichsfunktion wird während des Sortiervorgangs aufgerufen, so dass die Materialien sortiert werden können, um Zustandsänderungen bei jedem Aufruf von QSGMaterialShader::updateState() zu minimieren.

Der this-Zeiger und other haben garantiert die gleiche type().

[pure virtual] QSGMaterialShader *QSGMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const

Diese Funktion gibt eine neue Instanz der QSGMaterialShader Implementierung zurück, die zum Rendern von Geometrie für eine bestimmte Implementierung von QSGMaterial verwendet wird.

Die Funktion wird für jede Kombination von Materialtyp und renderMode nur einmal aufgerufen und intern zwischengespeichert.

Für die meisten Materialien kann die renderMode ignoriert werden. Einige wenige Materialien benötigen möglicherweise eine spezielle Behandlung für bestimmte Rendermodi. Zum Beispiel, wenn das Material Antialiasing auf eine Weise implementiert, die perspektivische Transformationen berücksichtigt, wenn RenderMode3D verwendet wird.

QSGMaterial::Flags QSGMaterial::flags() const

Gibt die Flaggen des Materials zurück.

void QSGMaterial::setFlag(QSGMaterial::Flags flags, bool on = true)

Setzt das Attribut flags für dieses Material, wenn on wahr ist; andernfalls wird das Attribut gelöscht.

[pure virtual] QSGMaterialType *QSGMaterial::type() const

Diese Funktion wird vom Szenengraphen aufgerufen, um einen Identifikator abzufragen, der für die durch createShader() instanziierte QSGMaterialShader eindeutig ist.

Für viele Materialien wird der typische Ansatz darin bestehen, einen Zeiger auf eine statische und damit global verfügbare QSGMaterialType -Instanz zurückzugeben. Das QSGMaterialType ist ein undurchsichtiges Objekt. Es dient lediglich als typsicherer, einfacher Weg, um eindeutige Materialbezeichner zu erzeugen.

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

[since 6.8] int QSGMaterial::viewCount() const

Gibt die Anzahl der Ansichten zurück, falls das Material im Multiview-Rendering verwendet wird.

Hinweis: Der Rückgabewert ist nur gültig, wenn er von createShader() aus aufgerufen wird, und danach. Der Wert ist nicht notwendigerweise aktuell, bevor createShader() vom Szenengraphen aufgerufen wird.

Normalerweise lautet der Rückgabewert 1. Eine Anzahl von Ansichten größer als 2 impliziert einen Multiview-Rendering-Durchgang. Von Materialien, die Multiview unterstützen, wird erwartet, dass sie viewCount() in createShader() oder in ihrem QSGMaterialShader Konstruktor abfragen und sicherstellen, dass die entsprechenden Shader ausgewählt werden. Der Vertex-Shader sollte dann gl_ViewIndex verwenden, um das Modelview-Projection-Matrix-Array zu indizieren, da es im Multiview-Modus mehrere Matrizen gibt. (eine für jede Ansicht)

Nehmen wir als Beispiel den folgenden einfachen Vertex-Shader:

#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;
}

Dieser Shader ist darauf vorbereitet, 2 Ansichten zu verarbeiten, und zwar nur 2 Ansichten. Er ist nicht mit anderen Ansichtszahlen kompatibel. Bei der Konditionierung des Shaders muss das Werkzeug qsb mit --view-count 2 aufgerufen werden oder, bei Verwendung der CMake-Integration, muss VIEW_COUNT 2 im Befehl qt_add_shaders() angegeben werden.

Hinweis: Eine Zeile mit #extension GL_EXT_multiview : require wird automatisch von qsb eingefügt, wenn ein View-Count von 2 oder höher eingestellt wird.

Entwicklern wird empfohlen, die automatisch injizierte Präprozessorvariable QSHADER_VIEW_COUNT zu verwenden, um die Handhabung der unterschiedlichen Anzahl von Ansichten zu vereinfachen. Wenn zum Beispiel die Notwendigkeit besteht, sowohl Non-Multiview als auch Multiview mit einer View-Anzahl von 2 in derselben Quelldatei zu unterstützen, könnte folgendes getan werden:

#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;
}

Dieselbe Quelldatei kann nun zweimal durch qsb oder qt_add_shaders() laufen, einmal ohne Angabe der Anzahl der Ansichten und einmal mit der Anzahl der Ansichten auf 2. Das Material kann dann zur Laufzeit die entsprechende .qsb-Datei anhand von viewCount() auswählen.

Mit CMake könnte dies ähnlich wie im Folgenden aussehen. In diesem Beispiel wird erwartet, dass das entsprechende QSGMaterialShader zwischen :/shaders/example.vert.qsb und :/shaders/multiview/example.vert.qsb wählt, basierend auf dem Wert von viewCount(). (dasselbe gilt für den Fragment-Shader)

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
)

Anmerkung: Der Fragment-Shader sollte genauso behandelt werden wie der Vertex-Shader, auch wenn der Fragment-Shader-Code keine Abhängigkeit vom ViewCount (gl_ViewIndex) haben darf, um maximale Portabilität zu gewährleisten. Es gibt zwei Gründe dafür, auch Fragment-Shader in das Multiview-Set aufzunehmen. Zum einen kann die Vermischung verschiedener Shader-Versionen innerhalb derselben Grafik-Pipeline problematisch sein, je nach zugrunde liegender Grafik-API: Bei D3D12 zum Beispiel würde die Vermischung von HLSL-Shadern für das Shader-Modell 5.0 und 6.1 einen Fehler erzeugen. Zum anderen kann es sehr nützlich sein, QSHADER_VIEW_COUNT in Fragment-Shadern definiert zu haben, zum Beispiel wenn ein einheitliches Puffer-Layout zwischen der Vertex- und der Fragment-Stufe geteilt wird.

Anmerkung: Für OpenGL ist die minimale GLSL-Version für Vertex-Shader, die auf gl_ViewIndex angewiesen sind, 330. Niedrigere Versionen können zur Erstellungszeit akzeptiert werden, können aber zur Laufzeit zu einem Fehler führen, abhängig von der OpenGL-Implementierung.

Als Bequemlichkeit gibt es auch eine MULTIVIEW Option für qt_add_shaders(). Diese führt zuerst das qsb Werkzeug normal aus, überschreibt dann VIEW_COUNT auf 2, setzt GLSL, HLSL, MSL auf einige geeignete Standardwerte und führt qsb erneut aus, wobei dieses Mal .qsb Dateien mit einem angefügten Suffix ausgegeben werden. Die Materialimplementierung kann dann die Überladung QSGMaterialShader::setShaderFileName() mit einem Argument viewCount verwenden, das automatisch die richtige .qsb-Datei auswählt.

Der folgende Aufruf ist daher weitgehend äquivalent zu dem oben gezeigten Beispielaufruf, mit der Ausnahme, dass keine manuell verwalteten Ausgabedateien angegeben werden müssen. Beachten Sie, dass es Fälle geben kann, in denen die automatisch ausgewählten Shading-Sprachversionen nicht ausreichen. In diesem Fall sollten Anwendungen weiterhin alles explizit angeben.

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

Siehe QRhi::MultiView, QRhiColorAttachment::setMultiViewCount(), und QRhiGraphicsPipeline::setMultiViewCount() für weitere, tiefergehende Details zur Multiview-Unterstützung in Qt. Der Qt Quick Szenengraphen-Renderer ist darauf vorbereitet, Multiview-Renderziele zu erkennen, wenn sie über QQuickRenderTarget::fromRhiRenderTarget() oder die 3D-API-spezifischen Funktionen wie fromVulkanImage() mit einem arraySize -Argument größer als 1 angegeben werden. Der Renderer wird dann die Anzahl der Ansichten an die Grafikpipelines und die Materialien weitergeben.

Diese Funktion wurde in Qt 6.8 eingeführt.

© 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.