Wie kann ich positive und negative Werte in einer Textur speichern?

Dec 03 2020

Ich erstelle ein Programm, in dem ich die GPU für Berechnungen (über Fragment-Shader) verwende und signierte Werte in Texturen speichern muss.

Meine Textur wird mit GL_FLOAT wie folgt initialisiert:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, nullptr);

Und soweit ich Opengl verstehe, müssen einzelne Texel im Bereich [0,1] liegen, wenn GL_FLOAT verwendet wird (wenn ich mit glClear experimentiert habe, werden meine Werte auf diesen Bereich begrenzt). Was ich bisher gemacht habe, ist, meine Werte basierend auf ihrem tatsächlichen Bereich auf den Bereich [-1,1] zu verkleinern und diesen dann in [0,1] umzuwandeln, bevor ich ihn zurück in die Textur schreibe. Der nächste Shader, der mit den Daten arbeiten muss, liest den Texelwert und verschiebt ihn auf [-1,1], bevor er fortfährt und so weiter ...

Meine Frage ist, ist dies der richtige Weg, um mit negativen Werten umzugehen? Ich bin mir ziemlich sicher, dass die wiederholten Konvertierungen dazu führen, dass sich fp-Fehler ansammeln, was offensichtlich nicht gut für die Genauigkeit ist.

Vielen Dank

Antworten

1 httpdigest Dec 03 2020 at 15:04

Siehe auch: Unterschied zwischen Format und internem Format

Das interne Format (dritter Parameter glTexImage2D) entscheidet , wie die GPU speichert und interpretiert diese Werte, nicht der Typ - Parameter glTexImage2D(zweiten bis letzten Parameter). Dieser Parameter entscheidet, wie der Treiber Ihren Client- / Host-seitigen Speicher beim Hochladen in die Textur interpretieren soll, die Sie derzeit nicht verwenden nullptr.

Sie können den signierten 8-Bit verwenden GL_RGBA8_SNORModer die 16-Bit - Gleitkomma - GL_RGBA16Foder 32-Bit - Floating-Point - GL_RGBA32FGröße internes Formats für die Textur.

Im Allgemeinen sollten Sie immer ein verwenden Größe internes Format sein explizit über das, was Sie wollen und bekommen.

Siehe die Tabelle zu: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml

Wenn Sie also nur eine 8-Bit-Auflösung und Werte im Bereich [-1, 1] benötigen, können Sie Folgendes verwenden:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_SNORM, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

Das vorletzte Argument ist eigentlich irrelevant, da wir keine Texeldaten in die Textur hochladen.