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

Aktuelle Zeit: Fr Jul 18, 2025 08:11

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



Ein neues Thema erstellen Auf das Thema antworten  [ 68 Beiträge ]  Gehe zu Seite 1, 2, 3, 4, 5  Nächste
Autor Nachricht
BeitragVerfasst: Di Sep 21, 2010 14:50 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
Hallo,

als Weiterführung aus diesem Thema: viewtopic.php?f=2&t=9346&start=30
gehts nun um die 3D-Texturen. Musste leider ein kleine Pause einlegen darum gehts jetzt erst weiter.
Kurz:
Ich möchte mehrere Projektoren (Scheinwerfer) mittels Shadern realisieren. Dazu möchte ich die zu projezierenden Texturen über eine 3D-Textur in den Shader bekommen, damit ich nicht die TMU Begrenzung beachten muss.

Habe leider nicht viel über 3D-Texturen gefunden. Wie bekomme mehrere 2D-Texturen in eine 3D-Textur?

Kurze Frage nebenbei:
Kann ich einem Shader ein dynamisches Array (4x4Matrizen) übergeben?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Sep 21, 2010 15:34 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Wie bekomme mehrere 2D-Texturen in eine 3D-Textur?

Ich würde mal glTexImage3D mit GL_TEXTURE_2D_ARRAY als Target vorschlagen. Selbst gemacht habe ich das noch nicht. Bei einer normalen 3D-Textur würde nämlich auch in Z-Richtung linear interpoliert, was ja hier nicht erwünscht ist. Ich glaube das braucht die Extension GL_EXT_texture_array (oder OpenGL 3.0). Im Shader musst du dann auch entsprechend einen Array-Sampler und die Array-Texturzugriffsfunktionen (ab GLSL 1.3, siehe Spec) benutzen.

Zitat:
Kurze Frage nebenbei:
Kann ich einem Shader ein dynamisches Array (4x4Matrizen) übergeben?

Du kannst Uniform-Arrays übergeben, diese müssen aber eine konstante Größe haben. Wenn du aber zusätzlich die Größe des Arrays als Uniform übergibst hast du ein dynamisches Array, zumindest in einem gewissen Rahmen. Beachte das die Anzahl der Uniforms begrenzt ist. Für größere Datenmengen eignet sich die Verwendung einer Textur mit einem Float-Format, z.B. GL_RGBA32F_ARB was aber die Extension GL_ARB_texture_float (oder OpenGL 3.0) benötigt. Das ist dann wirklich dynamisch. Besser als Texturen sind für solche Fälle natürlich TBOs, was aber recht aktuelle Hardware erfordert.

Kleines Beispiel:
Meine Textur hat jeweils eine Matrix pro Zeile, bei 4 floats pro Texel ist sie also 4 Texel breit. Wichtig ist das der Texturfilter auf GL_NEAREST steht damit nicht zwischen Texel interpoliert wird.
Code:
uniform sampler2D tTextureMatrices; // Textur mit GL_RGBA32F_ARB als internes Format
uniform float uTextureMatrices; // Anzahl Matrizen

// exakte Texelkoordinaten berechnen
#define TEXEL(texel, textureSize) ((0.5 + float(texel)) / float(textureSize))

void main() {
   float matrixPos = TEXEL(gl_MultiTexCoord0.x, uTextureMatrices);
   mat4 texMatrix = mat4(
      texture2D(tTextureMatrices, vec2(TEXEL(0,4), matrixPos)),
      texture2D(tTextureMatrices, vec2(TEXEL(1,4), matrixPos)),
      texture2D(tTextureMatrices, vec2(TEXEL(2,4), matrixPos)),
      texture2D(tTextureMatrices, vec2(TEXEL(3,4), matrixPos))
   );

   // ...
}

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Sep 21, 2010 16:03 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
ui, also brauchst doch schon rel. aktuelle Grakas um 3D-Texturen in der Form zu benutzen...

