OpenGL - Lichtquellen mit double positionieren****

thekiller

Viceinator
Nabend,

ich programmiere zur Zeit an einer Engine in OpenGL und mir ist gerade aufgefallen, dass man mit glLightfv() den 3. Parameter nur als float* angeben kann und damit die Positionieren auch nur in float.
Gibts da ne Möglichkeit trotzdem den Wertebereich von double nutzen zu können? Eventuell eine andere OpenGL Funktion? Oder muss ich mich mit float begnügen?

MfG Manuel
 
Hallo Manuel,

bei Verwendung der Fixed-Function-Pipeline bleibt dir nichts anderes übrig als die Lichtparameter in einfacher Fließkommagenauigkeit zu übergeben. Du kannst diese Einschränkung (ist das für dich wirklich eine?) umgehen, indem du Shader verwendest und deine Parameter z.B. über glUniform3d setzt.

Grüße,
Matthias
 
Hi Matthias,

mit Shadern habe ich leider noch nicht gearbeitet. Nur mal kurz überflogen. Ich denke ich bleibe dann vorerst ersteinmal bei float bevor ich etwas verwende wovon ich kaum Ahnung habe. Ich kann ja alle sichtbaren Objekte beim rendern immer relativ in Richtung Koordinatenursprung verschieben sobald die Absolute Position float überschreitet...Kostet zwar Rechenzeit aber sollte gehen.

Danke trotzdem!

Mfg Manuel
 
Zuletzt bearbeitet:
Hallo Manuel,

mit welchen Einheiten rechnest du denn, dass du Werte auf größer als 10^38 kommst? :eek: Wieso skalierst du dein Koordinatensystem nicht einfach, um kleinere Zahlen zu erhalten?

Grüße,
Matthias
 
Im Moment bin ich noch nicht soweit, dass ich solche hohen bzw. niedrigen Werte erreiche.

Nur zum Verständnis. Wenn ich einen Integer-Wert habe(32-Bit) dann habe ich ja einen Wertebereich von ?2.147.483.648 bis +2.147.483.647.
Float hat ja ebenfalls 32 Bit. Da ich hinter dem Komma ja auch noch eine bestimmte Genauigkeit erwarte (sagen wir mal 4 stellen), dann minimiert sich doch der Wertebereich vor dem Komma richtig?

So dass ich z.B. nur von -10000.0000 bis 10000.0000 habe (ist natürlich ein ausgedachter Wert!!).

Es ist ja nirgends ne Angabe zu finden welche Höchstwerte man bei welcher Genauigkeit nach dem Komma erreichen kann.
Mit 1.5E-45 bis 3.4E38 kann hier ich irgendwie nichts anfangen...
Desswegen wollte ich double verwenden weil ich damit definitiv auf der richtigen Seite wäre was Platz angeht ;-)



MfG Manuel
 
Die Formel die du gerne hättest kann man sich auch herleiten, wenn man weiß wie Maschinen-Fließkommazahlen aufgebaut sind[1]:

F(t,?,?) = { M·2^E | M = 0 oder 2^(t-1) ? |M| < 2^t; ? ? E ? ?; M, E ? ? }

Die Menge der floats wäre damit F(24,-148,104), doubles wären über F(53,-1074,971) charakterisiert.

Zwei aufeinanderfolgende Zahlen M·2^E und (M+1)·2^E mit gleichem Exponenten E unterscheiden sich immer um den Wert (M+1)·2^E - M·2^E = 2^E. Wenn dieser größer als beispielsweise 0,0001 ist, kann die vierte Nachkommastelle nicht mehr exakt wiedergegeben werden:

2^E > 0,0001
E > log?(0,0001) ? -13,29

Mit E = -14 haben wir also noch vier Nachkommastellen Genauigkeit, mit E = -13 schon nicht mehr. Da |M| < 2^t gilt, ist die größte darstellbare Zahl mit E = -14 gleich (2^t – 1)·2^(-14). Für floats (t = 24) ergibt sich so ca. 1024, für doubles (t = 53) ca. 549.755.813.888. Aus Symmetriegründen sind die jeweiligen Untergrenzen vom Absolutbetrag her identisch.

