ARM annonce sa nouvelle génération de processeurs : les Cortex A75 et A55 et le processeur graphique Mali G72

ARM est à la fois une société qui conçoit (mais ne fabrique pas) des processeurs et le nom de l’architecture de ces processeurs. Elle vend donc des blocs que d’autres sociétés peuvent intégrer aux processeurs qu’elles fabriquent (comme Samsung pour ses Exynos et certains processeurs de Qualcomm), de telle sorte qu’elles peuvent développer des processeurs complets très rapidement, le travail ayant été prémâché par ARM. (D’autres sociétés, comme Apple ou Qualcomm, préfèrent n’utiliser que les instructions ARM et concevoir complètement leurs processeurs de zéro.)

Fin mai, la société a annoncé deux nouveaux blocs de processeur : les Cortex A75 (optimisé pour la performance; qui succède au A73) et A55 (optimisé pour la consommation énergétique, qui succède au A53 de 2012). La société est organisée pour produire de nouveaux cœurs variés quant à leurs utilisations possibles avec une cadence élevée (de nouvelles conceptions chaque année dans chaque segment), les deux processeurs n’ont pas grand-chose en commun dans leurs détails — ce qui n’empêche de combiner plusieurs cœurs de chaque type dans un processeur haut de gamme, pour bénéficier d’une faible consommation quand les besoins en puissance ne sont pas énormes, mais avec toujours plus de puissance de calcul sous le capot.

Cortex A55 : une augmentation de performance et de l’efficacité énergétique

L’A55 est un cœur de calcul assez petit, incapable de réordonner les instructions qu’il effectue (contrairement aux cœurs plus gros, qui changent l’ordre des instructions pour utiliser au mieux leur architecture). Le point noir de l’architecture précédente était le système mémoire, qui limitait la partie de calcul pur. Ainsi, ARM a repensé le module de préchargement depuis la mémoire (la lecture est complètement séparée de l’écriture), mais a aussi intégré un cache L2 plus près de la partie calcul, l’objectif étant de réduire la latence de 50 % lors d’un accès direct en mémoire (un changement lié à DynamIQ, voir plus loin). Un cache L3 a aussi été ajouté. L’effet est immédiat : sur un test de copie de mémoire (LMBench), le temps d’exécution est presque divisé par deux. Les autres améliorations concernent principalement le prédicteur de branchement.

Globalement, d’après les chiffres d’ARM, à fréquence égale, un cœur A55 gagne 18 % en performance par rapport à son prédécesseur pour des opérations sur des nombres entiers (SPECint) et même 38 % avec des nombres à virgule flottante (SPECfp). Lors de tests plus réalistes, ce cœur a un score 21 % plus élevé au test Geekbench v4, 14 % pour Octane v2. En pratique, l’augmentation de performance devrait être plus importante, vu que la comparaison se voulait aussi égale que possible (même taille des caches L1, L2, pas de cache L3, fréquence égale, même compilateur, etc.), ce qui a obligé à désactiver certaines fonctionnalités de l’A55.

 

La consommation d’énergie est presque constante, avec une augmentation de 3 % — mais, en pratique, elle sera plus faible à performance égale, grâce aux nombreuses améliorations apportées. Ainsi, l’efficacité énergétique augmente de 15 % pour SPECint.

Cortex A75 : une même consommation pour une meilleure performance

L’A75 est un cœur bien plus gros que l’A55, ce qui lui permet d’effectuer un prétraitement plus poussé avant l’exécution du code. Ainsi, par rapport au A73, il peut décoder trois instructions par cycle (au lieu de deux). Il n’y a pas plus d’unités de calcul, mais plus de files pour stocker les microopérations à effectuer : ainsi, on passe de six microopérations effectuées à huit par cycle. Côté NEON (pour des instructions effectuant la même opération sur une série de valeurs à la fois — c’est le principe du SIMD, implémenté côté x86 par les instructions SSE et AVX), les changements sont similaires, avec cependant une troisième unité de calcul, dédiée aux accès à la mémoire.

