J'écris actuellement un petit moteur de jeu 2D multiplateforme basé sur OpenGL pour notre studio. Lorsque j'ai recherché la classe de vecteur 2D à utiliser, je suis tombé sur trois paradigmes de conception différents:
Float & Call-by-value, comme dans cet article Gamasutra . Semble être rapide mais offre peu de précision (voir aussi ce fil ). Pro: rapide, portable et compatible avec la plupart des bibliothèques.
Double et appel par référence. Si je comprends bien l'article ci-dessus, je pourrais également utiliser 2 variables de double précision au lieu des 4 nombres flottants. Selon le fil ci-dessus, le double est toujours plus lent que le flotteur.
Modèle pour double et float: Le livre très populaire " Game Engine Architecture " utilise des modèles pour permettre d'utiliser float et double selon les besoins. L'inconvénient évident est le ballonnement du code. De plus, je doute que le code puisse être optimisé sans écrire fondamentalement deux classes, de toute façon.
J'apprécierais de savoir quelles solutions vous utilisez dans vos moteurs internes et la précision, par exemple, des moteurs de jeux populaires, afin que je puisse décider quelle solution je vais implémenter dans notre moteur. En ce moment, je pense simplement à utiliser la précision flottante et à vivre avec.
la source
Réponses:
J'utilise toujours float sauf si j'ai une raison d'utiliser double, tout comme j'utilise int sauf si j'ai une raison d'utiliser int64_t.
Les flotteurs n'ont aucun problème à effectuer une arithmétique entière précise jusqu'à 2 24 , ce dont la plupart des gens ont peur (principalement de manière irrationnelle). Les doublons ne résolvent pas exactement le problème des valeurs communes qui ne peuvent pas être représentées exactement - que vous obteniez 0.10000001 ou 0.10000000000000001, vous devez toujours vous assurer que votre code le considère "égal" à 0,09999999.
Les doublons sont plus lents sur chaque plate-forme dont vous vous souciez pour l'écriture de jeux, prennent deux fois plus de bande passante mémoire et disposent de moins d'instructions CPU spécialisées.
Les flotteurs simple précision restent la norme pour les interfaces graphiques matérielles, à la fois côté C / C ++ et à l'intérieur des shaders.
Vous aurez probablement besoin d'un double vecteur à un moment donné, mais il devrait être utilisé en cas de besoin, pas par défaut.
En ce qui concerne les modèles - vous avez raison, pour des performances maximales, vous voudrez de toute façon spécialiser les modèles manuellement. En plus de cela, j'ai effectué des tests pour du code basé sur des modèles au cours du week-end (en créant un IntRect et un FloatRect à 4 éléments), et j'ai constaté que la version basée sur des modèles prenait environ 20 fois plus de temps à compiler que de simplement répéter le code, ce qui équivalait à environ 15 lignes. . La répétition craint, mais attendre les compilations est plus lourd - et ce n'est pas comme si j'allais avoir besoin d'un StringRect ou d'un FooRect.
la source
Le cadre de jeu Microsoft XNA a une classe Vector2 qui utilise des flottants. Ce serait ma principale raison personnelle d'aller avec des flotteurs, car j'ai confiance que la sagesse et l'expérience de l'équipe XNA sont bien plus grandes que les miennes.
J'ai trouvé assez intéressant de lire la réponse dans cette question de débordement de pile: "Float vs Double Performance" . Il y a aussi un fil gamedev.net avec une discussion sur la double performance dans les GPU. Je pense qu'il est prudent de supposer que les doubles sont plus lents que les flottants, du moins dans de nombreux GPU, et personnellement, j'ai toujours utilisé les fonctions OpenGL flottantes par rapport à leurs homologues doubles. Cela ne s'applique peut-être pas de nos jours, mais si vous considérez que tous ceux qui gèrent votre jeu n'ont pas le dernier GPU avec double support natif, je pense que c'est une raison suffisante pour utiliser des flotteurs et gagner un peu plus de performances.
la source