Sur cette page

Qt 3D Présentation

Qt 3D fournit un moteur de rendu entièrement configurable qui permet aux développeurs de mettre rapidement en œuvre n’importe quel pipeline de rendu dont ils ont besoin. De plus, Qt 3D fournit un framework générique pour des simulations en quasi-temps réel allant au-delà du rendu.

Qt 3D est clairement divisé en un noyau et un nombre illimité d’aspects pouvant implémenter toutes les fonctionnalités souhaitées. Les aspects interagissent avec les composants et les entités pour fournir une partie des fonctionnalités. Parmi les exemples d’aspects, on peut citer la physique, l’audio, les collisions, l’intelligence artificielle (IA) et la recherche de chemin.

Fonctionnalités 3D de base

Qt 3D est un framework 3D qui permet de dessiner des formes en 3D et de les déplacer, ainsi que de déplacer la caméra. Il prend en charge les fonctionnalités de base suivantes :

Les matériaux

Qt 3D dispose d’un système de matériaux robuste et très flexible qui permet plusieurs niveaux de personnalisation. Il prend en charge différentes approches de rendu sur différentes plateformes ou versions d’OpenGL, permet plusieurs passes de rendu avec différents ensembles d’états, fournit des mécanismes de remplacement des paramètres à différents niveaux et permet de changer facilement de shader. Tout cela depuis C++ ou à l’aide de liaisons de propriétés QML.

Les propriétés d'un type « Material » peuvent facilement être mappées à des variables uniformes dans un programme de shader GLSL, lui-même spécifié dans la propriété d'effet référencée.

Pour des exemples d’utilisation des matériaux, consultez les exemples suivants :

Shaders

Qt 3D prend en charge toutes les étapes du pipeline de rendu programmable OpenGL : shaders de sommets, de contrôle de tessellation, d’évaluation de tessellation, de géométrie et de fragments. Les shaders de calcul sont prévus pour une prochaine version.

Pour des exemples d'utilisation des shaders, consultez le guide «Qt 3D: Exemple QML de fil de fer ».

Mappage d’ombres

Les ombres ne sont pas directement prises en charge par OpenGL, mais il existe d’innombrables techniques permettant de les générer. Le mappage d’ombres est simple à utiliser pour générer de belles ombres, tout en ayant un coût en termes de performances très faible.

Le shadow mapping est généralement implémenté à l’aide d’un rendu en deux passes. Lors de la première passe, les informations d’ombre sont générées. Lors de la deuxième passe, la scène est générée à l’aide d’une technique de rendu particulière, tout en utilisant les informations recueillies lors de la première passe pour dessiner les ombres.

Le principe du shadow mapping repose sur le fait que seuls les fragments les plus proches de la source lumineuse sont éclairés. Les fragments situés derrière d’autres fragments sont masqués et se trouvent donc dans l’ombre.

Par conséquent, lors du premier passage, la scène est dessinée du point de vue de la source lumineuse. L’information stockée correspond simplement à la distance du fragment le plus proche dans cet espace lumineux. En termes d’OpenGL, cela correspond à disposer d’un Framebuffer Object (FBO) auquel est associée une texture de profondeur. En effet, la distance par rapport à l’œil définit la profondeur, et le test de profondeur par défaut effectué par OpenGL ne stocke en réalité que la profondeur du fragment le plus proche.

Il n’est même pas nécessaire d’associer une texture de couleur, car il n’est pas nécessaire d’ombrer les fragments, mais uniquement de calculer leur profondeur.

L’image suivante présente une scène comportant un plan projetant sa propre ombre et un nœud tréflé :

Une scène rendue en 3D représentant un nœud métallique planant au-dessus d'un avion vert et d'un avion orange volant en arrière-plan

L’image suivante montre une texture de carte d’ombres exagérée de la scène :

Carte de profondeur en niveaux de gris d'un nœud et d'un avion en 3D

