Sur cette page

Qt 3D: Exemple de wireframe en QML

Une application QML « Qt 3D » qui implémente une méthode de rendu filaire en un seul passage.

Rendu 3D en fil de fer d'un nœud toroïdal rouge avec un maillage triangulaire

Qt 3D Le rendu filaire illustre comment dessiner une seule entité (un nœud trèfle) à l’aide d’un ensemble personnalisé de shaders pour mettre en œuvre une méthode de rendu filaire en un seul passage.

Exécution de l'exemple

Vous pouvez exécuter l’exemple à partir de :

Création d’entités

Le moteur de rendu recherche les entités dotées d’une géométrie, d’un matériau et, éventuellement, d’une transformation. Ces éléments sont tous spécifiés sous la forme de sous-classes de QComponent qui ont été exportées vers le moteur QML sous la forme de Mesh, Material et Transform. Nous utilisons ces composants pour créer un élément QML personnalisé dans TrefoilKnot.qml.

Nous commençons par importer le module Qt3D 2.0, qui fournit le type Entity ainsi que des fonctions d’aide pour les types de valeurs, telles que Qt.vector3d(). Nous importons également le module Qt3D.Renderer, qui fournit les composants et autres types pris en charge par l’aspect « renderer » :

import Qt3D.Core 2.0
import Qt3D.Render 2.0

Pour utiliser des composants provenant d’autres aspects, il faudrait également importer le module QML correspondant.

Nous utilisons ensuite un type « Entity » comme élément racine du type QML personnalisé, exposant ainsi certaines propriétés personnalisées, exactement comme vous le feriez avec n’importe quel autre type en QML :

