Par l'équipe Codermind. |
|
Alors ce futur Direct3D 10, révolution ou évolution ?
Scoop : la version 10 de direct3d ne va pas révolutionner le gameplay des jeux. Mais ce n'est pas trés important puisque cette nouvelle release est entièrement et uniquement dédiée au graphisme ! Avec un peu de chance vous jouerez toujours aux mêmes FPS sous de nouveaux noms l'an prochain ;). Ce qui suit va donc uniquement parler du côté technique des jeux. Pour les tests, il y a les sites spécialisés.
Un peu d'histoire : au fur et à mesure des release, DirectX s'est réduit comme une peau de chagrin. Le premier à passer à la trappe a été le fameux Direct3D retained mode (moteur de rendu de type "scene graph"), qui constituait pourtant le coeur de la stratégie jeu de Microsoft. Les développeurs de jeu n'aimaient pas qu'on leur mâche le travail et en plus le retained mode un peu rigide et reposant sur un rendu software super optimisé est vite devenu inadapté dans le monde ultra changeant des jeux en 3D. Puis est passée à la trappe l'interface DirectDraw (traitements 2D) dont l'évolution en parallèle ne permettait pas profiter des capacités des cartes accélératrices 3D. Puis on a vu arriver puis disparaître DirectPlay, une interface censée simplifier le jeu en réseau (modem, série, IPX) mais rendue obsolète par l'omniprésence de TCP/IP. Enfin, DirectInput est en train de mourir de manière similaire. La faute à une implantation sous XP qui n'a rien à apporter de plus face aux messages windows classiques pour la gestion du couple clavier/souris. Et en partie aussi du au nouveau focus de Microsoft sur les accessoires Xbox360 qu'ils essaient de promouvoir pour le jeu sous Windows. Ne restent donc plus que la 3D et l'audio. L'audio ne progressera pas dans sa prochaine version (ce qui pousse Creative Labs à pousser OpenAL comme alternative à DirectAudio).
Tout ça pour dire que seule la partie 3D changera de manière significative dans la prochaine itération de l'API de Microsoft. Mais quel changement !
Une nouvelle plateforme
Ceux qui ont connu le passage de Direct3D8 à Direct3D9, ne vont pas reconnaître leurs petits. D3D10 joue la rupture sur tous les plans.
Premièrement D3D10 ne sera disponible que sur Vista, le nouvel OS de Microsoft. Pas de rétro compatibilité avec les ordinateurs sous XP.
Deuxièmement D3D10 ne tournera que si vous avez une carte qui intègre toutes les features de Direct3D10. Pas d'exception. Si votre vendeur de hardware vous vend une carte graphique compatible D3D9 en vous disant qu'elle a des features qui vont au delà des specs de D3D10 vous pouvez lui rire au nez. Quoiqu'il arrive les derniers hardwares sortis ne feront pas tourner les jeux écrits exclusivement pour Direct3D10.
Enfin, l'interface de programmation change du tout au tout. Avec Direct3D8, vous pouviez faire un search/replace pour remplacer les noms des interfaces d3d8 et les remplacer par les noms d'interface d3d9. Ici ce n'est plus possible. Tout ce qui est legacy support est passé à la trappe. Il n'y a pas de hw transform and lighting, uniquement des shaders. Il n'y a pas de texture stages, uniquement des shaders et des texture samplers.
Pour résumer, programmer pour Direct3D10 c'est comme programmer pour une nouvelle plateforme. Votre base de client sera forcément réduite au départ et pour toucher un plus large public il faudra faire du "multiplateforme" : faire un jeu qui tourne de la même façon sous D3D9 et D3D10. Abstraire les similarités et simuler les parties manquantes.
Quoi de neuf en fait ?
Lister toutes les nouveautés risque de devenir une énumération à la Prévert. Mais bon tentons.
Unification des spécifications des shaders. Sous D3D8 et D3D9, on avait introduit des vertex shaders et pixel shaders dont la syntaxe était totalement différente avec possibilité de mixer les versions entre elles et des features qui étaient accessibles pour l'une et pas pour l'autre (texturing). D3D10 met fin à ça. Tous les shaders doivent être de la même version et ont accés aux mêmes instructions. Ils peuvent lire les mêmes formats de textures, ont les mêmes capacités de branchement. Seules certaines instructions très spécifiques (comme les gradients) pourraient garder un parfum de spécificité. Bien entendu, la séparation "logique" entre vertex et pixel shader subsiste, la forme du pipeline ne change que pour introduire un stade intermédiaire (geometry shaders) et la possibilité de rediriger la sortie d'un shader intermédiaire vers une zone mémoire.
Une nouveauté de taille est justement le geometry shader. Celui-ci s'intercale entre le vertex shader et le pixel shader et permet de modifier plusieurs sommets à la fois. En fait il peut lire plusieurs informations de sommets connexes et peut générer une nouvelle information qui peut être le même nombre de sommets ou des sommets en plus ou des sommets en moins. Les possibilités sur le papier peuvent être immenses : à partir d'un simple jeu de coordonnées et d'un programme vous pouvez générer des particules (similaires aux point sprites). à partir d'un mesh "normal" vous pouvez générer un shadow volume extrudé selon la direction de la lumière. À partir d'un mesh low poly vous pouvez subdiviser pour obtenir un mesh haut poly en fonction de la taille à l'écran et modifier le résultat avec une texture de déplacement. Bien entendu si on peut faire de nombreux plans avec ces specs, n'oublions pas que l'on attend encore le hardware qui implémentera ces features pour en voir les performances.
Le streaming output permet de sauvegarder le résultat d'un vertex ou geometry shader en mémoire sans passer par le pixel shader. Pour des raisons de performances et de gestion des accés concurrents, il n'est sans doute pas préférable d'autoriser les écritures aléatoires depuis n'importe où dans un shader (plusieurs shaders tournant en parallèle pouvant accéder à la même mémoire). Ces écritures "structurées" sont un compromis entre flexibilité et performance. On peut penser bien entendu à sauvegarder le résultat d'un calcul complexe en vue de le réutiliser plus tard dans un rendu qui nécessiterait de recalculer ces données plusieurs fois.
Les multiple render targets (MRT) sont étendues à la notion de rendertarget arrays. Autre nouveauté, le geometry shader peut rediriger les triangles vers une ou plusieurs "vues". Ce qui permet par exemple de rendre en une seule passe toutes les faces d'une cubemap utilisée pour les réflexions. Sous D3D9 il était nécessaire d'envoyer six fois la même géométrie, changer les états et la rendertarget cible six fois de suite avec une matrice différente. Le gain de temps est évident.
D3D10 introduit aussi la notion de "predication". C'est un mode de rendu conditionnel. Avec D3D9, si vous utilisiez une occlusion query pour savoir si votre objet est bien présent à l'écran ou pas, il fallait attendre le résultat de l'occlusion query qui arrivait au mieux à la fin de la frame ou une frame trop tard ce qui faisait que le rendu conditionnel est imprécis sous D3D9. Avec D3D10, vous pouvez envoyer des commandes dont l'éxecution ne sera effectuée que si l'occlusion query précédente est passée. Bien entendu vous paierez toujours le coût de l'envoi de la commande jusqu'au moment où le résultat de la predication peut être utilisé. Vous pouvez bien sûr utiliser le résultat des queries précédentes pour savoir quel objet a plus de chance d'être caché (en cas de cohérence temporelle) et donc de maximiser le gain de la prédication.
Le langage des shaders a également évolué. Exit l'assembleur, tous les programmes seront écrits en HLSL (langages de shader de plus haut niveau). Le traitement sur les variables entières font leur apparition, mine de rien c'est un gros changement. Il faut savoir que jusqu'à présent il n'était pas possible de faire d'opérations bits à bits comme un simple AND ou un simple XOR. On a rajouté aussi l'accès indexé à des tableaux de constantes, l'accés indexé aux tableaux de textures (texture arrays).
L'instancing prend également une autre dimension avec D3D10. Sous D3D9, on pouvait rendre la même géométrie avec juste une propriété de transformation différente (pour les cartes qui supportent le shader model 3). Sous D3D10 on peut même utiliser des textures différentes pour les différentes instances via les texture arrays (cf plus haut). De même on peut tracer une géométrie sans connaitre à l'avance le nombre de ses sommets, ce qui est obligatoire si cette géométrie est issue d'un stream output (impossible de savoir à l'avance combien de sommets vont être écrits dans le buffer de destination).
On pourrait continuer la description mais je vais m'arrêter là . Pour ceux qui veulent se rendre compte des nouveautés. La documentation (temporaire) ainsi que des échantillons de code ( et des vidéos des échantillons pour ceux qui n'ont pas windows Vista) sont disponibles dans le dernier SDK (february 2006 sdk with D3d10 technology preview).
Nul doute que les jeux qui exploiteront toutes ces capacités (en supposant que le support hardware suive au niveau des perfs) seront bien intéressants visuellement.
Des images ?
Il n'y a pas vraiment d'images des nouveaux jeux D3D10 qui ne sont pas encore écrits, mais des vidéos que fournit Microsoft à ceux qui n'ont pas Vista (le hardware D3D10 y est émulé de manière software grâce au reference rasterizer).
Ce premier exemple génère du motion blur en extrudant les polygones en fonction de leur vélocité et les fond avec l'arrière plan avec l'alpha to coverage.

Ce deuxième exemple utilise l'instancing, en rajoutant la possibilité de varier la texture de l'herbe, des feuilles grâce aux arrays de texture indexables.

Ce dernier exemple utilise le geometry shader pour faire évoluer la plante avec une intervention minimale du CPU.