L’image indique la profondeur enregistrée lors du rendu de la scène du point de vue de la source lumineuse. Les couleurs plus foncées représentent une faible profondeur (c’est-à-dire plus proche de la caméra). Dans cette scène, la lumière est placée quelque part au-dessus des objets de la scène, du côté droit par rapport à la caméra principale (comparez cela avec la première capture d’écran). Cela correspond au fait que le petit avion est plus proche de la caméra que les autres objets.

Une fois la carte d'ombres générée, on effectue un deuxième passage de rendu. Lors de ce deuxième passage, le rendu est effectué à l'aide de la caméra normale de la scène. N'importe quel effet peut être utilisé ici, comme l'ombrage de Phong. Il est important que l’algorithme de la carte d’ombres soit appliqué dans le shader de fragment. Autrement dit, le fragment le plus proche de la source lumineuse est dessiné éclairé, tandis que les autres fragments sont dessinés dans l’ombre.

La carte d’ombres générée lors de la première passe fournit les informations nécessaires sur la distance des fragments par rapport à la source lumineuse. Il suffit alors de remapper le fragment dans l’espace lumineux, ce qui permet de calculer sa profondeur du point de vue de la source lumineuse, ainsi que l’emplacement de ses coordonnées sur la texture de la carte d’ombres. La texture de la carte d'ombres peut alors être échantillonnée aux coordonnées données et la profondeur du fragment peut être comparée au résultat de l'échantillonnage. Si le fragment est plus éloigné, il est alors dans l'ombre ; dans le cas contraire, il est éclairé.

Rendu par instanciation

L’instanciation est une méthode permettant au GPU de dessiner de nombreuses copies (instances) d’un objet de base qui varie d’une certaine manière pour chaque copie. Souvent, cela concerne la position, l’orientation, la couleur, les propriétés du matériau, l’échelle, etc. Qt 3D fournit une API similaire à l’élément Qt Quick Repeater . Dans ce cas, le délégué est l’objet de base et le modèle fournit les données propres à chaque instance. Ainsi, alors qu’une entité à laquelle est associé un composant « Mesh » est finalement transformée en un appel à `glDrawElements`, une entité dotée d’un composant «instanced» sera convertie en un appel à `glDrawElementsInstanced`.

Le rendu instancié est prévu pour une prochaine version.

Objets de tampon uniformes

Un objet de tampon uniforme (UBO) peut être lié à des programmes de shaders OpenGL afin de rendre facilement accessibles de grandes quantités de données. Les UBO sont généralement utilisés pour des ensembles de paramètres de matériaux ou d’éclairage.

Conseils utiles

Vous trouverez sur cette page des conseils de programmation très utiles pour le rendu 3D : Qt 3D Conseils de rendu professionnels.

Moteur de rendu configurable

Afin de combiner la prise en charge des API C++ et QML avec un moteur de rendu entièrement configurable, le concept de « framegraph » a été introduit. Alors qu’un « scenegraph » est une description, basée sur des données, de ce qu’ il faut rendre, un « framegraph » est une description, basée sur des données, de la manière de le rendre.

Un « framegraph » permet aux développeurs de choisir entre un moteur de rendu direct simple, incluant une passe de remplissage Z, ou d’utiliser par exemple un moteur de rendu différé. Il leur permet également de contrôler le moment où les objets transparents doivent être rendus, etc. Comme tout cela est configuré uniquement à partir de données, il est très facile d’apporter des modifications, même de manière dynamique lors de l’exécution, sans toucher au code C++. Il est possible d’étendre Qt 3D en créant vos propres framegraphs qui implémentent des algorithmes de rendu personnalisés.

Extensions 3D

Au-delà des fonctionnalités essentielles d’affichage de contenu 3D à l’écran, « Qt 3D » est suffisamment extensible et flexible pour accueillir les types d’extensions suivants liés aux objets 3D :

  • Simulation physique
  • Détection de collisions
  • Audio positionnel 3D
  • Animation de corps rigides, de squelettes et de cibles de morphing
  • Calcul d’itinéraires et autres fonctions d’IA
  • Sélection
  • Particules
  • Génération d’objets

Les performances