Allgemein gilt also: eine vorgegebene Genauigkeit ? wird im Bereich ±(2^t – 1)·2^(floor(log?(?))) erreicht, mit t = 24 für float und t = 53 für double.

Grüße,
Matthias

[1]: Angelehnt an http://www5.in.tum.de/lehre/vorlesu...11/vorl/NumPro_WS1011_Vorlesung_Kapitel_1.pdf
 
Okay ich habs eben mal ermittelt.

Wenn ich float verwende und mit einer Genauigkeit von 3 Nachkommastellen rechne, dann kann ich bis etwas über 10000.000 im Positiven bereich gehen. Das würde einer realen Genauigkeit von 1mm entsprechen. Also 10 x 10 x 10 Kilometer. Das ist mir etwas zu wenig. Da würde ich ja grad mal ne Kleinstadt reinbekommen.
Mit double sind es über 1 x 1 x 1 mrd Kilometer. Dass reicht auf jedenfall. Also muss ich entweder immer relativ zum Koordinatenursprung rechnen oder wie du sagtest mit Shadern.
 
Bei drei Nachkommastellen komme ich auf über 16.000 Einheiten pro Richtung, also insgesamt über 32.000 in jede Dimension. Damit kannst du eine Fläche von über 1.024km² abdecken. Da passt Berlin locker rein. Welche Dimensionen schwebten dir denn so vor?

Grüße,
Matthias
 
Ja wie ich schon erwähnte ich hatte nur den positiven Wertebereich ermittelt. Also müssten dass etwas über 20 x 20km sein bei 3 Stellen nach dem Komma. Wenn ich z.B. 15000.000 um 0.001 addiere, dann habe ich schon eine Abweichung von 0.001 bis 0.002.

Dimensonen können durchaus in den Millionenbereich gehen, da auch kleinere Sonnensysteme simuliert werden sollen. Logisch, dass nicht alles gleichzeitig dargestellt werden kann aber wenn ich mich auf Planet X befinde, welcher sich außerhalb des Wertebereichs von float befindet, und da eine Lichtquelle vorhanden sein soll, dann kann ich diese nicht positionieren grr
Nervt mich echt gerade weil ich meine Engine schon recht weit hatte was das Objekthandling angeht habe und das jetzt teilweise verwerfen kann.

Is echt nen unding, dass man mit OpenGL Mitteln Objekte mit double positionieren kann aber Lichtquellen nicht -.- Damit hätte ich mir jetz einiges sparen können -.-
 
Ja wie ich schon erwähnte ich hatte nur den positiven Wertebereich ermittelt. Also müssten dass etwas über 20 x 20km sein bei 3 Stellen nach dem Komma. Wenn ich z.B. 15000.000 um 0.001 addiere, dann habe ich schon eine Abweichung von 0.001 bis 0.002.
Wie kommst du auf diese Zahlen? Wenn ich ? = 0,001 in die Formel einsetze, kommt bei mir rund 16.384 raus. Bei 15.000 hat man demnach noch eine Abweichung von unter 0,001. Das kannst du mit einem einfachen C-Programm auch überprüfen.

Dimensonen können durchaus in den Millionenbereich gehen, da auch kleinere Sonnensysteme simuliert werden sollen.
Aber da brauchst du doch keine Genauigkeit von einem Millimeter!?

Logisch, dass nicht alles gleichzeitig dargestellt werden kann aber wenn ich mich auf Planet X befinde, welcher sich außerhalb des Wertebereichs von float befindet, und da eine Lichtquelle vorhanden sein soll, dann kann ich diese nicht positionieren grr
Verwende doch pro Planet ein lokales Koordinatensystem. Dann hast du keine Probleme mit zu ungenauen Fließkommazahlen.

Is echt nen unding, dass man mit OpenGL Mitteln Objekte mit double positionieren kann aber Lichtquellen nicht -.- Damit hätte ich mir jetz einiges sparen können -.-
Es ist fraglich, ob dein OpenGL-Treiber intern überhaupt mit double arbeitet oder die Werte sofort nach der Übergabe in float konvertiert. Grafikkarten können noch nicht allzu lange mit double rechnen (siehe z.B. https://www.opengl.org/registry/specs/EXT/vertex_attrib_64bit.txt). Du kommst diesem Problem also so und so nicht aus.

Grüße,
Matthias
 
Zurück