Globalement, l’augmentation de performance est perceptible, que ce soit sur des tests synthétiques (22 % d’augmentation pour SPECint, 33 % pour SPECfp, 16 % pour LMBench) ou réels (48 % sur Octane v2, 34 % sur Geekbench v4).

DynamIQ, le nouveau nom de big.LITTLE

Pour améliorer la consommation énergétique des processeurs de ses clients tout en proposant un haut niveau de performance, ARM a développé ces dernières années big.LITTLE. Cette technologie permet de rassembler plusieurs cœurs différents (A53 et A73, par exemple) et de les activer et désactiver selon la charge de calcul : les cœurs sont rassemblés dans deux grappes (de maximum quatre cœurs), l’une ou l’autre étant choisie selon les calculs à effectuer. En d’autres termes, l’hétérogénéité était assez limitée, puisqu’on avait une grappe de cœurs peu puissants (LITTLE) et l’autre de cœurs plus puissants (big), sans solution intermédiaire. Des implémentations plus complexes n’avaient pas cette limitation et pouvaient exploiter tous les cœurs des deux grappes simultanément — mais les grappes doivent rester homogènes.

Les besoins ont continué d’évoluer, ce qui a rendu big.LITTLE problématique pour l’évolution future, d’où DynamIQ : l’objectif est d’avoir une technologie plus flexible, qui permet d’utiliser plus de cœurs (potentiellement plus spécialisés), tout en augmentant la performance.

Les Cortex A55 et A75 sont spécifiquement prévus pour exploiter au mieux DynamIQ. Ainsi, chaque cœur possède ses caches L2 privés, très près des parties effectuant les calculs, pour une performance optimale. Les caches L3, au contraire, sont partagés au niveau d’une grappe, de telle sorte qu’une tâche peut passer d’un cœur à l’autre d’une même grappe sans devoir trop accéder à la mémoire externe à la grappe (forcément lente).

Ces grappes peuvent alors être interconnectées : avec huit cœurs par grappe, trente-deux grappes par puce, on peut encore monter avec une interconnexion CCIX entre puces. Chaque cœur de chaque grappe peut être désactivé individuellement — même si la fréquence doit être identique pour tous les cœurs activés d’un même “domaine”, prédéfini à l’avance par le constructeur (les huit cœurs d’une grappe peuvent cependant avoir chacun leur domaine, dans une implémentation plus complexe : chaque domaine doit avoir son propre régulateur de tension pour gérer la fréquence).

Mali G72 : des améliorations itératives

Finalement, ARM a aussi annoncé un nouveau processeur graphique, le G72. L’objectif est multiple : s’adapter aux nouveaux besoin en puissance (des jeux mobiles avec une haute fidélité de rendu) et aux nouvelles applications (apprentissage automatique et réalité virtuelle). Le G72 n’apporte pas une architecture complètement renouvelée (c’était le cas du G71, avec l’architecture Bifrost), mais bien améliorée sur certains points particuliers.

Les améliorations se concentrent sur des détails, qui ont toutefois leur importante : l’efficacité énergétique est ainsi améliorée de 25 %, la densité de performance de 20 % (c’est-à-dire une augmentation de performance de 40 % à surface et à consommation équivalente).

Ainsi, certaines instructions trop complexes et peu souvent utilisées ont été retirées et remplacées par plusieurs instructions, qui prennent donc plus de cycles — en diminuant la complexité du processeur. L’impact en performance est négligeable, puisque ces instructions sont peu utilisées. Au contraire, certaines instructions complexes ont été optimisées dans le cadre des opérations graphiques (ne respectant pas forcément la norme IEEE 754 : ces variations des instructions ne sont pas impactées).

Cependant, la plupart des gains en performance viennent plutôt des caches, tous quelque peu impactés : les caches L1, d’écritures et de temporisation des tuiles sont plus grands ; la logique des caches d’instruction a été améliorée pour limiter les défauts et donc les accès directs en mémoire. L’effet principal est donc de réduire les besoins en bande passante du GPU : cela tombe bien, les opérations en mémoire sont parmi les plus énergivores.

