Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 04, 2025 13:22

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
BeitragVerfasst: So Apr 14, 2013 16:14 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
Hallo zusammen,

ich hatte gerade eine recht interessante Diskussion mit einem Freund bzgl einer geplanten Weltraumsimulation. Es ging darum, welchen Datentyp man für die Weltkoordinaten verwenden sollte.

Das Problem im Weltraum ist ja, dass man es mit mit relativ großen Entfernungen zu tun hat (Abstand Sonne Saturn: 1500 *10^9 Meter). Fließkommazahlen können nur eine gewisse Anzahl an Stellen speichern und verschieben den Wertebereich in die gewünschte Region. Durch dieses "Verschieben" können sie zwar einen größeren Wertebereich mit 32bit oder 4 bit erfassen, als ein entsprechender Integer, allerdings kommt es zu Datenverlusten. Wir haben uns folgendes Beispiel überlegt:

Es seien 2 Objekte, die einen Meter Abstand voneinander haben, mit Fließkommazahlen beschrieben. Diese liegen nun in den Weltkoordinaten (wir bleiben mal eindimensional) bei 10m und 11m. Die Fließkommazahl soll bis zu 4 Stellen abbilden können. Ist in diesem fall kein Problem, denn es ginge beispielsweise: 0.110 - 0.100 = 0.010. Somit entsteht bei der Abstandsberechnung kein Fehler. Was ist aber nun, wenn wir die selben Objekte um sagen wir 10^5 Meter verschieben. Dann würde die Berechnung 0 zurück liefern, denn die ersten 4 Zahlen von 10011 und 10010 sind jeweils 1-0-0-1. Somit würden also Objekte die zu den Rändern des Systems verschoben werden in ihren Positionen immer ungenauer definiert werden können und im schlimmsten Fall ineinander fallen.

Mache ich da nun irgendeinen Denkfehler oder sind meine Ausführungen korrekt? Wenn ja, würde es heißen, dass ich lieber mit Integern der ensprechenden Größe rechne (vermutlich longint). Wir wollen schon mindestens eine Weltgröße von 10^9 km haben, gleichzeitig aber Annäherungen auf den mm (10-3m) genau berechnen können, egal wo man sich gerade befindet.

MfG Der Troll


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Apr 14, 2013 16:23 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
10⁹ km = 10¹²m. Ihr wollt also einen Wertebereich von 10¹⁵. Das ist praktischerweise genau die Genauigkeit eines doubles :). Aber ja, genau das Problem existiert. Deshalb teilt man die Welt z.B. in Sektoren ein, deren Position zueinander fix ist. Der Vorteil ist dann, dass die Objekte ihre Position innerhalb des Sektors mit hoher genauigkeit kennen. Über Sektorgrenzen hinweg ist die Positionsungenauigkeit nicht mehr so wichtig, weil die Objekte sowieso ewig weit voneinander entfernt sind.

An der Genauigkeitsgrenze vom Datentyp arbeiten ist nicht unbedingt das gelbe vom Ei.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Apr 14, 2013 16:31 
Offline
Compliance Officer
Benutzeravatar

Registriert: So Aug 08, 2010 08:37
Beiträge: 460
Programmiersprache: C / C++ / Lua
Ihr könntet natürlich auch eigene Datentypen schreiben und verwenden. Nachteil wäre allerdings, dass es nicht so schön wäre diese zu verwenden und der größere Speicherverbrauch und die langsameren Berechnungen.

_________________
offizieller DGL Compliance Beauftragter
Never run a changing system! (oder so)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Apr 14, 2013 16:47 
Offline
DGL Member

Registriert: Sa Okt 18, 2008 11:59
Beiträge: 180
Ich hatte mal einen TimerManager gebastelt. Da hast du quasi dasselbe Problem, da ich GENAUER sein wollte als Milisekunden. Also sollte ich doubles nehmen? Wollte ich nicht, da diese, je länger das Programm läuft, unpräziser werden.

Lösung: neue Time-Klasse mit überschriebenen Operator-Funktionen (du nutzt ja schließlich C++ ;)), hat eine Int für den Vorkommaanteil und einen Double für den Nachkommaanteil.

Und so könntest du es auch machen, du hast einen Int für beispielsweise Kilometer und für alles kleinere nimmst du dann den double.
Oder halt die Sektorenzerlegung die Lord Horazont vorgeschlagen hat.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Apr 14, 2013 16:52 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
Das mit den Sektoren ist uns auch schon inden Sinn gekommen, nur würde dies ja zusätzlichen Aufwand bedeuten, da man Übergabeparameter etc definieren müßte. Weiterhin bräuchte ich zusätzlichen Speicher für die Sektoren. Nehmen wir longints, hätten wir 2^64 Werte zur Verfügung. Eine kurze Überschlagsrechnung hat gezeigt, dass wir bei einer kleinsten Werteeinteilung von 10e-6 (ein tausenstel Millimeter) immer noch eine Welt mit 12 facher Größe der Distanz von Saturn und Sonne erzeugen könnten. Ich würde mal behaupte selbst bei nem Ego-Shooter sind 0.000001m mehr Genauigkeit als man braucht.

