Auf dieser Seite

Instanziertes Rendering

Einführung

Qt Quick 3D unterstützt die Instanzierung von „ Model “-Objekten. Unter Instanzierung versteht man eine Technik, bei der ein Objekt mit einem einzigen Draw-Call mehrfach gerendert wird. (Beispielsweise die OpenGL-Funktion „ glDrawElementsInstanced “.)

Instancing ermöglicht das Duplizieren eines Modells mit Variationen. Im Gegensatz zur Verwendung eines „ Repeater3D “ werden das Modell und seine Grafikressourcen nur einmal zugewiesen. Das Rendern der duplizierten Instanzen erfolgt auf niedriger Ebene durch die GPU. Je nach Komplexität des Modells kann dies zu einer Leistungssteigerung um mehrere Größenordnungen führen.

In der Praxis erfolgt das Instancing durch die Definition einer Tabelle, die festlegt, wie jede Instanz im Vergleich zum Basismodell modifiziert wird.

Instancing-API

Das Hauptprinzip der Instancing-API besteht darin, dass sie explizit ist: Sie versucht nicht, Möglichkeiten für Instancing innerhalb der bestehenden API automatisch zu erkennen. Stattdessen wird jedes Modell einzeln markiert, indem seine Eigenschaft ` instancing ` so gesetzt wird, dass sie auf ein ` Instancing `-Objekt verweist. Dasselbe `Instancing`-Objekt kann gleichzeitig für mehrere Modelle verwendet werden.

Das Instancing-Objekt gibt eine Tabelle an, die festlegt, wie jede Kopie gerendert wird. Folgende Anpassungen sind möglich:

  • transformation: Position, Rotation und Skalierung
  • Farbe: eine Farbe, die mit dem Material des Modells gemischt wird
  • benutzerdefinierte Daten: Daten, die von benutzerdefinierten Materialien verwendet werden können

Qt stellt drei Qml-Typen zur Verfügung, die von `Instancing` erben:

  • InstanceList listet alle Instanzen auf und ermöglicht die Bindung an die Eigenschaften jeder Instanz.
  • RandomInstancing bietet eine Möglichkeit zum schnellen Testen und Erstellen von Prototypen durch die Generierung zufälliger Instanzen innerhalb definierter Grenzen.
  • FileInstancing Liest eine Instanztabelle aus einer externen Datei ein.

Das Instanzierungsbeispiel zeigt, wie man mithilfe der QML-API eine Szene erstellt.

Andere Arten von Instanztabellen können in C++ durch Unterklassenbildung von ` QQuick3DInstancing` definiert werden. Beispielsweise verwendet der ` particle system ` intern eine eigene Instanztabelle. Diese ist als ` ModelParticle3D.instanceTable` verfügbar.

Durch das Schreiben von benutzerdefiniertem Shader-Code ist es möglich, Instanzierung zur Steuerung zusätzlicher Eigenschaften zu nutzen, wie z. B. Variablen für physikalisch basiertes Rendering, Gewichte für Skelettanimationen, Verzerrungen oder alles andere, was mit benutzerdefinierten Materialien ausgedrückt werden kann. Die benutzerdefinierten Daten in der Instanzierungstabelle bestehen aus vier Gleitkommazahlen.

Das Beispiel für benutzerdefiniertes Instancing zeigt, wie benutzerdefinierte Materialien und eine in C++ implementierte Instanztabelle kombiniert werden können.

Alpha-Blending und Instanzierung

Für korrektes Alpha-Blending müssen halbtransparente Objekte von hinten nach vorne gerendert werden. Aus diesem Grund sortiert „ QtQuick3D “ undurchsichtige und halbtransparente Objekte separat und rendert sie in der richtigen Reihenfolge. Bei der Instanzierung rendert die GPU die Instanzen jedoch in der durch die Instanzierungstabelle festgelegten Reihenfolge, sofern „ depth-sorting “ nicht aktiviert ist. Aus Leistungsgründen sortiert „ QtQuick3D “ die Tabelle standardmäßig nicht, da dies bei einer großen Anzahl von Instanzen sehr lange dauern kann. Das bedeutet, dass die Ergebnisse möglicherweise fehlerhaft aussehen, wenn sich halbtransparente Instanzen gegenseitig oder mit anderen halbtransparenten Objekten überlappen. Im Allgemeinen ist der Fehler bei geringer Deckkraft weniger sichtbar.

