Direct3D vs OpenGL
Quelle API vaut-il mieux utiliser pour un moteur 3D, OpenGL ou Direct3D ?Résumé
Voici les avantages et inconvénients des deux interfaces :- OpenGL
- + Facile à utiliser au départ. Les choses se compliquent par la suite.
- + Portable sur plus de plateformes, dont Linux
- - Rendu vers des targets non visible (ombres, caméras secondaires...) compliqué sur les vieilles cartes
- - Drivers pourris sur les cartes 3D Intel, Via, Sis, S3 et co.
- - Drivers très difficile à implémenter car une trop grande liberté d'action est offerte au programmeur.
- Direct3D
- + Plus simple de faire des choses avancées.
- + Meilleur support des rendus vers des targets non visibles
- + Meilleurs drivers sur les cartes très bas de gamme (Intel, Sis, Via, S3...)
- + De bien meilleurs outils de débuggage : Pix360, NvPerfhud, Pix Windows, D3D-debug...
- + Portable assez facilement sur XBox
- - Gros problème de performance si on affiche beaucoup d'objets
- Direct3D 10 sans intérêt : il est censé corriger les problèmes de performances de D3D9 sur les objets nombreux, mais a une part de marché trop ridicule pour être envisageable.
OpenGL
Les deux principaux problèmes de OpenGL sont les changements de rendertarget et les drivers des petites cartes 3D. Le premier problème ne se pose pas si on veut faire des ombres de façon moderne : les cartes ne supportant pas les FBO (FrameBuffer Objets) sont également incapable de calculer des shaders modernes.
Mais si l'on veut également supporter les vieilles cartes 3D (Geforce <= 4, voire certains Geforce FX, Radeons 8500 et -, Intel, Sis, S3...), alors ces deux problèmes deviennent des points noirs : il faudra se battre avec les horribles PBO, et les bugs des drivers des marques autres que Nvidia/ATI.
Direct3D
Direct3D de son coté a un énorme problème de conception. Il a été créé à une époque où les jeux affichaient peu d'objets et a été optimisé dans ce sens. Et même aujourd'hui, afficher pleins de petits objets est extrêmement lent sous Direct3D. Chaque rendu de primitive provoque un passage du CPU du mode protégé niveau 3 (applications) en niveau 0 (kernel Os) qui provoque un "stall" : une grosse pause.
Si pour un fps ou un 3dmark ce n'est pas trop gênant (car il y a assez peu d'objets séparés, les objets ayant surtout beaucoup de triangles), c'est très gênant pour des RTS (pleins d'unités) ou un SimCity-like en 3D (beaucoup de bâtiments différents et animés).
Pour corriger cela, une extension a été ajoutée dans Direct3D 9 : l'instanciation, qui permet d'afficher plusieurs fois un même objet. Mais ce n'est pas utilisable si peu d'objets sont répétés ou si les répétitions ne sont pas exactement au même moment de la même animation. De plus cela ne fonctionne pas sur les vieilles cartes.
La seule vraie solution est d'animer les vertexes sur le CPU, et de générer en permanence un méta-objet contenant les petits objets qui utilisent la même texture. Le retour au moyen-Âge, quoi!
D3D10 et suivant corrigent en fait ce problème.
Conclusion
La vraie solution serait-elle de programmer avec l'API OpenGl-ES, un OpenGL light ne contenant que le strict minimum et donc beaucoup plus simple à implémenter sur les cartes 3D ?
Update Octobre 2008
Un lien intéressant : OpenGL 3 & DirectX 11: The War Is Over sur tomshardware.com.
Les outils de débuggage pour D3D font fortement pencher la balance dans son sens.
À coté - comparaison rapide PC vs consoles
Les PC courant sont biens surs bien plus performants que les consoles.
Les consoles ont néanmoins l'avantage sur certaine features aidant la programmation :
- lecture du depth buffer. Pas besoin d'une prépasse de rendu du depth buffer dans un buffer couleur qui sera ensuite utilisé comme depth buffer lisible sur PC.
- antialiasing bien plus simple à mettre en place, surtout si on fait le rendu principal hors du framebuffer (et risque de bugs de drivers, comme on en a rencontré sur mon dernier jeu ; confirmé par le fabriquant qui a sorti un nouveau driver pour le corriger).
- sur consoles, on peut charger tous les shaders d'un jeu, même si plusieurs (dizaine de) milliers, sans problème. Sur PC, un écran bleu apparait après un certains nombre (dépendant de leur taille) ; la limite semblant être liée à un bloc de taille fixe alloué au driver graphique dans la mémoire Kernel.