Qt 3D est conçu pour offrir de bonnes performances et s'adapter au nombre de cœurs de processeur disponibles, car le matériel moderne améliore les performances en augmentant le nombre de cœurs plutôt qu'en augmentant la fréquence d'horloge de base. L'utilisation de plusieurs cœurs fonctionne bien, car de nombreuses tâches sont indépendantes les unes des autres. Par exemple, les opérations effectuées par un module de calcul d'itinéraire ne se chevauchent pas beaucoup avec les tâches effectuées par un moteur de rendu, sauf peut-être lors du rendu d'informations de débogage ou de statistiques.

Qt 3D Architecture

Les principaux cas d’utilisation d’ Qt 3D sont la simulation d’objets en temps quasi réel et le rendu de l’état de ces objets à l’écran. L’exemple Space Invaders contient les objets suivants :

Capture d'écran d'une partie de Space Invaders

  • Le canon au sol du joueur
  • Le sol
  • Les blocs défensifs
  • Les vaisseaux ennemis Space Invaders
  • La soucoupe volante du boss ennemi
  • Les balles tirées par les ennemis et le joueur

Dans une conception C++ traditionnelle, ces types d’objets seraient généralement implémentés sous forme de classes organisées en une sorte d’arborescence d’héritage. Diverses branches de cette arborescence pourraient ajouter des fonctionnalités supplémentaires à la classe racine, notamment pour :

  • Accepter les entrées de l'utilisateur
  • La lecture d’un son
  • Est animé
  • Entre en collision avec d’autres objets
  • S'affiche à l'écran

Les types de l'exemple Space Invaders peuvent être classés en fonction de ces caractéristiques. Cependant, concevoir un arbre d'héritage élégant, même pour un exemple aussi simple, n'est pas chose facile.

Cette approche, ainsi que d'autres variantes de l'héritage, posent un certain nombre de problèmes :

  • Les hiérarchies d'héritage profondes et étendues sont difficiles à comprendre, à maintenir et à étendre.
  • La taxonomie d'héritage est figée au moment de la compilation.
  • Chaque niveau de l'arbre d'héritage des classes ne peut effectuer de classification que selon un seul critère ou axe.
  • Les fonctionnalités communes ont tendance à remonter progressivement dans la hiérarchie des classes au fil du temps.
  • Il est impossible de prédire ce que les développeurs voudront faire.

L’extension d’arbres d’héritage profonds et étendus nécessite généralement de comprendre et d’adhérer à la taxonomie utilisée par l’auteur d’origine. C’est pourquoi « Qt 3D » met l’accent sur l’agrégation plutôt que sur l’héritage comme moyen de conférer des fonctionnalités à une instance d’objet. Plus précisément, « Qt 3D » met en œuvre un système de composants d’entité (ECS).

Utilisation d’un ECS

Dans un ECS, une entité représente un objet simulé, mais en soi, elle est dépourvue de tout comportement ou de toute caractéristique spécifique. Un comportement supplémentaire peut être greffé sur une entité en faisant en sorte que celle-ci agrège un ou plusieurs composants. Chaque composant est une tranche verticale du comportement d’un type d’objet.

Dans l’exemple de Space Invaders, le sol est une entité à laquelle est associé un composant qui indique au système que l’entité doit être affichée et quel type d’affichage elle nécessite. Un vaisseau ennemi d’Space Invaders est une autre entité à laquelle sont associés des composants qui provoquent le rendu du vaisseau, mais lui permettent également d’émettre des sons, d’entrer en collision, d’être animé et d’être contrôlé par une IA simple.

L’entité « canon au sol » du joueur possède des composants en grande partie similaires à ceux du vaisseau ennemi, à l’exception du composant d’IA. À la place, le canon dispose d’un composant d’entrée permettant au joueur de le déplacer et de tirer des balles.

Backend ECS

Schéma illustrant les composants de QEntity

Le backend d’ Qt 3D implémente la partie système du paradigme ECS sous forme d’aspects. Un aspect implémente une tranche verticale spécifique de la fonctionnalité fournie aux entités par une combinaison d’un ou plusieurs de leurs composants agrégés.

