Sur cette page

Qt 3D Vue d'ensemble

Qt 3D RHI fournit un moteur de rendu entièrement configurable qui permet aux développeurs d'implémenter rapidement tout pipeline de rendu dont ils ont besoin. De plus, Qt 3D fournit un cadre générique pour les simulations en temps quasi-réel au-delà du rendu.

Qt 3D Le système de simulation en temps quasi-réel est clairement séparé en un noyau et un nombre quelconque d'aspects qui peuvent mettre en œuvre toutes les fonctionnalités qu'ils souhaitent. Les aspects interagissent avec les composants et les entités pour fournir une partie de la fonctionnalité. 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 cadre 3D qui permet de dessiner des formes 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 s'adapte à différentes approches de rendu sur différentes plates-formes ou versions d'OpenGL, permet plusieurs passes de rendu avec différents ensembles d'états, fournit des mécanismes pour la surcharge des paramètres à différents niveaux et permet de changer facilement de shaders. Tout cela à partir de C++ ou en utilisant les liaisons de propriétés QML.

Les propriétés d'un type Material peuvent facilement être mises en correspondance avec des variables uniformes dans un programme de nuanceur GLSL qui est lui-même spécifié dans la propriété d'effet référencée.

Pour des exemples d'utilisation de matériaux, voir les exemples suivants :

Les nuanceurs

Qt 3D supporte toutes les étapes du pipeline de rendu programmable OpenGL : vertex, contrôle de tessellation, évaluation de tessellation, géométrie, et fragment shaders. Les nuanceurs de calcul sont prévus pour une prochaine version.

Pour des exemples d'utilisation des shaders, voir Qt 3D: Wireframe QML Example.

Cartographie des ombres

Les ombres ne sont pas directement supportées par OpenGL, mais il existe d'innombrables techniques qui peuvent être employées pour les générer. Le mappage d'ombres est simple à utiliser pour générer de belles ombres, tout en ayant un coût de performance très faible.

Le mappage d'ombres est typiquement implémenté en utilisant un rendu en deux passes. Lors de la première passe, les informations sur les ombres 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.

L'idée derrière le shadow mapping est que seuls les fragments les plus proches de la lumière sont éclairés. Les fragments situés derrière d 'autres fragments sont occultés et donc dans l'ombre.

Par conséquent, lors de la première passe, la scène est dessinée du point de vue de la lumière. L'information stockée est simplement la distance du fragment le plus proche dans cet espace lumineux. En termes d'OpenGL, cela correspond à un Framebuffer Object, ou FBO, auquel est attachée une texture de profondeur. En fait, la distance de l'œil est la définition de la profondeur, et le test de profondeur par défaut effectué par OpenGL ne stocke que la profondeur du fragment le plus proche.

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

L'image suivante montre une scène avec un plan et un nœud de trèfle auto-ombrés :

Scène rendue en 3D montrant 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'ombre exagérée de la scène :

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

L'image indique la profondeur stockée lors du rendu de la scène du point de vue de la lumière. Les couleurs plus sombres 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, sur le côté droit par rapport à la caméra principale (comparez 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 que la carte des ombres a été générée, la deuxième passe de rendu est effectuée. Dans cette deuxième passe, le rendu est effectué en utilisant la caméra de la scène normale. N'importe quel effet peut être utilisé ici, comme l'ombrage Phong. Il est important que l'algorithme de la carte d'ombre soit appliqué dans le nuanceur de fragment. En d'autres termes, le fragment le plus proche de la lumière est dessiné éclairé, tandis que les autres fragments sont dessinés dans l'ombre.

La carte des ombres générée lors de la première passe fournit les informations nécessaires sur la distance des fragments par rapport à la lumière. Il suffit alors de remapper le fragment dans l'espace lumineux, en calculant ainsi sa profondeur du point de vue de la lumière, ainsi que ses coordonnées sur la texture de la carte des ombres. La texture de la carte des 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 dans l'ombre, sinon il est éclairé.

Rendu instancié

L'instanciation est un moyen d'amener le GPU à dessiner plusieurs copies (instances) d'un objet de base qui varie d'une manière ou d'une autre pour chaque copie. Souvent, la position, l'orientation, la couleur, les propriétés matérielles, 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 par instance. Ainsi, alors qu'une entité à laquelle est attaché un composant Mesh est éventuellement transformée en un appel à glDrawElements, une entité à laquelle est attaché un composant instancié sera transformée en un appel à glDrawElementsInstanced.

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

Objets tampons uniformes

Un objet tampon uniforme (UBO) peut être lié aux programmes de shaders OpenGL pour rendre de grandes quantités de données facilement disponibles. Les cas d'utilisation typiques des UBO sont les ensembles de paramètres de matériaux ou d'éclairage.

Conseils utiles

Quelques conseils de programmation très utiles pour le rendu 3D peuvent être trouvés sur cette page : Qt 3D Render Pro Tips.

Renderer configurable

Pour combiner le support des API C++ et QML avec un moteur de rendu entièrement configurable, le concept de graphe de scène a été introduit. Alors qu'un graphique de scène est une description de ce qu' il faut rendre, un graphique de cadre est une description de la manière dont il faut le rendre.

Un framegraph permet aux développeurs de choisir entre un simple rendu avant, incluant une passe de z-fill, ou l'utilisation d'un rendu différé par exemple. Il leur permet également de contrôler le moment du rendu des objets transparents, etc. Comme tout cela est configuré uniquement à partir de données, il est très facile de le modifier, même dynamiquement, au moment de l'exécution, sans toucher au code C++. Il est possible d'étendre Qt 3D en créant ses propres framegraphs qui implémentent des algorithmes de rendu personnalisés.

