Derzeit schreibe ich eine kleine plattformübergreifende OpenGL-basierte 2D-Game-Engine für unser Studio. Als ich nachforschte, welche 2D-Vektorklasse ich verwenden sollte, stieß ich auf drei verschiedene Designparadigmen:
Float & Call-by-Value, wie in diesem Gamasutra-Artikel . Scheint schnell zu sein, bietet aber wenig Präzision (siehe auch diesen Thread ). Pro: Schnell, portabel und kompatibel mit den meisten Bibliotheken.
Double & Call-by-Reference. Wenn ich den obigen Artikel richtig verstehe, könnte ich auch 2 Variablen mit doppelter Genauigkeit anstelle der 4 Gleitkommazahlen verwenden. Nach obigem Thread ist Double immer noch langsamer als Float.
Vorlage für Double und Float: Das weit verbreitete Buch " Game Engine Architecture " verwendet Vorlagen, um die Verwendung von Float und Double nach Bedarf zu ermöglichen. Der offensichtliche Nachteil ist das Aufblähen des Codes. Ich bezweifle auch, dass der Code optimiert werden kann, ohne grundsätzlich zwei Klassen zu schreiben.
Ich würde gerne erfahren, welche Lösungen Sie in Ihren internen Engines verwenden und wie präzise zB beliebte Game-Engines sind, damit ich entscheiden kann, welche Lösung ich in unserer Engine implementieren werde. Im Moment denke ich darüber nach, einfach Float-Präzision zu verwenden und damit zu leben.
quelle
Antworten:
Ich verwende immer float, es sei denn, ich habe einen Grund, double zu verwenden, genauso wie ich int verwende, es sei denn, ich habe einen Grund, int64_t zu verwenden.
Floats haben kein Problem damit, präzise Ganzzahlarithmetik bis zu 2 24 durchzuführen , wovor die meisten Menschen (meistens irrational) Angst haben. Doppelte Probleme lösen nicht das Problem, dass allgemeine Werte nicht genau darstellbar sind. Unabhängig davon, ob Sie 0,10000001 oder 0,10000000000000001 erhalten, müssen Sie dennoch sicherstellen, dass Ihr Code sie als "gleich" mit 0,09999999 betrachtet.
Doppel sind auf jeder Plattform, auf der Sie Spiele schreiben möchten, langsamer, benötigen die doppelte Speicherbandbreite und verfügen über weniger spezielle CPU-Anweisungen.
Floats mit einfacher Genauigkeit bleiben der Standard für Hardware-Grafikschnittstellen, sowohl auf der C / C ++ - Seite als auch innerhalb von Shadern.
Sie werden wahrscheinlich irgendwann einen Doppelvektor benötigen, der jedoch bei Bedarf verwendet werden sollte, nicht standardmäßig.
Was das Template betrifft - Sie haben Recht, für maximale Leistung möchten Sie die Vorlagen ohnehin manuell spezialisieren. Abgesehen davon habe ich am Wochenende einige Tests für Vorlagencode durchgeführt (Erstellen eines 4-Ple-IntRect und eines FloatRect) und festgestellt, dass das Kompilieren der Vorlagenversion etwa 20-mal länger dauerte als das Wiederholen des Codes, der sich auf etwa 15 Zeilen belief . Wiederholung ist scheiße, aber das Warten auf Kompilierungen ist scheiße - und es ist nicht so, dass ich jemals einen StringRect oder FooRect brauchen werde.
quelle
Das Microsoft XNA-Spielframework verfügt über eine Vector2-Klasse, die Floats verwendet. Dies wäre mein größter persönlicher Grund für Floats, da ich darauf vertraue, dass die Weisheit und Erfahrung des XNA-Teams viel größer ist als meine eigene.
Ich fand es ziemlich interessant, die Antwort in dieser Frage zum Stapelüberlauf zu lesen: "Float vs Double Performance" . Es gibt auch einen gamedev.net-Thread mit einigen Erläuterungen zur doppelten Leistung in GPUs. Ich denke, man kann davon ausgehen, dass Doubles langsamer sind als Floats, zumindest in vielen GPUs, und ich persönlich habe die Float-OpenGL-Funktionen immer gegenüber ihren Double-Gegenstücken verwendet. Dies gilt heutzutage möglicherweise nicht mehr, aber wenn Sie bedenken, dass nicht jeder, der Ihr Spiel ausführt, über die neueste GPU mit nativer Doppelunterstützung verfügt, ist dies meiner Meinung nach Grund genug, Floats zu verwenden und ein bisschen mehr Leistung zu erzielen.
quelle