Generell würde ja mal eine Gegenüberstellung der Vor- und Nachteile von Interger gegenüber Float interessant sein. Bisher sähe die bei mir so aus:

Zitat:
Vor und Nachteile von Integer gegenüber Float:
----------------------------------------------------------

+ exakt definiert
+ keinerlei operative Fehler in Addition, Subtraktion und Multiplikation
- wesentlich kleinerer Wertebereich
- teilweise Konversationen für bestimmte mathematische Funktinen notwendig(Wurzel ziehen beispielsweise)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Apr 14, 2013 17:12 
Offline
DGL Member

Registriert: Sa Okt 18, 2008 11:59
Beiträge: 180
Konvertierung nicht Konversation...

Du hast aber unter Umständen vielleicht UNPRÄZISERE Divisionen als bei Fließkomma.

Ein Vorteil bei Sektor wäre das du die lokalen Koordinaten besser an OpenGL übergeben kannst. Meines Wissens nach gibt es keine Möglichkeit 64Bit-Ganzzahlen in Matrizen zu packen.

Ansonsten... wenn es passt kannst du das tun.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Apr 14, 2013 19:49 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
hm, das mit der KONVERTIERUNG (Ich und Fachwörter... :mrgreen: ) ist die Frage. Möglicherweise schlägt das etwas auf die Geschwindigkeit. Schließlich muss ich ja alle Weltkoordinaten transformieren für OpenGL... :/ Alles nicht so einfach. Ich muss mir das echt nochmal durch den Kopf gehen lassen... Vielleicht wäre auch die angegebene eigene Variablndeklaration sinnvoll...


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Apr 15, 2013 08:54 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Du musst dabei weiterhin beachten, dass du OpenGL nicht einfach die absoluten Koordinaten füttern kannst, denn da wird das ganze wahrscheinilch gar zu einem 32-bit Float. Selbst wenn du in deiner Anwendung hochpräzise rechnest, kannst du dann am Rande des Genauigkeitsbereiches lustige Grafikfehler bekommen.

Dementsprechend musst du das alles in einen lokalen Raum, z.B. die Kameraposition umrechnen, was nochmal aufwand bedeutet (da du dies jeden Frame machen musst, während du z.B. die Koordinaten relativ zur Sektormitte einfach für alles verwenden könntest). Die Berechnung kann nicht in OpenGL passieren, da du eben deine präzisen Werte nicht in Matrizen bekommst.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Apr 16, 2013 00:08 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
Immer wieder interessant... man findet etwas zu dem Problem, wenn man es bereits selbst gelöst hat xD :

http://arcsynthesis.org/gltut/Positioni ... Space.html

Letztendlich wird das ganze so verlaufen: Meine Weltkoordinaten werden aufgrund der Präzision LongInts werden. Bevor OpenGL die Koordinaten überreicht bekommt, rechne ich alle Weltkoordinaten in Kamerabezugskoordinaten um (simple Subtraktion). Die werden dann noch in Float konvertiert und anschließend an OpenGL übergeben. Somit nimmt die Präzision mit dem Abstand zur Kamera und nicht vom Weltenursprung ab. Ob ein paar tausend Kilometer entfernte Objekte nicht mehr auf den Meter genau abgebildet werden können, kann mir ja egal sein, da diese meist gar nicht mehr gerendert werden. ;)

Einzige Überlegung die noch bleibt: Wie stelle ich mein Frustrum richtig ein? Eine zu große Spanne zwichen Near und Far soll sich ja angeblich negativ auswirken, allerdings will ich die weit entfernten, riesigen Planeten auch noch rendern... einfach manuell skalieren und bis ins Frustrum vor ziehen?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Apr 16, 2013 09:48 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Nov 30, 2011 21:41
Beiträge: 136
Wohnort: Bad Vilbel
Programmiersprache: Delphi 7
Es gilt eigentlich immer für den Far-wert: So groß wie nötig, so klein wie möglich. (So groß dass man die relevanten Sachen noch sieht und nicht einfach riesige Objekte einfach auftauchen, aber so klein wie möglich, dass deine Anwendung noch performant bleibt.) Aber hier ein Trick wegen den Planeten:

Viele Spiele verwenden für sowas Billboards. Kurz du renderst die Planeten in ein FBO und packst dann die Textur einfach auf ein Quad in die Ferne. Eine performante Umsetzung wäre:

