Qt Quick 3D Architektur
Qt Quick 3D erweitert Qt Quick, um das Rendering von 3D-Inhalten zu unterstützen. Sie fügt umfangreiche Funktionen hinzu, darunter mehrere neue öffentliche QML-Importe sowie einen neuen internen Szenengraph und Renderer. Dieses Dokument beschreibt die Architektur von Qt Quick 3D, von der öffentlichen API bis hin zu den Details der Rendering-Pipeline.
Modul-Übersicht
Qt Quick 3D besteht aus mehreren Modulen und Plugins, die die zusätzlichen 3D-APIs sowie Dienstprogramme für die Aufbereitung und den Import vorhandener 3D-Assets bereitstellen.
QML-Importe
- QtQuick3D - Der Hauptimport, der alle Kernkomponenten der folgenden Module enthält Qt Quick 3D
- QtQuick3D.AssetUtils - Eine Bibliothek zum Importieren von 3D-Assets zur Laufzeit
- QtQuick3D.Helpers - Eine Bibliothek mit zusätzlichen Komponenten, die bei der Gestaltung von 3D-Szenen und der Fehlersuche verwendet werden können.
C++-Bibliotheken
- QtQuick3D - Das einzige öffentliche C++-Modul. Enthält die Definitionen aller Typen, die dem QtQuick3D QML-Import ausgesetzt sind, sowie einige C++-APIs
- QQuick3DGeometry - Unterklasse zur Erstellung prozeduraler Mesh-Daten
- QQuick3DTextureData - Unterklasse zur Erstellung prozeduraler Texturdaten
- QQuick3D::idealSurfaceFormat - wird verwendet, um das ideale Oberflächenformat zu erhalten
QtQuick3DAssetImport
- Eine interne und private Bibliothek zur Unterstützung des Imports von Assets und zur Konvertierung von Assets in QML.QtQuick3DRuntimeRender
- Eine interne und private Bibliothek, die die Knoten des räumlichen Szenegraphen und den Renderer enthält.QtQuick3DUtils
- Eine interne und private Bibliothek, die als gemeinsame Hilfsbibliothek von allen anderen C++-Modulen verwendet wird.
AssetImporters Plugins
Das Asset-Import-Tooling ist in einer Plugin-basierten Architektur implementiert. Die mit Qt Quick 3D gelieferten Plugins erweitern die Funktionalität der Asset-Importer-Bibliothek und des Tools Balsam.
- Assimp - Dieses Plugin verwendet die Drittanbieter-Bibliothek libAssimp, um 3D-Assets in 3D-Austauschformaten in Qt Quick 3D QML-Komponenten zu konvertieren.
Wie fügt sich Qt Quick 3D in den Qt Graphics Stack ein?
Das obige Diagramm veranschaulicht, wie Qt Quick 3D in den größeren Qt-Grafik-Stack passt. Qt Quick 3D arbeitet als Erweiterung der 2D-API Qt Quick, und wenn 3D-Szenenelemente in Verbindung mit View3D verwendet werden, wird die Szene über das Qt Rendering Hardware Interface (RHI) gerendert. Das RHI übersetzt API-Aufrufe in die richtigen nativen Rendering-Hardware-API-Aufrufe für eine bestimmte Plattform. Das obige Diagramm zeigt die für jede Plattform verfügbaren Optionen. Wenn kein natives Backend explizit definiert ist, wählt Qt Quick standardmäßig ein sinnvolles natives Backend für das Rendering für jede Plattform.
Die Integration zwischen den Qt Quick 3D Komponenten des Stacks und dem Qt Quick Stack wird in den nächsten Abschnitten beschrieben.
3D in 2D-Integration
Die Anzeige von 3D-Inhalten in 2D ist der Hauptzweck der Qt Quick 3D API. Die primäre Schnittstelle für die Integration von 3D-Inhalten in 2D ist die Komponente View3D.
Die Komponente View3D funktioniert wie jede andere QQuickItem abgeleitete Klasse mit Inhalt und implementiert die virtuelle Funktion QQuickItem::updatePaintNode. Qt Quick ruft updatePaintNode für alle "schmutzigen" Elemente im Qt Quick Szenegraphen während der Synchronisierungsphase auf. Dazu gehören auch die 3D-Elemente, die von einer View3D verwaltet werden und deren Synchronisationsphase ebenfalls durch den updatePaintNode-Aufruf ausgelöst wird.
Die updatePaintNode-Methode von View3D führt die folgenden Aktionen durch:
- Einrichten eines Renderers und eines Renderziels, falls noch keines vorhanden ist
- Synchronisieren von Elementen in der 3D-Szene über den SceneManager
- Aktualisieren aller "dynamischen" Texturen, die von Qt Quick gerendert wurden(2D im 3D-Texturpfad unten)
Das Rendering der 3D-Szene findet jedoch nicht in der Methode View3D updatePaintNode statt. Stattdessen gibt updatePaintNode eine QSGNode -Unterklasse zurück, die den Renderer für Qt Quick 3D enthält, der die 3D-Szene während der Vorverarbeitungsphase des Rendervorgangs von Qt Quick rendern wird.
Die Art und Weise, wie Qt Quick 3D gerendert wird, hängt davon ab, welche View3D::renderMode verwendet wird:
Offscreen
Der Standardmodus für View3D ist Offscreen. Im Offscreen-Modus wird View3D zum Texturanbieter, indem eine Offscreen-Oberfläche erstellt und darauf gerendert wird. Diese Oberfläche kann als Textur in Qt Quick abgebildet und mit QSGSimpleTextureNode gerendert werden.
Dieses Muster kommt der Funktionsweise von QSGLayerNodes in Qt Quick sehr nahe.
Unterlegen
Im Modus Underlay wird die 3D-Szene direkt auf QQuickWindow gerendert, das View3D enthält. Das Rendering erfolgt als Ergebnis des Signals QQuickWindow::beforeRenderPassRecording(), was bedeutet, dass alles andere in Qt Quick über den 3D-Inhalt gerendert wird.
Überlagerung
Im Modus Overlay wird die 3D-Szene direkt auf die QQuickWindow gerendert, die die View3D enthält. Das Rendering erfolgt als Ergebnis des Signals QQuickWindow::afterRenderPassRecording(), was bedeutet, dass der 3D-Inhalt über allen anderen Qt Quick -Inhalten gerendert wird.
Inline
Der Rendermodus Inline verwendet QSGRenderNode, was ein direktes Rendering auf das Renderziel von Qt Quick ermöglicht, ohne eine Offscreen-Oberfläche zu verwenden. Dazu werden die Render-Befehle während des 2D-Renderings der Qt Quick -Szene inline eingefügt.
Dieser Modus kann problematisch sein, da er denselben Tiefenpuffer wie der Qt Quick Renderer verwendet und z-Werte in Qt Quick und Qt Quick 3D völlig unterschiedliche Bedeutungen haben.
2D in 3D-Integration
Beim Rendern einer 3D-Szene gibt es viele Szenarien, in denen 2D-Elemente in 3D eingebettet werden müssen. Es gibt zwei verschiedene Möglichkeiten, 2D-Inhalte in 3D-Szenen zu integrieren, und jede davon hat ihren eigenen Weg zum Bildschirm.
Direkter Weg
Der direkte Pfad wird verwendet, um 2D-Inhalte Qt Quick so darzustellen, als ob sie als flaches Element in der 3D-Szene vorhanden wären. Betrachten Sie zum Beispiel die folgende Szenendefinition:
Node {
Text {
text: "Hello world!"
}
}
Wenn eine untergeordnete Komponente auf einen räumlichen Knoten vom Typ QQuickItem gesetzt wird, wird sie zunächst von einem QQuick3DItem2D umhüllt, der lediglich ein Container ist, der einem 2D-Element 3D-Koordinaten hinzufügt. Dadurch wird die 3D-Basistransformation für die Darstellung aller weiteren 2D-Kinder festgelegt, damit sie in der 3D-Szene korrekt erscheinen.
Wenn es an der Zeit ist, die Szene zu rendern, werden die QSGNodes dieser 2D-Elemente an den Qt Quick Renderer übergeben, um die entsprechenden Renderbefehle zu generieren. Da die Befehle inline ausgeführt werden und die aktuelle 3D-Transformation berücksichtigen, werden sie genau so gerendert wie im 2D-Renderer, erscheinen aber so, als wären sie in 3D gerendert worden.
Der Nachteil dieses Ansatzes ist, dass keine Beleuchtungsinformationen der 3D-Szene verwendet werden können, um den 2D-Inhalt zu schattieren, da der Qt Quick 2D-Renderer kein Konzept für die Beleuchtung hat.
Texturpfad
Der Texturpfad verwendet eine 2D-Szene Qt Quick, um dynamische Texturinhalte zu erstellen. Betrachten Sie die folgende Texturdefinition:
Texture { sourceItem: Item { width: 256 height: 256 Text { anchors.centerIn: parent text: "Hello World!" } } }
Dieser Ansatz funktioniert auf die gleiche Weise wie die Layer-Elemente in Qt Quick, indem alles auf eine Offscreen-Fläche in der Größe des Top-Level-Elements gerendert wird und diese Offscreen-Fläche dann als Textur verwendet werden kann, die an anderer Stelle wiederverwendet werden kann.
Diese Textur kann dann von Materialien in der Szene verwendet werden, um Qt Quick Inhalte auf Elementen zu rendern.
Synchronisierung von Szenen
Szenenmanager
Der Szenenmanager in Qt Quick 3D ist dafür verantwortlich, die räumlichen Elemente in einer 3D-Szene zu verfolgen und sicherzustellen, dass die Elemente während der Synchronisierungsphase ihre entsprechenden Szenengraphknoten aktualisieren. In Qt Quick wird diese Aufgabe von QQuickWindow für den 2D-Fall übernommen. Der Szenenmanager ist die primäre Schnittstelle zwischen den Frontend-Knoten und den Backend-Szenengraph-Objekten.
Jedes Element von View3D verfügt über mindestens einen Szenenmanager, da bei der Erstellung ein solcher erstellt und mit der eingebauten Szenenwurzel verknüpft wird. Wenn räumliche Knoten als Kinder von View3D hinzugefügt werden, werden sie beim Szenenmanager von View3D registriert. Bei Verwendung einer importierten Szene wird ein zweiter SceneManager erstellt (oder referenziert, falls bereits einer vorhanden ist), um die Knoten zu verwalten, die keine direkten Kinder der View3D sind. Dies ist erforderlich, da eine importierte Szene im Gegensatz zur View3D nicht auf einer QQuickWindow existiert, bis sie referenziert wird. Der zusätzliche SceneManager stellt sicher, dass Assets, die zur importierten Szene gehören, mindestens einmal pro QQuickWindow erstellt werden, in der sie referenziert werden.
Obwohl der SceneManager eine interne API ist, ist es wichtig zu wissen, dass der SceneManager dafür verantwortlich ist, updateSpatialNode für alle Objekte aufzurufen, die durch den Aufruf der update()-Methode als dirty markiert wurden.
Frontend/Backend-Synchronisation
Das Ziel der Synchronisation ist es, sicherzustellen, dass die auf dem Frontend (Qt Quick) eingestellten Zustände mit denen auf dem Backend (Qt Quick Spatial Scene Graph Renderer) übereinstimmen. Standardmäßig laufen das Frontend und das Backend in getrennten Threads: das Frontend im Qt Main Thread und das Backend im Qt Quick's Render Thread. Die Synchronisationsphase ist die Phase, in der der Haupt-Thread und der Render-Thread sicher Daten austauschen können. Während dieser Phase ruft der Szenenmanager updateSpatialNode für jeden verschmutzten Knoten in der Szene auf. Dadurch wird entweder ein neuer Backend-Knoten erstellt oder ein vorhandener Knoten zur Verwendung durch den Renderer aktualisiert.
Qt Quick Spatial Scene Graph
Qt Quick 3D ist so konzipiert, dass es das gleiche Frontend/Backend-Trennungsmuster wie Qt Quick verwendet: Frontend-Objekte werden von der Engine Qt Quick gesteuert, während Backend-Objekte Zustandsdaten für das Rendern der Szene enthalten. Frontend-Objekte erben von QObject und werden der Qt Quick -Engine zur Verfügung gestellt. Elemente in QML-Quelldateien werden direkt auf Frontend-Objekte abgebildet.
Wenn die Eigenschaften dieser Frontend-Objekte aktualisiert werden, werden ein oder mehrere Backend-Knoten erstellt und in einem Szenengraph platziert. Da das Rendern von 3D-Szenen viel mehr Zustände erfordert als das Rendern von 2D-Szenen, gibt es einen separaten Satz spezialisierter Szenegraph-Knoten, die den Zustand der 3D-Szenenobjekte darstellen. Dieser Szenegraph ist als Qt Quick Spatial Scene Graph bekannt.
Sowohl die Frontend-Objekte als auch die Backend-Knoten können in zwei Klassen eingeteilt werden. Die ersten sind räumlich, in dem Sinne, dass sie irgendwo im 3D-Raum existieren. In der Praxis bedeutet dies, dass jeder dieser Typen eine Transformationsmatrix enthält. Bei räumlichen Elementen ist die Eltern-Kind-Beziehung von Bedeutung, da jedes untergeordnete Element die Transformation seiner Eltern erbt.
Die andere Klasse von Elementen sind Ressourcen. Ressourcenelemente haben keine Position im 3D-Raum, sondern sind lediglich ein Zustand, der von anderen Elementen verwendet wird. Zwischen diesen Elementen kann eine Eltern-Kind-Beziehung bestehen, die jedoch keine andere Bedeutung als die des Eigentums hat.
Im Gegensatz zum 2D-Szenengraph in Qt Quick zeigt der räumliche Szenengraph dem Benutzer die Ressourcenknoten direkt an. So gibt es z. B. in Qt Quick, obwohl QSGTexture eine öffentliche API ist, kein QQuickItem, das dieses Objekt direkt zugänglich macht. Stattdessen muss der Benutzer entweder ein Bildelement verwenden, das sowohl beschreibt, woher die Textur kommt, als auch, wie sie gerendert wird, oder er muss C++-Code schreiben, um mit QSGTexture selbst zu arbeiten. In Qt Quick 3D sind diese Ressourcen direkt in der QML-API verfügbar. Dies ist notwendig, weil Ressourcen ein wichtiger Teil des Szenenstatus sind. Diese Ressourcen können von vielen Objekten in der Szene referenziert werden: zum Beispiel können viele Materialien die gleiche Textur verwenden. Es ist auch möglich, zur Laufzeit Eigenschaften einer Textur festzulegen, die z. B. die Art und Weise, wie eine Textur abgetastet wird, direkt verändern würden.
Spatial-Objekte
Alle räumlichen Objekte sind Unterklassen der Komponente Node, die die Eigenschaften enthält, die die Position, die Drehung und die Skalierung im 3D-Raum definieren.
Ressourcen-Objekte
Ressourcenobjekte sind Unterklassen der Komponente Object3D. Object3D ist lediglich eine Unterklasse von QObject mit einigen speziellen Hilfsfunktionen für die Verwendung mit dem Szenenmanager. Ressourcenobjekte haben Eltern-Kind-Verknüpfungen, die jedoch hauptsächlich für den Besitz von Ressourcen nützlich sind.
- Texture
- TextureData
- Geometry
- Material
- DefaultMaterial
- PrincipledMaterial
- CustomMaterial
- Effect
- SceneEnvironment
View3D und Render-Ebenen
Im Hinblick auf die Trennung von Frontend und Backend ist View3D der Trennungspunkt aus der Benutzerperspektive, da View3D den zu rendernden Szeneninhalt definiert. Im Qt Quick Spatial Scene Graph ist der Wurzelknoten für eine Szene, die gerendert werden soll, ein Layer-Knoten. Ebenenknoten werden von View3D unter Verwendung einer Kombination aus den Eigenschaften von View3D und den Eigenschaften von SceneEnvironment erstellt. Beim Rendern einer Szene für View3D wird dieser Ebenenknoten an den Renderer zum Rendern einer Szene übergeben.
Rendering einer Szene
Rendering-Ziel einrichten
Der erste Schritt im Rendering-Prozess besteht darin, das Renderziel der Szene zu bestimmen und einzurichten. Je nachdem, welche Eigenschaften in der SceneEnvironment eingestellt sind, variiert das tatsächliche Renderziel. Die erste Entscheidung ist, ob der Inhalt direkt auf eine Fensteroberfläche oder auf eine Offscreen-Textur gerendert wird. Standardmäßig rendert View3D in eine Offscreen-Textur. Bei der Verwendung von Nachbearbeitungseffekten ist das Rendering in eine Offscreen-Textur obligatorisch.
Sobald ein Rendering-Ziel für die Szene festgelegt ist, werden einige globale Zustände gesetzt.
- Fenstergröße - wenn in ein Fenster gerendert wird
- Viewport - die Größe des gerenderten Szenenbereichs
- scissor rect - die Teilmenge eines Fensters, auf die das Ansichtsfenster zugeschnitten werden soll
- clear color - die Farbe, mit der das Rendering-Ziel ggf. gelöscht werden soll.
Vorbereiten des Renderns
Die nächste Phase des Rendervorgangs ist die Vorbereitungsphase, in der der Renderer herausfindet, was für ein bestimmtes Bild gerendert werden muss und dass alle erforderlichen Ressourcen verfügbar und auf dem neuesten Stand sind.
Die Vorbereitungsphase selbst hat zwei Phasen: die Vorbereitung auf hoher Ebene, bei der bestimmt wird, was gerendert werden soll und welche Ressourcen benötigt werden, und die Vorbereitung auf niedriger Ebene, bei der RHI verwendet wird, um Rendering-Pipelines und Puffer einzurichten und die Rendering-Abhängigkeiten des Haupt-Szenendurchlaufs einzurichten.
Rendervorbereitung auf hoher Ebene
Der Zweck dieser Phase besteht darin, den Zustand des räumlichen Szenengraphs in etwas zu extrahieren, das für die Erstellung von Renderbefehlen verwendet werden kann. Der Renderer erstellt Listen von Geometrie- und Materialkombinationen, die aus der Perspektive einer einzelnen Kamera mit einer Reihe von Beleuchtungszuständen gerendert werden sollen.
Als erstes wird der globale gemeinsame Zustand für alle Inhalte bestimmt. Wenn SceneEnvironment eine lightProbe definiert, wird geprüft, ob die mit der Lichtsondentextur verbundene Umgebungskarte geladen ist, und wenn nicht, wird eine neue Umgebungskarte geladen oder erzeugt. Die Erzeugung einer Environment Map besteht aus einer Reihe von Durchläufen, um die Ausgangstextur in eine Cube Map zu falten. Diese Cube Map enthält sowohl Informationen über die Spiegelung als auch über die Bestrahlungsstärke, die für die Materialschattierung verwendet wird.
Als nächstes muss der Renderer bestimmen, welche Kamera in der Szene verwendet werden soll. Wenn eine aktive Kamera nicht explizit durch eine View3D definiert ist, wird die erste in der Szene verfügbare Kamera verwendet. Sind keine Kameras in der Szene vorhanden, wird kein Inhalt gerendert und der Renderer bricht ab.
Wenn eine Kamera bestimmt wurde, kann die Projektionsmatrix für dieses Bild berechnet werden. Die Berechnung erfolgt zu diesem Zeitpunkt, da jedes Renderable wissen muss, wie es projiziert werden soll. Dies bedeutet auch, dass nun berechnet werden kann, welche renderbaren Elemente gerendert werden sollen. Ausgehend von der Liste aller darstellbaren Elemente werden alle Elemente entfernt, die nicht sichtbar sind, weil sie entweder deaktiviert oder vollständig transparent sind. Wenn das "Frustum Culling" für die aktive Kamera aktiviert ist, wird jedes renderbare Element daraufhin überprüft, ob es sich vollständig außerhalb des Sichtfelds des Kamerastumpfs befindet, und wenn ja, wird es aus der Liste der renderbaren Elemente entfernt.
Zusätzlich zur Kameraprojektion wird auch die Kamerarichtung berechnet, da diese für die Beleuchtungsberechnungen im Schattierungscode erforderlich ist.
Wenn Lichtknoten in der Szene vorhanden sind, werden diese in einer Liste mit der Länge der maximal verfügbaren Lichter zusammengefasst. Wenn mehr Lichtknoten in der Szene vorhanden sind, als der Renderer unterstützt, werden alle zusätzlichen Lichtknoten über dieser Grenze ignoriert und tragen nicht zur Beleuchtung der Szene bei. Es ist möglich, den Geltungsbereich von Lichtknoten festzulegen, aber beachten Sie, dass auch beim Festlegen eines Geltungsbereichs der Beleuchtungsstatus jedes Lichts immer noch an jedes Material gesendet wird, das eine Beleuchtung hat, aber für Lichter, die nicht im Geltungsbereich sind, wird die Helligkeit auf 0 gesetzt, so dass diese Lichter in der Praxis nicht zur Beleuchtung dieser Materialien beitragen werden.
Mit einer hoffentlich kürzeren Liste von Renderables muss nun jedes dieser Elemente aktualisiert werden, um den aktuellen Zustand der Szene wiederzugeben. Für jedes Renderable wird geprüft, ob ein geeignetes Material geladen ist, und wenn nicht, wird ein neues erstellt. Ein Material ist eine Kombination aus Shadern und einer Rendering-Pipeline und wird für die Erstellung eines Zeichenaufrufs benötigt. Darüber hinaus stellt der Renderer sicher, dass alle Ressourcen, die zum Rendern eines Renderables benötigt werden, geladen sind, z. B. Geometrie und Texturen, die auf dem Modell eingestellt sind. Ressourcen, die noch nicht geladen sind, werden hier geladen.
Die Liste der Renderables wird dann in 3 Listen sortiert.
- Undurchsichtige Elemente: Diese werden von vorne nach hinten sortiert, oder anders gesagt, von Elementen, die der Kamera am nächsten sind, zu Elementen, die am weitesten von der Kamera entfernt sind. Dies geschieht, um die Vorteile des Hardware-Occlusion Culling oder der frühen Z-Erkennung im Fragment-Shader zu nutzen.
- 2D-Objekte: Dies sind QtQuick Objekte, die vom Qt Quick Renderer gerendert werden.
- Transparente Objekte: Diese werden von hinten nach vorne sortiert, d. h. von Objekten, die am weitesten von der Kamera entfernt sind, zu Objekten, die der Kamera am nächsten sind. Dies geschieht, weil transparente Elemente mit allen Elementen, die sich hinter ihnen befinden, überblendet werden müssen.
Low-Level-Rendervorbereitung
Nachdem nun alles, was für dieses Bild berücksichtigt werden muss, festgelegt wurde, können die Leitungen und Abhängigkeiten für den Haupt-Rendervorgang in Angriff genommen werden. Als erstes werden in dieser Phase alle Vorläufe gerendert, die für den Hauptdurchlauf erforderlich sind.
- Rendering DepthPass - Bestimmte Funktionen wie Screen Space Ambient Occlusion und Shadowing erfordern einen Tiefen-Pre-Pass. In diesem Durchgang werden alle undurchsichtigen Elemente in eine Tiefentextur gerendert.
- Render SSAOPass - Das Ziel des Screen Space Ambient Occlusion Passes ist es, eine Ambient Occlusion Textur zu generieren. Diese Textur wird später von Materialien verwendet, um bestimmte Bereiche beim Schattieren abzudunkeln.
- Render ShadowPasses - Jedes Licht in der Szene, für das Schatten aktiviert ist, trägt zu einem zusätzlichen Shadow-Pass bei. Der Renderer verwendet zwei verschiedene Schattentechniken, so dass es je nach Lichttyp unterschiedliche Durchgänge gibt. Wenn Schatten von einem gerichteten Licht gerendert werden, wird die Szene in eine 2D-Okklusions-Textur aus einer Kombination aus der Richtung des gerichteten Lichts und der Größe des Kamerastumpfes gerendert. Wenn Schatten von einem Punkt- oder Spotlicht gerendert werden, ist die Okklusionstextur des Lichts eine Würfelkarte, die den Okklusionsbeitrag relativ zu jeder Flächenrichtung des Lichts darstellt.
- Render ScreenTexture - Dieser Pass wird nur ausgeführt, wenn eine CustomMaterial verwendet wird, die eine Bildschirmtextur erfordert, die für Rendering-Techniken wie Brechung verwendet werden kann. Dieser Durchgang funktioniert wie ein Tiefenpass, rendert aber stattdessen alle undurchsichtigen Elemente in eine Farbtextur.
Nach dem Rendering der Abhängigkeiten werden die übrigen Durchläufe vorbereitet, aber nicht gerendert. Bei dieser Vorbereitung wird der in der High-Level-Vorbereitungsphase gesammelte Status in Grafikprimitive übersetzt, wie z. B. das Erstellen/Aktualisieren einheitlicher Pufferwerte, das Zuordnen von Samplern zu Abhängigkeitstexturen, das Einrichten von Shader-Ressourcenbindungen und alles andere, was zum Erstellen eines Pipeline-Status erforderlich ist, um einen Zeichenaufruf durchzuführen.
Rendering der Szene
Nun, da die harte Arbeit der Vorbereitung erledigt ist, ist der einfache Teil die Ausführung der Befehle, die zum Inhalt der Hauptszene beitragen. Das Rendering funktioniert in dieser Reihenfolge:
- Clear Pass - Dies ist nicht wirklich ein Durchgang, aber je nachdem, welcher backgroundMode auf SceneEnvironment eingestellt ist, können hier verschiedene Dinge passieren. Wenn der Hintergrundmodus entweder transparent oder farbig ist, wird der Farbpuffer entweder mit der Transparenz oder der angegebenen Farbe geleert. Ist der Hintergrundmodus jedoch auf SkyBox eingestellt, wird ein Durchgang ausgeführt, der die SkyBox aus der Kameraperspektive rendert, wodurch auch der Puffer mit den ursprünglichen Daten gefüllt wird.
- Opaque Pass - Als nächstes werden alle opaken Elemente gezeichnet. Dabei wird lediglich der Pipeline-Status gesetzt und der Zeichenbefehl für jedes Element in der Reihenfolge der Liste ausgeführt, da sie zu diesem Zeitpunkt bereits sortiert sind.
- 2D-Durchlauf - Wenn es 2D-Elemente in der Szene gibt, wird der Renderer Qt Quick aufgerufen, um die Renderbefehle zu generieren, die zum Rendern dieser Elemente erforderlich sind.
- Transparent Pass - Schließlich werden die transparenten Elemente in der Szene eines nach dem anderen auf dieselbe Weise gerendert wie die undurchsichtigen Elemente.
Damit ist das Rendering der Szene abgeschlossen.
Nachbearbeitung
Wenn eine Nachbearbeitungsfunktion aktiviert ist, kann davon ausgegangen werden, dass das Ergebnis des Szenenrenderers eine Textur ist, die als Input für die Nachbearbeitungsphase dient. Alle Nachbearbeitungsmethoden sind zusätzliche Durchläufe, die auf dieser Szeneneingabetextur arbeiten.
Alle Schritte der Nachbearbeitungsphase sind optional, und wenn keine eingebauten Funktionen und keine benutzerdefinierten Effekte aktiviert sind, ist die Ausgabe des Szenenrenders das, was vom endgültigen Renderingziel verwendet wird. Beachten Sie jedoch, dass tonemapping standardmäßig aktiviert ist.
Integriertes Post-Processing
ExtendedSceneEnvironment und sein übergeordneter Typ SceneEnvironment bieten die gängigsten Effekte, die in 3D-Szenen verwendet werden, sowie Tonemapping, das verwendet wird, um die vom Renderer erzeugten Farbwerte mit hohem Dynamikbereich auf den LDR-Bereich 0-1 zu übertragen. Zu den Effekten gehören Tiefenschärfe, Glühen/Blühen, Lens Flare, Vignette, Farbanpassung und -abstufung, Nebel und Umgebungsokklusion.
Nachbearbeitungseffekte
Anwendungen können ihre eigenen benutzerdefinierten Nachbearbeitungseffekte in Form einer geordneten Liste in der Eigenschaft SceneEnvironment::effects angeben. Wenn diese Liste nicht leer ist, werden die darin enthaltenen Effekte vor den integrierten Effekten von ExtendedSceneEnvironment angewendet. Jeder Nachbearbeitungseffekt ist Teil einer Kette, bei der die Ausgabe des vorherigen Effekts die Eingabe für den nächsten ist. Der erste Effekt in dieser Kette erhält seine Eingabe direkt von der Ausgabe des Szenen-Rendering-Schrittes. Es ist auch möglich, dass Effekte auf die Ausgabe der Tiefentextur des Szenenrenderers zugreifen.
Jeder Effekt in diesem Prozess kann aus mehreren Sub-Passes bestehen, was bedeutet, dass es möglich ist, Inhalte in Zwischenpuffern zu rendern. Der letzte Durchlauf eines Effekts mit mehreren Durchläufen wird voraussichtlich eine einzige Textur ausgeben, die die Farbdaten enthält, die von den nächsten Schritten der Nachbearbeitungsphase verwendet werden.
Zeitliches und progressives Antialiasing
Die Antialiasing-Schritte "Temporal" und "Progressiv" werden optional durch die Einstellung von Eigenschaften in SceneEnvironment aktiviert. Obwohl sie nicht streng genommen Teil der Nachbearbeitungsphase sind, werden die tatsächlichen Ergebnisse des temporären und progressiven Antialiasing während der Nachbearbeitungsphase realisiert.
Temporales Antialiasing wird durchgeführt, wenn eine Szene aktiv aktualisiert wird. Wenn diese Funktion aktiviert ist, nimmt die aktive Kamera beim Zeichnen der Szene für jedes Bild sehr kleine Anpassungen an der Kamerarichtung vor. Der aktuelle Frame wird dann mit dem zuvor gerenderten Frame gemischt, um das Gerenderte zu glätten.
Progressive Antialiasing wird nur durchgeführt, wenn eine Szene nicht aktualisiert wird. Wenn diese Option aktiviert ist, wird eine Aktualisierung erzwungen und der aktuelle Zustand der Szene wird mit sehr kleinen Anpassungen an die Richtung der aktiven Kamera gerendert. Bis zu 8 Bilder werden akkumuliert und mit vordefinierten Gewichten zusammengemischt. Dies hat den Effekt, dass eine nicht animierte Szene geglättet wird, geht aber zu Lasten der Leistung, da bei jeder Aktualisierung mehrere zusätzliche Bilder gerendert werden.
Super Sampling Antialiasing (SSAA)
Super Sampling Antialiasing ist eine brachiale Methode zur Glättung einer Szene. Dabei wird eine Textur gerendert, die ein Vielfaches der angeforderten Größe der Szene ist, und anschließend auf die Zielgröße heruntergesampelt. Wenn also zum Beispiel 2X SSAA angefordert wird, wird die Szene auf eine Textur gerendert, die das Zweifache der gewünschten Größe hat, und dann als Teil dieser Phase heruntergerechnet. Dies kann enorme Auswirkungen auf die Leistung und die Ressourcennutzung haben und sollte daher nach Möglichkeit vermieden werden. Es ist auch möglich, dass die Größe von View3D zu groß ist, um diese Methode zu verwenden, da die für diese Methode benötigte Textur größer sein kann, als von der Rendering-Hardware unterstützt wird.
© 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.