Grâce à ces gains, pour une performance équivalente, on pourra utiliser moins de cœurs G72 et donc gagner en place sur le processeur (ce qui en diminue le coût) ; ceux qui ont besoin de meilleures performances pourront mettre plus d’unités de calcul sur une même surface, ce qui est aussi avantageux.

Sources et images : Exploring DynamIQ and ARM’s New CPUs: Cortex-A75, Cortex-A55, ARM Announces Mali-G72: Bifrost Refined for the High-End SoC.

 

En route vers Scala 3 : sortie de Dotty 0.1.2 RC 1

La version 0.1.2 RC 1 du nouveau compilateur Scala, Dotty, est sortie fin mai. Il s’agit d’une réécriture complète du compilateur Scala, avec des changements au niveau syntaxique. La 0.1.2 est spéciale en ce sens qu’il s’agira de la première version publique de Dotty, même si le projet est connu de longue date — son développement dure déjà depuis quatre ans, le compilateur peut se compiler lui-même depuis 2015.

Par rapport à Scala 2, la syntaxe est légèrement épurée : notamment, il n’y a plus moyen d’écrire directement du XML dans du code Scala ; le langage fournit moins de types, mais des constructeurs revenant aux fondamentaux. La différence principale par rapport à Scala 2 se situe au niveau théorique : Dotty se base sur le modèle de calcul DOT (plus simple que les machines de Turing ou le calcul lambda, par exemple, mais surtout plus adapté au code réel). Cela permet de réaliser des preuves formelles à propos de morceaux de code. Ce modèle de calcul est forcément réduit par rapport aux fonctionnalités du langage, mais la plupart des constructions syntaxiques peuvent se réécrire dans ce modèle.

Quelques nouveautés par rapport à Scala 2 peuvent déjà être notées, comme les types d’intersection (un objet passé en argument à une fonction doit posséder plusieurs traits) et d’union (au moins un trait).

def f(x: Resettable & Growable[String]) = { // Intersection : à la fois Resettable et Growable[String]
  x.reset()
  x.add("first")
}

def help(id: UserName | Password) = { // Union : soit un UserName, soit Password (soit les deux)
  // ...
}

Les traits peuvent aussi posséder des paramètres, tout comme les classes.

trait Greeting(val name: String) {
  def msg = s"How are you, $name"
}

Les énumérations font leur apparition.

enum Color {
  case Red, Green, Blue
}

Dès maintenant, les développeurs se forceront à produire de nouvelles versions régulièrement : des versions compilées chaque jour et des RC toutes les six semaines, ces dernières devenant des versions finales après six semaines.

Sources : Announcing Dotty 0.1.2-RC1, a major step towards Scala 3, 0.1.2 release notes.

Plus de détails sur DOT.

PCIe 4.0 : jusqu’à seize millions de transferts par seconde

PCI Express (peripheral component interconnect) est le bus de référence dans les ordinateurs actuels. Il sert notamment à connecter toutes les cartes d’extension, y compris (voire surtout) les cartes graphiques, ainsi que certains SSD. Les cartes PCIe ont une forme bien spécifique pour les enchâsser dans la carte mère, une longue série de points de contact (comme pour PCI, AGP et ISA) ; plusieurs longueurs ont été normalisées, avec un nombre de contacts variables, afin de correspondre aux différents besoins en performance (entre x1 et x16, avec une bande passante qui augmente d’un facteur seize). PCIe, ce n’est pas que ces ports : on peut connecter des SSD à travers des ports M.2, qui peuvent utiliser le protocole PCIe, tout comme les ports externes Thunderbolt (compatibles USB C).

La version 3.0 est sortie en 2010 et permettait un total de huit millions de transferts par seconde (8 GT/s), un transfert étant un échange d’informations (équivalent d’un paquet dans les réseaux informatiques traditionnels). La quatrième version de la norme est maintenant prête (il ne manque que quelques vérifications légales, qui devraient être faites pour fin de l’année) et double la bande passante à seize gigatransferts par seconde. Ainsi, pour un port x16, PCIe 4.0 peut fournir un débit de soixante-quatre gigaoctets par seconde.