- Colorbuffer leeren
- Depthtest deaktivieren und Planenten rendern.
- Depthbuffer leeren und Depthtest wieder aktivieren
- Weltraumszene zeichnen
- SwapBuffers()

Vorteil von dieser Reihenfolge:
Es muss Color/Tiefenbuffer nur einmal geleert werden und du musst nicht aufpassen, dass deine Planeten ausversehentlich anderen Objekte verdecken.

Vorteil von Billboards:
Nahezu kein Performanceverlust, da für jeden Planet nur ein Texturiertes Quad gerendert werden muss. Das rendern in die FBOs
kannst du einmal am Anfang machen, denn auf die Ferne sollte es ja egal sein, von welcher Seite du gerade den Planeten betrachtest.

Nachteile von Billboards:
- Schatten für die Billboards müsstest du, wenn du sie umbedingt brauchst, selbst berechnen.
- Man sieht den Planeten immer von der selben Seite.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Apr 16, 2013 10:00 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Die beste Implementierung die ich kenne ist ein 3D Array für Sektoren und double precision für ein Sektor(wenn es um genauigkeit geht).
Man kann auch auf float setzten und sollte dann auf jeden Fall zwischen -1.0 und 1.0 bleiben und im vertex shader auf die echte dimension skalieren, um die Ungenauigkeit möglichst bis zum Ende zu vermeiden.
Double ist so Präzise, dass man mit großen Zahlen arbeiten kann ohne Probleme mit der Genauigkeit zu bekommen aber man muss immer zwischen float und double konvertieren, weil gpu nun mal flink mit floats sind.

Passend zum Thema kann ich folgende Seite und Buch empfehlen.
http://www.virtualglobebook.com/

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Apr 16, 2013 14:21 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
@Dinge in der Ferne: Für den Fall, dass sich die fernen Objekte nicht mit nahen überlappen (was bei riesigen weit entfernten Planeten der Fall sein sollte), kann man auch mehrere Passes machen, wobei unterschiedliche Near und Far-Werte nimmt.

Einen Pass für die nahen Objekte mit möglichst kleinem Far, und einen Pass für die fernen Objekte, mit möglichst großem Near und beliebig großem Far.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Apr 16, 2013 14:37 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Um 2Pass verfahren zu umgehen, kann man auch Imposter verwenden.
Man rendert für die fernen Planeten und Himmelskörper Quads, mit einem vorher im fbo gerendertem textur und verwendet die so lange, bis der kamerawinkel nicht mehr stimmt oder sich der Winkel des Objektes ändert und die Textur aktualisiert werden muss.
Dabei wird der Tiefentest deaktiviert und von hinten nach vorne sortiert und gerendert.
Ja da gibt es overdraw aber das sind Objekte, die auf dem Bild eh nur noch so 32x32 Pixel ein nehmen, wenn überhaupt.

Für alles, was mehr Platzt ein nimmt, lohnen sich Cube Imposter, also man rendert per Shader eine Kugel in den Cube und tut per raytracing die textur drauf projezieren. Alternative Raytracing auf ein Volume Textur. Das sollte aber dann bei größer werden, des Renderbereiches auch nicht mehr verwendet werden.
Für Objekte die noch größer werden, switcht man dann auf Mesh um und kann dann über Chunked LOD mit mesh morphing ohne ploppen gemacht werden.

Das ganze läuft auch auf älteren Karten sehr schnell, skaliert wunderbar und man hat kein ploppen.
Der Nachteil ist, man hat viel aufwand die Systeme ein zu bauen aber LOD ist nun mal ein Komplexes Thema.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Apr 17, 2013 00:20 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
Ohje.. jetzt fliegen ja doch schon einige Fachwörter durch den Raum, die ich erstmal googeln muss... :mrgreen: Außerdem befinde ich mich noch am Anfang von http://arcsynthesis.org/gltut/ . Ich habe zwar schon einige nette Programme mit OpenGL verzapft aber richtiges 3D habe ich bisher immer umschiffen können. Deswegen mögen man mir verzeihen wenn ich an einigen Stellen noch nicht ganz mitkomme. Ich bemühe mich das so schnell wie möglich aufzuarbeiten :)

Also wenn ich Lord Horazont richtig verstanden wäre der vorschlag prinzipiell folgendermaßen:

- Projektionsmatrix setzen (...,...,Near =sehr groß, Far = Noch größer)
- weit entfernte Objekte rendern
- Projektionsmatrix setzen (...,...,Near =normaler Wert, Far = normaler Wert)
- restliche Objekte rendern
- Buffer swappen

richtig Verstanden?

MfG Der Troll


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Apr 17, 2013 16:54 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Jupp, und zwischen Fern und Nah den Tiefenpuffer killen. Was Tak erzählt ist aber definitiv die coolere Profi-Variante.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]