Entity {
    id: root

    property real x: 0.0
    property real y: 0.0
    property real z: 0.0
    property real scale: 1.0
    property real theta: 0.0
    property real phi: 0.0
    property Material material

Outre l’agrégation de composants, le type ` Entity ` peut être utilisé pour regrouper des objets enfants. Ce fonctionnement est analogue à celui du type ` Item ` dans Qt Quick 2.

Spécification des transformations

Nous instancions un composant ` Transform ` et un composant ` Mesh `. Le composant ` Transform ` spécifie comment le moteur de rendu doit transformer la géométrie lorsqu’elle est dessinée via le pipeline OpenGL. Nous combinons un ensemble ordonné de transformations en un seul composant ` Transform `. Ces informations seront automatiquement mises à la disposition de nos shaders via des variables uniformes nommées standard :

    Transform {
        id: transform
        translation: Qt.vector3d(root.x, root.y, root.z)
        rotation: fromEulerAngles(theta, phi, 0)
        scale: root.scale
    }

Chargement de données dynamiques par sommet

Le composant « Mesh » est très simple. Nous utilisons sa propriété « source » pour charger un ensemble statique de données géométriques (telles que les positions des sommets, les vecteurs normaux et les coordonnées de texture) à partir d’un fichier au format Wavefront Obj. Ces données ont été exportées depuis l’application Blender.

    Mesh {
        id: mesh
        source: "qrc:/assets/obj/trefoil.obj"
    }

Outre l’élément « Mesh », l’ Qt 3D permet également la génération dynamique de données d’attributs par sommet via des hooks C++ appelés par le moteur basé sur les tâches.

Agrégation des composants

Cependant, il ne suffit pas de simplement instancier des composants. Pour qu’ils confèrent un comportement particulier à une entité, celle-ci doit agréger les composants via sa propriété `components` :

    components: [ transform, mesh, root.material ]

Cela permet de partager très facilement des composants entre plusieurs entités. Dans cet exemple, nous disposons de composants pour la transformation et le maillage contenus dans le type personnalisé `TrefoilKnot`. Le dernier composant, de type ` Material`, est fourni par une propriété du type personnalisé `TrefoilKnot`. Nous personnaliserons plus tard l’apparence de l’entité.

Rendu à partir de caméras

Nous utilisons le type personnalisé TrefoilKnot dans main.qml pour dessiner le nœud tréfoil à l’écran.

Nous utilisons les mêmes instructions d’importation que dans TrefoilKnot.qml, en y ajoutant une importation avec espace de noms pour le module Qt Quick dont nous aurons besoin pour les animations :

import QtQuick 2.1 as QQ2
import Qt3D.Core 2.0
import Qt3D.Render 2.0

Nous utilisons un type « Entity » comme type racine simplement pour qu’il serve de parent à ses enfants. En ce sens, le type « Entity » ressemble beaucoup au type « Item » :

import Qt3D.Input 2.0
import Qt3D.Extras 2.0

Entity {
    id: root

Le composant RendererSettings utilise le type ForwardRenderer pour configurer entièrement le moteur de rendu sans toucher au code C++ :

    // Render from the mainCamera
    components: [
        RenderSettings {
            activeFrameGraph: ForwardRenderer {
                id: renderer
                camera: mainCamera
            }
        },
        // Event Source will be set by the Qt3DQuickWindow
        InputSettings { }
    ]

Le type `BasicCamera` est un wrapper trivial autour du type intégré ` Camera `, qui représente une caméra virtuelle. Il dispose de propriétés telles que les plans proche et lointain, le champ de vision, le format d'image, le type de projection, la position et l'orientation :

    BasicCamera {
        id: mainCamera
        position: Qt.vector3d( 0.0, 0.0, 15.0 )
    }

Le type Configuration fournit une solution temporaire permettant de contrôler la caméra à l'aide de la souris, en attendant que l'implémentation appropriée, utilisant les aspects et les composants, soit finalisée :

    FirstPersonCameraController { camera: mainCamera }

Il est très simple d’utiliser plusieurs caméras et de basculer entre elles à l’aide du framegraph pour le rendu de tout ou partie de la scène.

Mappage des matériaux

Qt 3D dispose d’un système de matériaux robuste et très flexible qui permet plusieurs niveaux de personnalisation. Nous utilisons le type personnalisé `WireframeMaterial` pour encapsuler le type ` Material ` :

    WireframeMaterial {
        id: wireframeMaterial
        effect: WireframeEffect {}
        ambient: Qt.rgba( 0.2, 0.0, 0.0, 1.0 )
        diffuse: Qt.rgba( 0.8, 0.0, 0.0, 1.0 )

Nous instancions ensuite le type `TrefoilKnot` et lui attribuons le matériau :

    TrefoilKnot {
        id: trefoilKnot
        material: wireframeMaterial
    }

Le moteur « Qt 3D », associé à l’aspect « renderer », dispose désormais de suffisamment d’informations pour enfin rendre notre maillage à l’aide du matériau que nous avons spécifié.

Utilisation des éléments d’animation

Nous utilisons les éléments d’animation fournis par Qt Quick 2 pour animer les propriétés des types `TrefoilKnot` et `WireframeMaterial`. Les propriétés des composants d’un type sont mises à jour à l’aide du mécanisme de liaison de propriétés QML :

        QQ2.SequentialAnimation {
            loops: QQ2.Animation.Infinite
            running: true

            QQ2.NumberAnimation {
                target: wireframeMaterial;
                property: "lineWidth";
                duration: 1000;
                from: 0.8
                to: 1.8
            }

            QQ2.NumberAnimation {
                target: wireframeMaterial;
                property: "lineWidth";
                duration: 1000;
                from: 1.8
                to: 0.8
            }

            QQ2.PauseAnimation { duration: 1500 }
        }

Les mises à jour de propriétés sont détectées par la classe de base ` QNode ` et automatiquement transmises aux objets correspondants dans l’aspect « renderer ». Le moteur de rendu se charge ensuite de traduire ces mises à jour en nouvelles valeurs pour les variables uniformes dans les programmes de shaders GLSL.

Exécutez l’exemple pour visualiser le nœud en trèfle dont la largeur des lignes du filaire pulse. Tout le travail intensif est effectué par le GPU. Le CPU n’a qu’à exécuter les animations de propriétés et à traduire le graphe de scène et le graphe d’images en appels OpenGL bruts.

Il est également possible d’animer sur le GPU via un programme de shader et un matériau personnalisés.

Exemple de projet sur code.qt.io

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