Cette augmentation de débit maximum est importante pour bon nombre d’applications, comme les cartes graphiques : pour le traitement de jeux de données de plus en plus grands ou l’utilisation de textures plus détaillées dans les jeux vidéos, les quantités de données à transférer augmentent régulièrement (il est actuellement difficile de remplir entièrement un bus de seize gigaoctets par seconde pour ces applications, mais cela le sera probablement dans les années à venir).

La conversion entre le nombre de transferts par seconde et le débit s’effectue selon la manière d’encoder un paquet. Depuis PCIe 3.0, un encodage 128b/130b est utilisé : cent vingt-huit bits sont codés sur cent trente bits, les deux bits supplémentaires étant utilisés pour détecter et corriger les erreurs de transmission (principalement des horloges non synchronisées). Chaque ligne PCIe est utilisée pour la transmission (en duplex : en envoi ou réception, selon les besoins) : un port x1 définit une seule ligne, un x16 seize lignes.

Puisque l’encodage ne change pas, les gains en débit sont obtenus uniquement par une montée en fréquence de l’émission : PCIe 3.0 fonctionne à huit gigahertz, on peut attendre que la version 4.0 fonctionne à une douzaine de gigahertz, mais aucun chiffre n’est avancé officiellement. Le problème de ces hautes fréquences est que la synchronisation sur une longue distance devient plus difficile : une différence de quelques millimètres sur une piste peut induire un décalage important des paquets dans le temps.

Un avantage de cette augmentation de fréquence est que, pour un débit donné, une carte PCIe aura besoin de moins de lignes : les besoins en énergie pour une même transmission diminuent donc (ce qui est important notamment dans le calcul de haute performance, actuellement limité par ce facteur).

Une version 5.0 est d’ores et déjà en cours de préparation, toujours en utilisant des pistes de cuivre (la 4.0 devait être la dernière sur ce support). La rédaction devrait être achevée pour 2019, avec les premiers produits pour 2020 ou 2021. Le débit annoncé est de cent vingt-huit gigaoctets par seconde (le double de PCIe 4.0), notamment pour suivre dans des applications comme des cartes Ethernet 400 Go/s ou InfiniBand 200 Go/s.

Sources et image : PCIe 4.0 specification finally out with 16 GT/s on tap, PCI-SIG® Fast Tracks Evolution to 32GT/s with PCI Express 5.0 Architecture.

La science des données est-elle morte ?

L’apprentissage automatique et la science des données sont maintenant partout, l’actualité le montre assez. En exploitant des jeux de données immenses, il devient possible de résoudre n’importe quel problème, comme détecter si quelqu’un s’est fait voler son identité en ligne ou jouer au go.

Le problème, c’est que, pour atteindre ces résultats, il faut de la créativité, pas simplement une capacité d’écrire du code : en d’autres termes, il faut des scientifiques des données. Ils sont cependant une ressource rare, que les entreprises s’arrachent.

La solution est toute trouvée dans un grand nombre de cas : des services en ligne proposant les modèles de sociétés privées, appelables par une API REST ou autre. Ainsi, un même genre de problème est résolu une seule fois, avec des jeux de données de plus grande taille, qui grandissent sans cesse avec l’utilisation de la plateforme. C’est notamment le cas d’IBM Watson, dont les capacités n’ont de cesse d’étonner.

L’efficacité de ces services est souvent extrêmement bonne, largement suffisante pour ne pas justifier l’engagement d’un scientifique des données. Dans certains cas, des solutions plus spécifiques peuvent apporter une meilleure performance, une prédiction juste dans 95 % des cas plutôt que 80 % en utilisant un service tout fait, mais avec un coût autre — et un bénéfice plus que très relatif, selon le cas d’utilisation. Dans d’autres cas, battre un service en ligne (de traduction automatique, notamment) requiert des compétences très poussées, des solutions algorithmiques avancées et une puissance de calcul pas à la portée du premier venu.