Par exemple, l’aspect « rendu » recherche les entités dotées de composants de maillage, de matériau et, éventuellement, de transformation. Si l’aspect « rendu » trouve une telle entité, il sait comment exploiter ces données pour en tirer un rendu esthétique. Si une entité ne dispose pas de ces composants, l’aspect « rendu » l’ignore.

Qt 3D Il construit des entités personnalisées en agrégant des composants qui fournissent des capacités supplémentaires. Le moteur d’ Qt 3D utilise des aspects pour traiter et mettre à jour les entités dotées de composants spécifiques.

Par exemple, un aspect physique recherche des entités dotées d’un composant de volume de collision et d’un autre composant spécifiant les propriétés nécessaires à ce type de simulations, telles que la masse, le coefficient de frottement, etc. Une entité qui émet du son dispose d’un composant indiquant qu’il s’agit d’un émetteur sonore, ainsi que d’un composant précisant quand et quels sons doivent être joués.

Comme l’ECS utilise l’agrégation plutôt que l’héritage, il est possible de modifier dynamiquement le comportement d’un objet lors de l’exécution, simplement en ajoutant ou en supprimant des composants.

Par exemple, pour permettre à un joueur de traverser soudainement les murs après avoir obtenu un bonus, le composant de volume de collision de cette entité peut être temporairement supprimé, jusqu’à l’expiration du bonus. Il n’est pas nécessaire de créer une sous-classe spéciale à usage unique pour l’ PlayerWhoRunsThroughWalls.

Qt 3D Implémentation de l’ECS

Qt 3D implémente l’ECS sous la forme d’une hiérarchie de classes simple. La classe de base de l’ Qt 3D est Qt3DCore::QNode, qui est une sous-classe de QObject. Qt3DCore::QNode ajoute à QObject la capacité de communiquer automatiquement les modifications de propriétés aux aspects, ainsi qu’un identifiant unique dans toute l’application. Les aspects existent dans des threads supplémentaires et Qt3DCore::QNode simplifie le transfert de données entre les objets visibles par l’utilisateur et les aspects.

En règle générale, les sous-classes de Qt3DCore::QNode fournissent des données supplémentaires utilisées par les composants. Par exemple, la classe QShaderProgram spécifie le code GLSL à utiliser lors du rendu d’un ensemble d’entités.

Schéma illustrant les relations entre QEntity, QComponent, QNode et QObject

Dans Qt 3D, les composants sont implémentés en sous-classant Qt3DCore::QComponent et en ajoutant les données nécessaires au bon fonctionnement de l’aspect correspondant. Par exemple, le composant « mesh » est utilisé par l’aspect « renderer » pour récupérer les données par sommet qui doivent être transmises au pipeline OpenGL.

Enfin, Qt3DCore::QEntity est simplement un objet pouvant regrouper zéro ou plusieurs instances de Qt3DCore::QComponent.

Extension Qt 3D

L’ajout de fonctionnalités à Qt 3D, que ce soit dans le cadre de Qt XML ou spécifiquement pour vos propres applications afin de tirer parti du back-end multithread, comprend les tâches suivantes :

  • Identifier et implémenter les composants nécessaires ainsi que les données associées.
  • Enregistrer les composants auprès du moteur QML (uniquement si vous utilisez l’API QML).
  • Créer une sous-classe de `QAbstractAspect` et implémenter les fonctionnalités du sous-système.

Qt 3D Moteur basé sur les tâches

Dans Qt 3D, les aspects sont interrogés à chaque trame afin de déterminer un ensemble de tâches à exécuter ainsi que les dépendances entre celles-ci. Les tâches sont réparties sur tous les cœurs configurés par un planificateur afin d'améliorer les performances.

Qt 3DAspects de xml-ph-0000@deepl.internal

Par défaut, Qt 3D fournit les aspects Qt3DRender et Qt3DInput. Les composants et autres classes de support fournis par ces aspects sont décrits dans la documentation de ces modules.

Des aspects supplémentaires offrant davantage de fonctionnalités seront ajoutés dans les futures versions d’ Qt 3D.

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