Qt Quick 3D Szenen mit 2D-Inhalten

2D-Elemente in einer 3D-Welt

Qt Quick 3D bietet effiziente Erstellung und Rendering von Szenen, die 3D- und 2D-Elemente kombinieren.

Was verstehen wir unter einer kombinierten 3D-2D-Szene?

Ein View3D Objekt, das ein 3D-Ansichtsfenster in der 2D-Szene darstellt, kann naturgemäß leicht mit Qt Quick Elementen wie Rechteck, Bild, Text um, unter oder über dem View3D Element kombiniert werden, das selbst ein Qt Quick Item ist.

Betrachten Sie das folgende Beispiel:

import QtQuick
import QtQuick3D

Rectangle {
    gradient: Gradient {
        GradientStop { position: 0; color: "steelblue" }
        GradientStop { position: 1; color: "black" }
    }
    Text {
        text: "Hello 2D World"
        font.pointSize: 32
        color: "red"
        anchors.top: parent.top
        anchors.horizontalCenter: parent.horizontalCenter
    }
    Item {
        width: 400; height: 400
        anchors.centerIn: parent
        View3D {
            anchors.fill: parent
            environment: SceneEnvironment { backgroundMode: SceneEnvironment.Color; clearColor: "lightGray" }
            PerspectiveCamera { z: 600 }
            DirectionalLight { }
            Model {
                source: "#Cube"
                materials: PrincipledMaterial { baseColor: "green"; metalness: 0.0; roughness: 0.0 }
                eulerRotation: Qt.vector3d(30, 45, 0)
            }
        }
    }
}

Hier ist die 3D-Szene der Bereich mit grauem Hintergrund. Der Rest des Fensters besteht aus 2D-Elementen Qt Quick. Diese können sich mit dem View3D überschneiden, sind aber nicht Teil der 3D-Welt, verwenden nicht das 3D-Koordinatensystem und nehmen nicht an den Transformationen der 3D-Szene teil.

Was ist, wenn wir 2D-Elemente in der 3D-Welt haben wollen, und zwar so, dass sie wirklich an allen 3D-Transformationen teilnehmen? Können wir zum Beispiel Rectangle und Text so in der 3D-Welt platzieren, dass sie der Drehung des Würfels folgen und sich immer über ihm befinden?

In den folgenden Abschnitten werden wir uns ansehen, wie dies erreicht werden kann. Während das Beispiel Rectangle und Text verwendet, kann jeder Qt Quick Inhalt, einschließlich Qt Quick Controls, Shape, ShaderEffect, ParticleSystem, auf diese Weise verwendet werden.

Hinweis: Es gibt auch andere Ansätze, um 2D-Inhalte in 3D-Objekte zu integrieren. Das Hinzufügen von 2D-Elementen zu 3D-Knoten ermöglicht die freie Kombination von 2D- und 3D-Objekten in der 3D-Welt, aber es erlaubt nicht das Rendern des 2D-Inhalts auf der Oberfläche eines 3D-Objekts. Wenn das Ziel darin besteht, ein 3D-Mesh mit Inhalten zu texturieren, die von Qt Quick erzeugt wurden, verwenden Sie stattdessen the sourceItem property von Texture.

Qt Quick Inhalt, der als Textur-Map verwendet wirdQt Quick Elemente in der 3D-Szene

Hinzufügen von 2D-Elementen zu 3D-Knoten

Der Schlüssel dazu ist die Fähigkeit von Object3D, Item Kindobjekte zu akzeptieren und sie auf besondere Weise zu behandeln. Object3D ist die Basisklasse für den Typ Node. Das bedeutet, dass jeder Node und auch Typen wie Model Item Kinder akzeptieren.

Ab Qt 6.0 löst das Hinzufügen eines 2D-Objekts zu einem 3D-Knoten nicht mehr das Rendern des 2D-Inhalts in eine OpenGL-Textur, ein Vulkan-Bild oder ähnliches aus. Stattdessen werden die 2D-Elemente standardmäßig zusammen mit dem Rest der 3D-Szene im selben Renderdurchgang gerendert. Auf die 2D-Elemente werden alle 3D-Transformationen angewendet. Die Transformationen werden vom Wrapping Node geerbt.

import QtQuick
import QtQuick3D