Extensions 3D

Au-delà de l'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 des collisions
  • Audio 3D de position
  • Animation de corps rigides, de squelettes et de cibles morphologiques
  • Recherche de chemin et autres IA
  • Sélection
  • Particules
  • Création d'objets

Performances

Qt 3D est conçu pour offrir de bonnes performances et s'adapter au nombre de cœurs de processeurs disponibles, car le matériel moderne améliore les performances en augmentant le nombre de cœurs plutôt que la vitesse 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 recherche de chemin 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 L'architecture

Les principaux cas d'utilisation de 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 de Space Invaders contient les objets suivants :

Capture d'écran d'un jeu Space Invaders

  • Le canon terrestre du joueur
  • Le sol
  • Les blocs défensifs
  • Les vaisseaux ennemis des envahisseurs de l'espace
  • 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 typiquement implémentés sous forme de classes disposées dans une sorte d'arbre d'héritage. Les différentes branches de l'arbre d'héritage peuvent ajouter des fonctionnalités supplémentaires à la classe racine, par exemple :

  • Accepter les données de l'utilisateur
  • Joue un son
  • s'animer
  • entrer en collision avec d'autres objets
  • Est dessiné à l'écran

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

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

  • Les hiérarchies d'héritage profondes et larges sont difficiles à comprendre, à maintenir et à étendre.
  • La taxonomie de l'héritage est figée au moment de la compilation.
  • Chaque niveau de l'arbre d'héritage des classes ne peut classer qu'en fonction d'un seul critère ou axe.
  • Les fonctionnalités partagées ont tendance à remonter 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 larges nécessite généralement de comprendre et d'accepter la taxonomie utilisée par l'auteur d'origine. Par conséquent, Qt 3D met l'accent sur l'agrégation plutôt que sur l'héritage comme moyen de transmettre des fonctionnalités à une instance d'objet. Plus précisément, Qt 3D met en œuvre un système de composants d'entités (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 caractéristique spécifique. Un comportement supplémentaire peut être greffé sur une entité en lui faisant agréger un ou plusieurs composants. Chaque composant est une tranche verticale de comportement d'un type d'objet.

Dans l'exemple des envahisseurs de l'espace, le sol est une entité à laquelle est attaché un composant qui indique au système que l'entité a besoin d'un rendu et de quel type de rendu elle a besoin. Le vaisseau ennemi des envahisseurs de l'espace est une autre entité avec des composants attachés qui provoquent le rendu du vaisseau, mais qui lui permettent également d'émettre des sons, d'être heurté, d'être animé et d'être contrôlé par une IA simple.

L'entité canon terrestre du joueur possède des composants similaires à ceux du vaisseau envahisseur de l'espace, à l'exception de l'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

Diagramme montrant les composants de QEntity

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

Par exemple, l'aspect "rendu" recherche des entités qui ont des composants de maillage, de matériau et, éventuellement, de transformation. Si l'aspect "rendu" trouve une telle entité, il sait comment prendre ces données et en tirer quelque chose d'agréable. Si une entité n'a pas ces composants, l'aspect de rendu l'ignore.

Qt 3D construire des entités personnalisées en agrégeant des composants qui fournissent des capacités supplémentaires. Le moteur Qt 3D utilise des aspects pour traiter et mettre à jour des entités avec des composants spécifiques.

Par exemple, un aspect physique recherche des entités qui ont un composant de volume de collision et un autre composant qui spécifie d'autres propriétés nécessaires à de telles simulations, comme la masse, le coefficient de frottement, etc. Une entité qui émet des sons possède un composant qui spécifie qu'il s'agit d'un émetteur de sons, et qui spécifie quand et quels sons doivent être joués.

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

Par exemple, pour permettre à un joueur de courir soudainement à travers les murs après une mise sous tension, le composant de volume de collision de cette entité peut être supprimé temporairement, jusqu'à ce que la mise sous tension s'arrête. Il n'est pas nécessaire de créer une sous-classe spéciale et unique pour PlayerWhoRunsThroughWalls.

Qt 3D Mise en œuvre de l'ECS

Qt 3D met en œuvre le système ECS sous la forme d'une simple hiérarchie de classes. La classe de base Qt 3D est Qt3DCore::QNode, qui est une sous-classe de QObject. Qt3DCore::QNode ajoute à QObject la capacité de communiquer automatiquement les changements de propriété aux aspects et 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 orientés utilisateur et les aspects.

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

Diagramme montrant la relation entre QEntity, QComponent, QNode et QObject

Les composants de Qt 3D sont mis en œuvre en sous-classant Qt3DCore::QComponent et en ajoutant les données nécessaires au 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 envoyées dans le pipeline OpenGL.

Enfin, Qt3DCore::QEntity est simplement un objet qui peut agréger 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 de manière spécifique à vos propres applications pour bénéficier du back-end multithread, consiste en les tâches suivantes :

  • Identifier et mettre en œuvre tous les composants nécessaires et les données d'appui.
  • Enregistrer les composants auprès du moteur QML (uniquement si vous utilisez l'API QML).
  • Sous-classer QAbstractAspect et mettre en œuvre la fonctionnalité du sous-système.

Qt 3D Moteur basé sur les tâches

Dans Qt 3D, les aspects sont invités dans chaque cadre à exécuter un ensemble de tâches ainsi que les dépendances entre elles. 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 l'entreprise

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

D'autres aspects offrant davantage de possibilités seront ajoutés dans les prochaines versions de 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.