Vollständig undurchsichtige Objekte werden zusammen mit nicht überlappenden halbtransparenten Objekten immer korrekt gerendert, da Qt Tiefenpufferprüfungen verwendet, um das Zeichnen hinter undurchsichtigen Objekten zu vermeiden. Das Fehlen einer Sortierung hat jedoch potenzielle Auswirkungen auf die Leistung bei undurchsichtigen Objekten: Sie werden möglicherweise nicht in der optimalen Reihenfolge gerendert, was bedeutet, dass dasselbe Pixel mehrfach geschrieben werden kann, was den Fragment-Shader zusätzlich belastet.

Der Renderer überprüft den Inhalt der Instanztabelle nicht; daher muss explizit angegeben werden, wenn eine Instanztabelle halbtransparente Alpha-Werte enthält: Setze die Eigenschaft „ hasTransparency “ auf „ true “, um sicherzustellen, dass der Renderer das Alpha-Blending aktiviert. Dies gilt für alle Instanzen: Selbst vollständig undurchsichtige Instanzen werden ohne Tiefenprüfung gerendert, was möglicherweise zu sichtbaren Fehlern führt.

Die Renderreihenfolge im Verhältnis zum Rest der Szene kann durch die Einstellung des „ depth bias “ des Modells angepasst werden.

Transformationen und Instanzierung

Jede Instanz verfügt in der Instanztabelle über eine eigene Transformation. Diese wird mit den Transformationen des instanzierten Modells kombiniert. Dies ist etwas komplex, da es mehrere Anwendungsfälle gibt:

  • Eine Transformation am Modell vornehmen, die auf jede einzelne Instanz angewendet wird. Dies ermöglicht ressourcenschonende Animationen, beispielsweise durch gleichzeitiges Drehen aller Instanzen, ohne die Instanztabelle ändern zu müssen.
  • Transformieren der gesamten Instanzgruppe auf einmal.
  • Instanziierung einer Modellhierarchie.

Um all diese Fälle zu unterstützen, wird die Transformation des Modells in zwei Teile aufgeteilt: die lokale Instanztransformation und die globale Instanztransformation. Konzeptionell erfolgt die Instanziierung wie folgt:

  • Zunächst wird das Modell gemäß der lokalen Instanztransformation transformiert.
  • Anschließend wird jede Instanz durch Anwendung der Instanztabellen-Transformation berechnet
  • Schließlich wird die gesamte Gruppe der instanzierten Objekte gemäß der globalen Instanztransformation transformiert.

Standardmäßig besteht die lokale Instanztransformation eines Modells aus der Skalierung und Drehung des Modells, während der Rest in die globale Instanztransformation einfließt.

Dies lässt sich durch die Einstellung der Eigenschaft „ instanceRoot “ des Modells steuern. Diese definiert den Ursprung des Koordinatensystems der Instanz. Am häufigsten wird dies bei der Instanziierung einer Modellhierarchie verwendet. Zum Beispiel bei einer Kugel, die um einen Würfel kreist:

Model {
    id: cube
    instancing: someInstanceTable
    source: "#Cube"
    materials: DefaultMaterial { diffuseColor: "lightgray" }
    Node {
        Model {
            source: "#Sphere"
            instanceRoot: cube
            instancing: cube.instancing
            x: 150
            materials: DefaultMaterial { diffuseColor: "gray" }
        }
        NumberAnimation on eulerRotation.y {
            from: 0
            to: 360
            duration: 4000
            loops: Animation.Infinite
        }
    }
}

Die Eigenschaft „ instanceRoot “ ist erforderlich, um festzulegen, dass die Kugelinstanz so positioniert werden soll, als wäre sie ein Element des Würfels. Jedes Modell in einer Hierarchie muss weiterhin die Eigenschaft „ instancing “ angeben: Im Normalfall sollten alle auf dasselbe „ Instancing “-Objekt gesetzt werden.

instanceRoot kann auch beim Instanzieren eines einzelnen Modells verwendet werden. Zum Beispiel ein Zylinder, der sich um einen außermittigen Punkt dreht:

 Node {
    id: parentNode
    Model {
        source: "#Cylinder"
        instanceRoot: parentNode
        instancing: anotherInstanceTable
        x: 25
        materials: DefaultMaterial { diffuseColor: "white" }
    }
    NumberAnimation on eulerRotation.y {
        from: 0
        to: 360
        duration: 1000
        loops: Animation.Infinite
    }
}

Auswahl und Instanziierung

Picking ist ein Mechanismus, der die Auswahl eines Modells über eine Benutzeroberfläche ermöglicht. Beim instanzierten Rendering gibt es mehrere Darstellungen desselben Modells, sodass das Auswahlergebnis ein ` instance index` enthält. Die instanzierte Auswahl wird durch das Setzen der Eigenschaft ` pickable ` am Basismodell aktiviert.

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