Rectangle {
    gradient: Gradient {
        GradientStop { position: 0; color: "steelblue" }
        GradientStop { position: 1; color: "black" }
    }
    Text {
        text: "Hello 2D World"
        font.pointSize: 32
        color: "red"
        anchors.top: parent.top
        anchors.horizontalCenter: parent.horizontalCenter
    }
    Item {
        width: 400; height: 400
        anchors.centerIn: parent
        View3D {
            anchors.fill: parent
            environment: SceneEnvironment { backgroundMode: SceneEnvironment.Color; clearColor: "lightGray" }
            PerspectiveCamera { z: 600 }
            DirectionalLight { }
            Model {
                Node {
                    y: 150
                    Rectangle {
                        anchors.horizontalCenter: parent.horizontalCenter
                        color: "white"
                        width: text3d.width
                        height: text3d.height
                        Text {
                            id: text3d
                            text: "Hello 3D World"
                            font.pointSize: 32
                        }
                    }
                }
                source: "#Cube"
                materials: PrincipledMaterial { baseColor: "green"; metalness: 0.0; roughness: 0.0 }
                eulerRotation: Qt.vector3d(30, 45, 0)
            }
        }
    }
}

Im Vergleich zum ersten Schnipsel hat der Knoten Model jetzt einen untergeordneten Knoten mit einer Transformation, die ihn etwas oberhalb der Position des Würfels platziert. 150 ist relativ zum Zentrum des Würfels im 3D-Koordinatenraum.

Model {
    Node {
        y: 150

Dann gibt es noch das Element Rectangle. Beim Hinzufügen unter einem Node werden die Grenzen zwischen der 3D- und der 2D-Welt intern überschritten, was aber für den Anwendungsdesigner nicht sichtbar ist. Es wird automatisch ein unsichtbares content item erzeugt, das es dem Rechteck ermöglicht, auf parent zu verweisen und eine Verankerung durchzuführen. Die 3D-Transformation des Knotens wird auf den gesamten 2D-Teilbaum angewendet. In diesem Beispiel bedeutet dies, dass die Drehung mit der Drehung des Würfels übereinstimmt.

Node {
    y: 150
    Rectangle {
        anchors.horizontalCenter: parent.horizontalCenter

Koordinatenräume in 2D und 3D

Die 2D-Elemente verwenden weiterhin das Koordinatensystem von Qt Quick: Die Y-Achse verläuft von oben nach unten, und die Einheiten entsprechen Pixeln. 3D-Knoten hingegen verwenden das 3D-Koordinatensystem: Die Y-Achse zeigt nach oben, und die Einheiten entsprechen Zentimetern, was durch die perspektivische Projektion von Camera beeinflusst wird.

Die linke obere Ecke des obersten Elements befindet sich standardmäßig am Ursprung des Knotens. Das bedeutet, dass das oberste Element in einem 2D-Teilbaum oft einen Anker angeben möchte, z. B. anchors.centerIn: parent, oder, wie in diesem Beispiel, die horizontale Mitte an der horizontalen Mitte des übergeordneten Elements verankern und so den 2D-Inhalt horizontal über dem 3D-Knoten zentrieren.

Weitere Überlegungen

  • Während die 2D-Elemente in-line mit 3D-Objekten wiedergegeben werden, nehmen sie nicht an der Beleuchtung teil und werfen keine Schatten.
  • Clipping Die Funktion "Clipping" funktioniert möglicherweise nicht wie erwartet und sollte vermieden werden. Wenn Clipping für das Design von 2D-Objekten wichtig ist, sollte die Anwendung explizit auf das Rendering auf eine Textur zurückgreifen. Dies kann durch das Hinzufügen von layer.enabled: true auf der obersten Ebene Item unter dem 3D-Knoten erreicht werden.
  • Ab Qt 6.2 werden Eingaben an die 2D-Elemente nach Bedarf übergeben. Eingaben von Zeigegeräten müssen innerhalb der childrenRect der deklarierten Items erfolgen.
  • Während das Hinzufügen eines 2D-Elementbaums in die 3D-Szene recht billig ist, sollten übermäßige Mengen (Hunderte oder mehr) von 2D-Teilbäumen innerhalb der 3D-Szene vermieden werden, da dies in großen Mengen zu einem erhöhten Speicher- und Grafikressourcenverbrauch führen kann. Beachten Sie, dass sich dies auf die Anzahl der separaten Item Teilbäume unter 3D-Knoten bezieht, nicht auf die Gesamtzahl der 2D-Elemente in diesen Teilbäumen. Das obige QML-Snippet enthält beispielsweise nur einen 2D-Teilbaum.

Siehe auch Qt Quick 3D - Quick Items Example und QQuickItem::mapFromGlobal().

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