Ce constat est suffisant pour que certains affirment d’ores et déjà que la science des données telle qu’on la connaît pour l’instant est morte et enterrée : il n’y a plus besoin d’engager quelqu’un qui a des compétences spécifiques dans ce domaine, pour la plupart des besoins. Le scientifique des données “du futur” aura donc tendance à devenir un chef d’orchestre, qui arrange savamment les différentes API avec des données traitées en conséquence.

Ce ne serait pas le premier domaine à subir une telle évolution. La recherche opérationnelle était autrefois présente dans bon nombre d’entreprises, avec des services dédiés, bon nombre des tâches sont maintenant reprises par des sociétés qui proposent des logiciels clé-en-main — les services de recherche opérationnelle ont depuis souvent fusionné avec ceux de science des données.

Néanmoins, dans tous les cas, des gens avec ces compétences spécifiques restent requis : d’un côté, il faut construire ces services en ligne ; de l’autre, tous les besoins ne sont pas remplis par des logiciels existants, il faudra toujours développer, de temps à autre, une solution sur-mesure.

N’est-ce pas ?

Qt 5.9 et OpenVG

Qt 5.9 a apporté une nouveauté presque invisible pour pas mal de gens : le rendu d’applications Qt Quick par OpenVG. Il s’agit d’une API pour accélérer le rendu d’interfaces en 2D sur du matériel où seul le rendu logiciel est possible — principalement, certaines plateformes embarqués (comme les NXP iMX6 SoloLite ou Vybric VF5xxR, qui utilisent le GPU GC355). La dernière version d’OpenVG est la 1.1, sortie en 2008 : la norme n’a rien de nouveau, elle n’évoluera probablement plus, mais reste très implémentée. OpenVG n’a rien de neuf pour Qt : du temps de Qt 4, une implémentation de QPainter pouvait utiliser OpenVG. L’utilisation actuelle est quelque peu plus limitée en termes de fonctionnalités.

L’intérêt d’OpenVG pour Qt est le déploiement sur des plateformes embarquées, où Qt Quick est de plus en plus utilisé. Cependant, avec comme prérequis une implémentation d’OpenGL 2.0, cela limite énormément les plateformes compatibles, surtout dans les segments bon marché, où les GPU ne sont pas compatibles avec OpenGL. C’est déjà dans cette optique que le moteur de rendu logiciel avait été développé. Sa performance peut être largement améliorée si le GPU implémente la norme OpenVG 1.1, tout en gérant la grande majorité des fonctionnalités de Qt Quick.

Dans l’embarqué, cela laisse donc trois possibilités pour effectuer le rendu : purement logiciel s’il n’y a pas de GPU, avec OpenVG si le GPU ne gère pas OpenGL, puis idéalement OpenGL. Ce dernier reste la technologie préférée, puisque le GPU peut largement optimiser les appels effectués : par exemple, sur Raspberry Pi, qui gère tant OpenVG qu’OpenGL, il est plus facile d’atteindre les soixante images par seconde avec OpenGL qu’OpenVG.

Cette implémentation du moteur de rendu est limitée par rapport à celle d’OpenGL. Notamment, tout ce qui concerne la 3D et les shaders n’est pas pris en compte, puisque ces fonctionnalités sortent complètement du cadre d’OpenVG. Les modules comme les particules et les effets graphiques ne pourront pas fonctionner, puisqu’ils dépendent explicitement d’OpenGL.

Source : Getting more out of Qt Quick with OpenVG.

Qt 5.10 accueillera Vulkan : les premiers pas

Les discussions pour une première gestion de Vulkan dans Qt ne sont pas récentes : elles datent de 2016 sur le gestionnaire de tickets du projet, avec les premiers résultats attendus pour Qt 5.10, en fin de cette année 2017.