Wie bekomme ich denn raus, wie viele uniform variablen (z.B. Texturen und Matrizen) ich deklarieren darf?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Sep 21, 2010 16:28 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Wie bekomme ich denn raus, wie viele uniform variablen (z.B. Texturen und Matrizen) ich deklarieren darf?

glGetIntegerv mit:
GL_MAX_VERTEX_UNIFORM_COMPONENTS (Minimum laut Spec: 512, meine Geforce 9800 GT: 4096)
GL_MAX_FRAGMENT_UNIFORM_COMPONENTS (Minimum laut Spec: 64, meine Geforce 9800 GT: 2048)

Eine "Komponente" ist hier ein vec4. Ist meines Wissens aber nicht festgelegt ob z.B. ein Array von vec2 zusammengefasst wird. Ein mat4 braucht natürlich vier vec4, ein mat3 wahrscheinlich drei vec4.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Sep 21, 2010 18:08 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
und wie siehts mit Samplern aus?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Sep 21, 2010 18:21 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 04, 2008 23:15
Beiträge: 39
Wohnort: Oberösterreich
Programmiersprache: ObjPas, C, DivASM
Thmfrnk hat geschrieben:
und wie siehts mit Samplern aus?

mittels GL_MAX_TEXTURE_IMAGE_UNITS


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Sep 21, 2010 19:06 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
erstmal vielen dank für die schnellen Antworten.

Was passiert denn wenn ich in einem Shader mal mehr als unterstützt deklariert habe, läuft dann der ganze shader nich mehr?

Gibts denn bei GL_MAX_TEXTURE_IMAGE_UNITS auch einen Mindestsupport?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Sep 21, 2010 20:10 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 04, 2008 23:15
Beiträge: 39
Wohnort: Oberösterreich
Programmiersprache: ObjPas, C, DivASM
Thmfrnk hat geschrieben:
Was passiert denn wenn ich in einem Shader mal mehr als unterstützt deklariert habe, läuft dann der ganze shader nich mehr?

Richtig, dann wird das compilieren des Shader fehlschlagen.

Thmfrnk hat geschrieben:
Gibts denn bei GL_MAX_TEXTURE_IMAGE_UNITS auch einen Mindestsupport?

Laut Spezifikationen:
OpenGL 2.1 = 2 (in der Praxis werden es 4-8 sein, habe aber keine Erfahrung da ich für so eine Hardware nicht programmiere)
OpenLG 3.0 bis 3.3 = 16

Edit: 23:08 21.09.10


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Sep 22, 2010 06:09 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 11, 2009 08:02
Beiträge: 532
Programmiersprache: pascal (Delphi 7)
Zitat:
Edit: 23:08 21.09.10
Hat sich das seit 21:10 geändert? 8)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Sep 22, 2010 08:37 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
nun aktuell will ich daher gehen und 3 Shader-Varianten schreiben
- für ältere mit 2 Samplern für die Projektorbildchen
- für das mittelmaß mit 4 Samplern
- und für supi Grakas mit 32 Sampler (hat meine z.B.)

