Registriert: Sa Sep 29, 2007 18:43 Beiträge: 38 Wohnort: STR / BLN / LAU
Hallo,
ich bin noch relativ neu auf dem Gebiet. Wenn ich was verdrehe bitte Nachsicht.
Mein Hirn ist Moment ganz schön weich!
Ich betreibe Render-To-Texture. Die Output-Textur in die gerendert wird, besteht aus einem internen RGB16-Format, wobei jeder Texel dann 4 Grauwerte enthält. Die Input-Textur ebenfalls. Die Input-Textur wird in ein großes Viereck gelegt, so groß wie der Viewport. Ich möchte die gerenderten Werte aus der Output-Textur NICHT farblich anzeigen lassen, sondern nur Berechnungen im Shader rüber laufen lassen und die Werte anders weiter verwenden.
Nun die Fragen:
1. Wenn ich den Shader benutze, muss ich selber auf die Input-Textur mittels Sampler2D
zugreifen?
2. Falls 1. "Ja" dann ist glEnable(GL_TEXTURE_2D) überflüssig?
3. Über die 3 Special-Output-Variables des Shaders kann ich nur float-werte zurückgeben, gibt
es Konvertierung um UINT zurück zu geben?
4. Wenn 3. "Nein", wie kann ich UINT aus meinem Shader lesen?
Oder gibt es noch eine andere Möglichkeit, außer die Textur, um die zu verrechnenden UINT-Daten in den Shader zu bekommen und berechnete Werte wieder raus und das Ganze schnell und zackig?
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Daniellus hat geschrieben:
3. Über die 3 Special-Output-Variables des Shaders kann ich nur float-werte zurückgeben, gibt es Konvertierung um UINT zurück zu geben?
Was genau meinst du mit "Special-Output-Variables"?
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my 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
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Also zumindest ich habe es nicht richtig verstanden glaub ich...
4 Grauwerte pro Texel sind bei meiner Rechnung aber nur 2 bit.
Oder wir reden was den Begriff Texel betrifft aneinander vorbei.
Du meinst sicher 4 bit pro Komponente ? Sonst komm ich irgendwie nich auf die 12 bit.
Nochmal grob zum Verständnis:
Ich nehme an du willst "Nicht-Grafik"-Berechungen auf der GPU machen, oder?
Du hast eine bestimmte Menge an Werten. Zusammengepackt in eine Textur. Und der Shader soll das Ergebnis in Form eines "Bildes" im Viewport ausgeben?
Anschliessend wieder in eine Textur gepackt kann man das doch wunderbar handhaben und wieder auslesen.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
damadmax hat geschrieben:
Also zumindest ich habe es nicht richtig verstanden glaub ich... 4 Grauwerte pro Texel sind bei meiner Rechnung aber nur 2 bit. Oder wir reden was den Begriff Texel betrifft aneinander vorbei. Du meinst sicher 4 bit pro Komponente ? Sonst komm ich irgendwie nich auf die 12 bit.
Grauwerte müssen nicht nur binär sein. Denk doch mal an 256 Graustufen Bitmaps.
Aber ich komm mit der "Aufgabenstellung" ehrlichgesagt auch nicht ganz klar.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my 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
Registriert: Sa Sep 29, 2007 18:43 Beiträge: 38 Wohnort: STR / BLN / LAU
Ich geh genauer auf mein Vorhaben ein...
Zuerst einmal:
Die Special-Output-Variables sind gl_FragColor, glFragData und glFragDepth.
Mein Vorhaben:
- nicht-grafische Berechnungen
- habe ein 12-Bit-Graustufenbild, welches bestimmte Filter(math. Algorithmen) passieren muss
- habe ein Array im Applikationsspeicher mit dem originalen 12-Bit-Graustufen-Bild
- diese Graustufen-Werte werden in eine 16-Bit-RGBA-Textur gepackt
- jedes Texel enthält als RGBA-Wert jeweils 4 Graustufen-Werte aus dem Originalbild
- z.Bsp.: R=1297 G=1134 B=1432 A=2341
- der Viewport enthält ein QUAD, beide sind so groß wie die Input-Textur, alle OpenGL-Filter
werden abgeschalten, so das die Textur-Werte bei Eintritt in die Pipeline nicht interpoliert
werden
- die Input-Textur füllt dann sozusagen das nicht vorhandene Fenster Komplett aus
- in eine Output-Textur soll gerendert werden
- die Output-Textur wird dem Framebuffer hinzugefügt
- nach dem Rendern landen die Werte dann im Framebuffer( theoretisch )
- das ganze nennt sich wohl auch Offscreen-Rendering
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
also wenn ich das richtig verstanden habe, sind deine beispielwerte bisschen zu groß
denn maximal kann man pro texel 32 bit speichern.
ob in GL_UNSIGNED_INT_8_8_8_8 oder GL_UNSIGNED_INT_10_10_10_2...maximum ist immer 32bit.
bei deinen werten komme ich aber auf 45 bit.
R=1297 min 11 bit
G=1134 min 11 bit
B=1432 min 11 bit
A=2341 min 12 bit
16 rgba textur heisst nicht das jede komponente 16 bit hat. sondern insgesamt 16bit sprich 4 pro komponente. siehe GL_UNSIGNED_SHORT_4_4_4_4
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
damadmax: Jain. GL_UNSIGNED_SHORT_4_4_4_4 bezieht sich normal auf eine GL_RGBA4 Textur. Und da hat jeder Kanal nur 4 Bit. Das stimmt so. Aber GL_RGBA16 sollte normal schon 16 Bit Pro Kanal sein. Aber der Treiber hat natürlich über allem die Macht und er kann entscheiden, dass er doch wieder ein anderes Format benutzt.
Theoretisch gibt es sogar GL_RGBA12. Mit 12 Bits pro Kanal. Eigentlich genau das gewünschte Format. Allerdings unterstützen das weder ATI noch NVidia.
Ich habe gerade mal geschaut und laut der einen Doku die ich da habe unterstützt NVidia (Bis NV4 (GFeorce6)) lediglich die 32 Bit Float Formate (Mehr als 8 Bit). Die RGBA16 werden intern auf 8 Bit gemapped. ATI hingegen unterstützt sowohl Floatformate als auch GL_RGBA16 allerdings steht nicht dabei welche Generation das ist. Tippe aber mal auf neu. Also solltest du IN JEDEM FALL von deinen erstellten Texturen die Daten abfragen und sollte es nicht unterstützt werden dann ein anderes Format benutzen. Dazu eignen sich die GL_PROXY_TEXTURE_2D da sie das Ganze nur simulieren.
Und sonst solltest du in jedem Falle in ein FrameBufferObject hinein rendern. Denn im normalen Framebuffer können die Daten auch schnell mal verlohren gehen, da dieser normal nur die 16 oder 32 Bit des Systems macht. Maximal 8 Bit. Es gibt zwar auch Floating Point Frambuffer aber wie die genau gehen weiß ich nicht. Die Extension müssten bei den WGLs zu finden sein. Mit dem FBO kannst du aber das Format aber direkt angeben. Und dieses sollte man eigentlich auch wieder auslesen können. Bzw auch wieder als Textur benutzen etc.
Registriert: Sa Sep 29, 2007 18:43 Beiträge: 38 Wohnort: STR / BLN / LAU
Hallo,
ich bin da jetzt nen bisschen schlauer als vorher.
Erstmal zum letzten Beitrag:
Also RGBA16 als internes Format, heißt wirklich das man 16 Bit pro Komponente speichern kann.
Also zusammen 16*4Bit pro Texel. Maximal müssten 32Bit pro Komponente möglich sein, also 128 Bit pro Texel.
Meine Grauwerte haben eine Auflösung von 12Bit, das heißt ich kann sie nur in 16Bit-Komponeten packen.
Deine Rechnung mit 45 Bit für ein Texel ist zwar mathematisch richtig, aber ich kann ja keine 11-Bit-Komponenten für ein Texel angeben. Geschweige denn für RGB 11Bit und für den A dann 12 Bit, also RGB11A12.
Ich brauche als RGBA16, von daher ist es eh egal, ob es 12 oder 11 bit effektiv genutzter Speicherplatz sind.
Zum Rest der Geschichte:
Ich weiß das mit den RGBA16Bit, weil ich es glücklicherweise geschafft habe, das der Fragmentschader die Werte von der Input-Textur liest, sie mit dem Algorithmus verrechnet und das Ergebnis in die Output-Textur bzw. in den Offscreen-Bereich des Framebuffer schreibt, wo ich die Daten nur auslesen muss. Juhuuuuuu!
Da habe ich dann ganz große bekommen als es lief... Über glFragColor, habe ich die berechneten Werte ausgegeben. Da glFragColor ja float-werte beinhaltet und meine Output-Textur UINT-Formatiert ist, dachte ich das hackt sich. Tut es aber nicht. Entweder Konvertiert irgendetwas die Werte, oder es findet irgendeine Normierung[0.0 1.0] vor dem Shader statt und wird danach rückgängig gemacht. Was ich für wahrscheinlich halte, denn die Farbwerte, wenn man glFragColor=vec4(1.0, 0.5, 0.4, 0,3) beschreibt, gibt man ja auch in diesem Bereich an.
Vielen Dank an alle, welche sich Gedanken machten...
Bei Fragen oder Interresse zu dem Thema stehe ich natürlich zur Verfügung...
Registriert: Sa Sep 29, 2007 18:43 Beiträge: 38 Wohnort: STR / BLN / LAU
hallo Lossy,
ich benütze einen FBO.
RGBA16 klappt bei mir ja wie vorher erwähnt. RGBA12 habe ich noch nichts gelesen, wäre aber top wenn das ginge. Ich probier das morgen gleich mal. GL_LUMINANCE12 und GL_LUMINANCE16 funktioniert bei mir nicht. Wahrscheinlich macht die Karte es nicht, obwohl diese ja sehr aktuell ist (NVidia 8800 GTS).
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Von NVidia gibts ein Dokument, in dem drinsteht welche GPU welche Texturformate unterstützt. Hier gibts dieses als PDF und XLS. 12-Bit Formate werden aber auf keiner Karte (zumindest NVidia) unterstützt, da diese eigentlich zu speziell sind und kaum Verwendung finden würden.
Registriert: Sa Sep 29, 2007 18:43 Beiträge: 38 Wohnort: STR / BLN / LAU
Hallo,
vielen Dank für die Übersicht, gibt ja ne Menge Formate! Leider ist das letzte Update irgendwann 2004 gewesen und die 8000 Baureihe von NVidia ist nicht drauf. Wenn ich das richtig sehe ersetzen die NVidia-Karten das RGBA12 und RGBA16 durch eine 8-Bit-Genauigkeit. Zumindestens scheint die 8000-Reihe RGBA16 zu akzeptieren.
RGBA12, macht die gleichen seltsamen Dinge wie LUMINANCE12.
Texture-Input besteht aus 256 Werten von 0-255, Output-Texture hat dann nur 0.
Beinhaltet das Input Zahlen von 256-511, ist im Output nur 257 enthalten.
Ab Input 512-767 ist im Output nur 514 enthalten.
Ab Input 768-1023 ist in der Ausgabe nur 714.
Ab 1024 , dann immer 1028.
Mal davon abgesehen das Werte über 255 ja gar nicht in 8-Bit darstellbar sind, kann ich das Rätsel nicht lösen.
Außer das die Differenz zwischen den Ausgabe-Zahlenwerten immer gleich ist, sehe ich keinen Zusammenhang.
Na Ja, ist ja nun auch nicht so wichtig, wäre schon gut gewesen 4 Bit zeitl. Schreib/Leseaufwand zu sparen.
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Lossy eX hat geschrieben:
damadmax: Jain. GL_UNSIGNED_SHORT_4_4_4_4 bezieht sich normal auf eine GL_RGBA4 Textur. Und da hat jeder Kanal nur 4 Bit. Das stimmt so. Aber GL_RGBA16 sollte normal schon 16 Bit Pro Kanal sein. Aber der Treiber hat natürlich über allem die Macht und er kann entscheiden, dass er doch wieder ein anderes Format benutzt.
ich glaub ich halte dann einfach mal die klappe wenn die grossen jungs sich unterhalten
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Mitglieder in diesem Forum: 0 Mitglieder und 5 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.