Ceci se passe dans un contexte double : d’un côté, Vulkan a été développé comme successeur à OpenGL, pour exploiter au mieux les cartes graphiques (notamment pour la réalité virtuelle et des applications aussi gourmandes) ; de l’autre, Qt 5.8 avait pour nouveauté majeure côté Qt Quick une refactorisation du moteur de rendu du graphe de scène, pour le découpler d’OpenGL, avec de premiers travaux pour utiliser Direct3D 12 (l’équivalent Vulkan de Microsoft) pour le rendu de scènes Qt Quick.

Un premier objectif pour faciliter l’utilisation de Vulkan avec Qt est de fournir une série de classes (comme les QOpenGL) qui facilitent l’écriture de code portable. Notamment, la création d’une surface de rendu Vulkan est loin d’être aisée en devant gérer toute une série de plateformes :

QWindow *window;

#if defined(VK_USE_PLATFORM_WIN32_KHR)
    VkWin32SurfaceCreateInfoKHR createInfo;
    createInfo.hwnd = (HWND) window->winId();
    ...
    err = vkCreateWin32SurfaceKHR(...);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
    VkWaylandSurfaceCreateInfoKHR createInfo;
    ...
    err = vkCreateWaylandSurfaceKHR(...);
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
    VkAndroidSurfaceCreateInfoKHR createInfo;
    ...
    err = vkCreateAndroidSurfaceKHR(...)
#elif defined(VK_USE_PLATFORM_XCB_KHR)
    VkXcbSurfaceCreateInfoKHR createInfo;
    ...
    err = vkCreateXcbSurfaceKHR(...)
#elif ..

Il serait nettement plus pratique (et orienté Qt) d’écrire un code concis et compréhensible comme :

QWindow *window;
VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(window);

Une gestion de Vulkan dans Qt, même basique, faciliterait donc grandement cette étape très importante dans l’utilisation de l’API. C’est donc le premier objectif de ce nouveau module Qt Vulkan et des classes QVulkan.

Un deuxième objectif à court terme pour ce module est de fournir une abstraction pour une fenêtre dont le rendu est entièrement effectué par du code Vulkan, tout comme QD3D12Window et QOpenGLWindow. Certes, ces classes ont quelques limitations, mais facilitent la prise en main. Ainsi est arrivée QVulkanWindow.

Par contre, pour Qt 5.10, les objectifs ne sont pas beaucoup plus élevés que cela. Notamment, l’API Vulkan n’est aucunement cachée à l’utilisation : Qt aide à créer des fenêtres, à gérer les différences entre plateformes et à charger dynamiquement les fonctions de Vulkan. La nouvelle API n’est, pour le moment, pas du tout utilisée dans des modules comme Qt Quick, Qt 3D, Qt Canvas 3D, QPainter : cela pourrait venir dans le futur, mais pas pour Qt 5.10. Des fenêtres Vulkan peuvent être combinées avec des interfaces à base de widgets à l’aide de la fonction bien connue QWidget::createWindowContainer(), tout comme des fenêtres OpenGL.

Au niveau des plateformes, Qt Vulkan peut être utilisé sous Windows (quand le SDK LunarG est installé et définit la variable d’environnement VULKAN-SDK), Linux (avec xcb, pas encore Wayland) et Android (avec les API de niveau 23 et 24, même si les en-têtes Vulkan ne sont disponibles que depuis le niveau 24).

Les bibliothèques Vulkan sont chargées dynamiquement, c’est-à-dire à l’exécution : il n’est nécessaire que de disposer des en-têtes de Vulkan (une version assez récente, au moins la 1.0.13) lors de la compilation de Qt, pas plus. Dans un futur proche, certaines configurations de test pourraient venir avec une bibliothèque Vulkan, mais ces détails sont en cours de fignolage et devraient être corrigés d’ici à la sortie de Qt 5.10.

Source : Vulkan Support in Qt 5.10 – Part 1.

Les nouveautés de Qt 3D dans Qt 5.9

