Sur cette page

Qt Quick Scènes 3D avec du contenu 2D

Éléments 2D dans un univers 3D

Qt Quick La 3D permet de créer et de rendre efficacement des scènes combinant des éléments 3D et 2D.

Qu'entend-on par « scène combinée 3D-2D » ?

Par nature, un objet « View3D », représentant une fenêtre d’affichage 3D dans une scène 2D, peut être facilement combiné avec des éléments d’ Qt Quick, tels que Rectangle, Image ou Texte, placés autour, en dessous ou au-dessus de l’objet « View3D », qui est lui-même un Qt Quick Item .

Prenons l'exemple suivant :

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)
            }
        }
    }
}

Cube en 3D avec superposition de texte en 2D

Ici, la scène 3D correspond à la zone avec un fond gris. Le reste de la fenêtre est constitué d’éléments 2D Qt Quick. Ceux-ci peuvent se superposer à l’ View3D, mais ne font pas partie du monde 3D, n’utilisent pas le système de coordonnées 3D et ne participent pas aux transformations de la scène 3D.

Que se passe-t-il si nous souhaitons intégrer des éléments 2D dans l’univers 3D, de manière à ce qu’ils participent véritablement à toutes les transformations 3D ? Par exemple, pouvons-nous placer des éléments « Rectangle » et « Text » au sein de l’univers 3D, de sorte qu’ils suivent la rotation du cube et restent toujours superposés à celui-ci ?

Cube pivoté avec un texte en 2D s'adaptant à la rotation

Dans les sections suivantes, nous verrons comment y parvenir. Bien que l’exemple utilise Rectangle et Text, tout contenu Qt Quick, y compris Qt Quick Controls, Shape, ShaderEffect et ParticleSystem, peut être utilisé de cette manière.

Remarque : il existe également d’autres méthodes pour intégrer du contenu 2D aux objets 3D. L'ajout d'éléments 2D à des nœuds 3D permet de combiner librement les objets 2D et 3D dans l'univers 3D, mais ne permet pas de rendre le contenu 2D à la surface d'un objet 3D. Si l'objectif est d'appliquer une texture à un maillage 3D à l'aide de contenu généré par Qt Quick, utilisez plutôt the sourceItem property ou Texture.

Qt Quick Contenu utilisé comme carte de textureQt Quick éléments de la scène 3D

Cube texturé avec du contenu 2D

Cube contenant des éléments 2D dans une scène 3D

Ajout d’éléments 2D à des nœuds 3D

La clé de cette fonctionnalité réside dans la capacité de Object3D à accepter des objets enfants de type Item et à les traiter de manière spécifique. Object3D est la classe de base du type Node. Cela signifie que tous les types Node, ainsi que des types tels que Model, acceptent des enfants de type Item.

À partir de Qt 6.0, l’ajout d’un élément 2D à un nœud 3D ne déclenche plus le rendu du contenu 2D dans une texture OpenGL, une image Vulkan ou tout autre format similaire. Le mode par défaut consiste désormais à rendre les éléments 2D en ligne avec le reste de la scène 3D, au cours du même passage de rendu. Les éléments 2D subissent toutes les transformations 3D. Ces transformations sont héritées du nœud englobant « Node ».

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)
            }
        }
    }
}

Cube avec un texte en 2D comme élément enfant

Par rapport au premier extrait de code, le nœud « Model » possède désormais un nœud enfant, dont la transformation le place légèrement au-dessus de la position du cube. « 150 » est relative au centre du cube, dans l’espace de coordonnées 3D.

Model {
    Node {
        y: 150

Vient ensuite l’élément « Rectangle ». Lorsqu’on l’ajoute sous un « Node », les frontières entre les mondes 3D et 2D sont franchies en interne, mais cela reste transparent pour le concepteur de l’application. Un « content item » invisible est généré automatiquement, permettant au «Rectangle» de se référer à « parent » et d’effectuer un ancrage. La transformation 3D provenant du «Node» est appliquée à l’ensemble de la sous-arborescence 2D. Dans l’exemple, cela signifie que la rotation correspondra à celle du cube.

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

Espaces de coordonnées en 2D et 3D

Les éléments 2D continuent d’utiliser le système de coordonnées de Qt Quick: l’axe Y s’étend de haut en bas, et les unités correspondent à des pixels. Les nœuds 3D, en revanche, utilisent le système de coordonnées 3D : l’axe Y pointe vers le haut, et les unités correspondent à des centimètres, sous l’effet de la projection en perspective de Camera.

Par défaut, le coin supérieur gauche de l’élément de niveau supérieur est placé à l’origine du nœud. Cela signifie que l’élément de niveau supérieur d’une sous-arborescence 2D devra souvent spécifier un point d’ancrage, par exemple anchors.centerIn: parent, ou, comme dans l’exemple, ancrer le centre horizontal au centre horizontal du parent, centrant ainsi le contenu 2D horizontalement sur le nœud 3D.

Autres considérations

  • Bien que les éléments 2D soient rendus en ligne avec les objets 3D, ils ne participent pas à l’éclairage et ne projettent pas d’ombres.
  • Clipping Le clipping peut ne pas fonctionner comme prévu et doit être évité. Si le clipping est essentiel à la conception des éléments 2D, l’application doit recourir explicitement au rendu sur une texture. Pour ce faire, ajoutez ` layer.enabled: true ` à l’élément de niveau supérieur ` Item ` situé sous le nœud 3D.
  • À partir de Qt 6.2, les entrées sont transmises aux éléments 2D selon les besoins. Les entrées provenant de périphériques de pointage doivent s’effectuer au sein de l’ childrenRect des éléments déclarés.
  • Bien que l’ajout d’une arborescence d’éléments 2D dans la scène 3D soit relativement peu coûteux, il convient d’éviter un nombre excessif (des centaines ou plus) de sous-arborescences 2D au sein de la scène 3D, car en grande quantité, cela peut entraîner une augmentation de l’utilisation de la mémoire et des ressources graphiques. Notez que cela fait référence au nombre de sous-arborescences Item distinctes sous les nœuds 3D, et non au nombre total d’éléments 2D dans ces sous-arborescences. Par exemple, l’extrait de code QML ci-dessus ne contient qu’une seule sous-arborescence 2D.

Voir également Qt Quick 3D - Exemple d’éléments rapides et QQuickItem::mapFromGlobal().

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