Doch ich werde das gefühl nicht los das das ein morts schreibaufwand wird, da ich ja 32 Uniformvariablen deklarieren müsste... und diese könnt ich ja nichtmal in einer schleife ansprechen.. Also brauch ich doch irgendein Arraytyp für die Texturen..


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Sep 22, 2010 09:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Sampler kann man leider nicht in ein Array packen. Warum habe ich leider auch nicht verstanden, aber aus Sicht der Hardware wird das schon seinen Grund haben.
Möglichkeiten:
1. Einfach 32 Uniform-Variablen und ein gigantisches Switch zur Texturabfrage. => Extrem hässlich aber einfachste Variante.
2. Sofern deine Texturen nicht zu groß sind kannst du alle in eine große 2D-Textur packen. Wenn eine Grafikkarte allerdings mehr als 4096x4096 Texturen kann, kann sie wahrscheinlich auch schon 2D-Array-Texturen.
3. Eine 3D-Textur mit GL_NEAREST als Texturfilter und ohne Mipmaps. Du kannst Mipmaps und einen bi- oder trilinearen Texturfilter manuell im Shader implementieren. Funktioniert, ist aber sehr langsam.
4. Kannst du vielleicht eine dem Deferred Shading ähnliche Technik benutzen damit es weniger Overhead ist mehrfach zu rendern?
5. Als Alternative zu 2. kommt möglicherweise eine VirtualTexture/MegaTexture in Frage. Extrem aufwendig zu Implementieren, dafür aber nur geringe Hardwareanforderungen (OpenGL 2.0 mit FBO-Extension reicht), Texturen von 262144 x 262144 sind recht problemlos möglich (*) und das auch noch bei guter Performance. Die Textur ist nur virtuell und liegt nicht vollständig im Grafikspeicher. Eine normale Textur dient als Cache in der 128x128 Texel große Schnipsel der großen Textur gespeichert werden. Im Shader werden die Texturkoordinaten jeweils so umgebogen das sie auf die richtige Stelle im Cache zeigen. In meiner Diplomarbeit will ich mit dieser Technik 80 GB Texturdaten managen die von einem Server auf den Client gestreamt werden. Als Einstieg in die Materie empfehle ich diese Bachelorarbeit von Andreas Neu die bei uns am Lehrstuhl entstanden ist.

(*) 524288 x 524288 und ggf. auch mehr ist ebenfalls möglich, aber dann muss man anfangen zu tricksen, da die Genauigkeit eines 32bit Floats am Ende ist.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Sep 22, 2010 17:10 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
ich versuche für den Anfang mal die 1. Variante.. doch mir ist gerade aufgefallen ich kann ja ein Sampler nur übergeben in dem ich eine Texturunit wähle (glActiveTextureARB(GL_TEXTURE1)), da eine Textur binde und diese dann mittels glUniform1iARB an den jeweiligen Sampler schicke..

Nun so kann ich doch maximal nur so viele Sampler nutzen wie ich TMUs (GL_MAX_TEXTURE_UNITS_ARB) habe ode? Denn da hab ich nur 4.. im Shader 32..

Oder hab ich da jetzt einen denkfehler..

hatte gedacht das geht so:
- setzte TMU1
- Binde Projektionstextur1
- Setze Sampler für Shader auf 1
- Binde Projektionstextur2
- Setze Sampler für Shader auf 1..

hatte gedacht das er die an den Shader übergebene Textur irgendwo zwischenspeichert..


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Sep 22, 2010 17:20 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
GL_MAX_TEXTURE_UNITS bezieht sich wahrscheinlich auf die FixedFunctionPipeline.
=>
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS (TMUs im Vertexshader)
GL_MAX_TEXTURE_IMAGE_UNITS (TMUs im Fragmentshader, glaub ich jedenfalls)
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (TMUs gleichzeitig in Vertex- und Fragmentshader)

Am besten schaust du selbst nochmal in die Spec wofür die Werte genau stehen. Ich hab jetzt nur geschaut was mir "glxinfo -l" sagt.

Zitat:
hatte gedacht das er die an den Shader übergebene Textur irgendwo zwischenspeichert..

Über glUniform1i setzt du direkt die Nummer der Texturunit. Es reicht übrigens auch das einmal zu setzen nachdem du den Shader compiliert&gelinkt hast. Erst zu dem Zeitpunkt an dem du renderst muss da auch wirklich eine Textur auf der entsprechenden TMU gebunden sein.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Sep 22, 2010 19:09 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
also bin ich quasi an die FixedFunctionPipeline gebunden wenn ich die texturen einzeln übergeben will?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Sep 22, 2010 19:22 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Was verstehst du unter "texturen einzeln übergeben"? Wenn du Shader benutzt kannst du mit glActiveTexture halt bis GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS gehen statt nur bis GL_MAX_TEXTURE_UNITS.

_________________
Yeah! :mrgreen:


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


Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] 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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.013s | 16 Queries | GZIP : On ]