Qt 3D était une fonctionnalité très attendue pour Qt 5, avec une période de gestation très longue : Qt 5.5 est arrivé avec un moteur 3D, bien que pas encore finalisé (il a fallu attendre Qt 5.7). Son architecture est prévue pour être extrêmement flexible, à tous les points de vue.

Dès Qt 5.9, il devient possible d’intégrer une scène Qt Quick à l’intérieur d’une application Qt 3D (chose impossible précédemment, malgré l’ironie de la situation quand une visualisation Qt 3D est inclus dans une scène Qt Quick). Le cas d’utilisation typique est l’inclusion d’une interface bidimensionnelle sur une surface place — un cas qui deviendra de plus en plus fréquent avec l’avènement de la réalité virtuelle ou augmentée. Cette intégration se fait avec le composant Scene2D (nom choisi pour faire référence à Scene3D, pour inclure une scène 3D dans une interface Qt Quick), qui effectue le rendu de la scène Qt Quick dans une texture et l’affiche à l’endroit voulu dans un objet 3D. Les événements sont bien sûr transférés depuis Qt 3D vers la scène Qt Quick. (Voir l’exemple Scene2D.) Pour des besoins plus simples, l’affichage de texte peut se faire par QText2DEntity.

Le rendu physique (PBR) est maintenant extrêmement utilisé dans les moteurs de rendu afin d’augmenter le niveau de réalisme du rendu. De manière générale, implémenter le rendu physique signifie que chaque matériau doit renvoyer la lumière qu’il reçoit d’une manière propre, pas avec quelques lois prédéfinies de manière stricte. Qt 3D reçoit ainsi deux modèles d’éclairage : QMetalRoughMaterial et QTexturedMetalRoughMaterial, qui implémentent des algorithmes PBR avec des reflets spéculaires de Blinn-Phong. Combinés avec une lumière de type QEnvironmentLight, les réflexions sur l’environnement seront nettement plus naturelles.

Jusqu’à présent, la manière la plus simple de réaliser des animations avec Qt 3D était d’utiliser les mécanismes de base de Qt Quick pour animer des propriétés (en C++, on peut utiliser QPropertyAnimation). Cependant, les graphistes souhaitent souvent des animations bien plus compliquées ; la manière la plus courante de procéder est d’utiliser des images clés. Par ailleurs, les animations de Qt Quick ne permettent pas d’exploiter au mieux le degré de parallélisme permis par l’architecture de Qt 3D.

C’est ainsi qu’apparaît le module Animation. Il implémente exclusivement des animations par images clés pour le moment, c’est-à-dire que la valeur de certaines propriétés est connue à un instant donné (par exemple, après cinq secondes, le bras se lève à hauteur du visage). Cependant, entre ces instants clés, le moteur de rendu doit afficher quelque chose : il interpole donc entre les points connus. Pour le moment, il peut effectuer des interpolations linéaires (lerps) et selon des courbes de Bézier. Ainsi, il est possible de réaliser un très grand nombre d’animations. Les calculs sont principalement effectués en parallèle, dans la réserve de fils de calcul de Qt 3D.

Pour gérer des scènes de très grande taille ou des machines peu puissantes, les moteurs de rendu utilisent depuis belle lurette la notion de niveau de détail : les structures géométriques proches de la caméra sont affichées avec tous leurs détails, tandis que les objets plus lointains n’ont pas besoin du même niveau de fidélité (texture, nombre de polygones, shaders peuvent varier). Qt 3D propose cette notion dans la classe QLevelOfDetail, qui mémorise les différents choix, activés par QLevelOfDetailSwitch.

Qt 5.10 apportera à nouveau son lot de nouveautés pour Qt 3D, comme de nouveaux types d’animation (notamment, un moteur de morphose plus abouti). Dans un futur peut-être plus lointain, Qt 3D pourrait s’enrichir de fonctionnalités orientées réalité virtuelle.

Source et images : What’s new in Qt 3D with Qt 5.9?.

Voir aussi : quelques exemples d’utilisation de ces nouvelles fonctionnalités.