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

Aktuelle Zeit: Do Mai 23, 2024 23:39

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



Ein neues Thema erstellen Auf das Thema antworten  [ 26 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
BeitragVerfasst: Sa Dez 03, 2011 15:11 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Hm ja das klingt logisch mit der Einheitsmatrix. Zur Zeit habe ich das ja mit dem glOrtho (siehe anderer Thread zum FBO) gelöst.
Aber habe es gerade umgebaut und siehe da, ich kann mir das glOrtho wirklich sparen indem ich mein Quad so skaliere wie du geschrieben hast, top!

Aber wo wir eigentlich beim Thema Shader sind erlaube ich mir mal, eine weitere Frage dazu zu stellen.
Mein Shader funktioniert jetzt soweit, ich habe jetzt allerdings eine scheinbar sehr rechenintensive Partikel-Partikel-Interaktion implementiert, das Ganze sieht dann so aus:
Code:
  1.  
  2. uniform sampler2D Texture0;
  3. uniform sampler2D Texture1;
  4.  
  5.  
  6. void main(){
  7.         vec4 data0 = texture2D(Texture0,vec2(gl_TexCoord[0]));
  8.         ivec2 aktCoords = ivec2(gl_FragCoord.xy);
  9.         //FragCoord: Raster der Pixel auf der Textur, x und y gehen von 0 bis Size-1
  10.         int x = 0;
  11.         int y = 0;
  12.         for (y = 0; y < 64; y++)  
  13.         {
  14.           for (x = 0; x < 64; x++)
  15.           {
  16.                 ivec2 newCoords = ivec2(x,y);
  17.                 vec4 read0 = texelFetch2D(Texture0, newCoords, 0);
  18.                 [...] // Tu was damit
  19.           }
  20.         }
  21.  
  22.         gl_FragData[0] = data0;
  23. }
  24.  


Je nach größe der Textur = Anzahl der Partikel (hier 64) scheint dieses texelFetch2D ganz schön Performance zu kosten.
Gibt es - außer der Technik im anderen Partikel-Tutorial - eine weitere Möglichkeit, performant an die Daten der anderen Texel zu kommen? Denn das brauche ich ja für Partikel-Partikel-Interaktion.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Dez 03, 2011 17:40 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Nun das Problem der Partikel-Partikel Interaktion ist, dass der Aufwand quadratisch ist: Für jeden Partikel muss jeder andere Partikel angefasst werden. Mit steigender Partikelzahl explodiert der Aufwand also quasi.
Du machst hier für jeden Partikel 64*64 = 4096 Texturzugriffe. Es kann möglicherweise einen leichten Schub bringen in deiner Doppelschleife zuerst x zu durchlaufen und dann y. Liegt einfach daran wie deine Textur im Speicher liegt...Zeilenweise oder Spaltenweise. Nebeneinander liegende Texel können nämlich gecacht werden, d.h. der Zugriff ist viel schneller. Du kannst noch versuchen die Datenmenge zu reduzieren. Welchen Texturtyp benutzt du? Eine RGBA-Float-Textur? Reicht vielleicht RGB? Reichen auch halbe Floats, also 16 statt 32bit pro Kanal? Ansonsten lässt sich da nicht viel optimieren, abgesehen von einer dickeren Grafikkarte natürlich :P


Was du optimieren kannst ist natürlich der Algorithmus selbst. Kannst du vielleicht auf die Partikel-Partikel-Interaktion verzichten? Reicht es vielleicht nur einen Teil der anderen Partikel anzuschauen (wie im anderen Partikeltutorial) oder kannst du die Sache vielleicht sonst irgendwie faken?

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Dez 04, 2011 11:34 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Ja sowas dachte ich mir schon.

Gut optimieren kann man am Algorithmus recht viel, das Problem ist nur für die meisten Optimierungen benötige ich halt erstmal die Position der Partikel und ich nehme an, dass die eigentlichen Berechnungen nur einen Bruchteil der Zeit benötigen wie der Texturzugriff.

Ich werde jetzt mal die Physik fertig portieren (habe es ja auf CPU-Basis schon fertig) und so weit fertig stellen wie es geht und in den Semesterferien wage ich mich dann mal an die Techniken der Version 2 :-)

[Edit] Kurze Frage: Ich habe mal bei den Texturen statt GL_RGBA32 nur GL_RGBA16 genommen und plötzlich verhalten sich meine Partikel komplett anders. Wo muss ich denn diese Änderung noch berücksichtigen?
Dachte eigentlich nur statt GL_FLOAT halt GL_HALF_FLOAT, die Extension GL_ARB_half_float_pixel wird bei mir unterstützt. (Siehe http://www.opengl.org/wiki/Floating_point_and_mipmapping_and_filtering
[/Edit]


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Dez 04, 2011 13:43 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Wichtig ist das du das interne Format änderst. Das ist der dritte Parameter von glTexImage2D. Wenn du Halffloats willst muss hier GL_RGBA16F stehen. Die Parameter 7 und 8 geben das externe Format an, das muss natürlich mit dem übereinstimmen was du mit Parameter 9 reinsteckst. Eventuelle Umwandlungen von externem zu internen Format gehen automatisch.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Dez 04, 2011 13:54 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Ja ok das klingt einleuchtend, nur ist es so, dass meine Daten die ich im Parameter 9 übergebe ja alle vom Typ
Code:
  1.  
  2. GLfloat = Single;
  3.  

sind. Und Single ist ein 32Bit Datentyp und 16Bit Fließkomma bietet Delphi nativ nicht an.
Habe dazu folgendes im Inet gefunden: http://galfar.vevb.net/wp/2011/16bit-half-float-in-pascaldelphi/
Ich werde das jetzt mal ausprobieren, sofern jemand ne elegantere Lösung hat nur her damit ;-)

[Edit]
Ok, habe nun folgendes:
Code:
  1. glTexImage2D (GL_TEXTURE_2D, 0,GL_RGB16F, Size, Size, 0, GL_RGBA , GL_HALF_FLOAT, FTextureBuffers[i]);

Wobei der letzte Parameter ein Array mit diesem Typ von obigem Link ist.
Leider funktioniert die Rück-Konvertierung scheinbar nicht.
Desweitern muss ich doch noch den Shader anweisen, mit 16 Bit zu rechnen. Dazu habe ich die Modifizierer lowp und mediump gefunden. Hat das was damit zu tun? Es tut mir Leid, dass ich da so ratlos bin aber zu Half Float Texturen mit Shader finde ich nicht wirklich viel.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Dez 04, 2011 16:23 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Es tut mir Leid, dass ich da so ratlos bin aber zu Half Float Texturen mit Shader finde ich nicht wirklich viel.

Wird daran liegen weil du dich um nicht kümmern musst...Konvertierung geht alles automatisch.

Also deine Daten liegen als Single/GLFloat vor? Dann sag ihm das auch:
glTexImage2D (GL_TEXTURE_2D, 0,GL_RGB16F, Size, Size, 0, GL_RGBA , GL_FLOAT, FTextureBuffers[i]);

Im Shader angekommen werden die Daten automatisch wieder zu float konvertiert. Das ist kein Problem, dein Falschenhals ist der Texturzugriff, nicht die Berechnung selbst. Es ist auch möglich im Shader mit halffloats zu rechnen, wenn deine Grafikkarte das unterstützt. Da musst du dir die entsprechenden Extensions anschauen. In den neueren GLSL-Versionen sind die halffloats auch schon ohne Extension verfügbar. Vermutlich geben aber die Textur-Funktionen weiterhin einen vec4 zurück. Müsste man mal in die Doku schauen, habe diese gerade nicht hier.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Dez 04, 2011 17:47 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Dann schau ich mal, wie ich das mit dem Texturzugriff noch optimiert bekomme.
Werd mal ein wenig lesen und mal schauen. Jedenfalls habe ich jetzt immerhin schon > 10000 Partikel bei 10Fps, im Vergleich zu meiner CPU-Version (2000 Fps und dann ist Schluss) ein deutlicher Fortschritt :).

Btw habe ich gerade die zweite Textur eingebunden um mehr Daten zu haben und mir ist aufgefallen, dass ich wenn ich in den FBO render noch ein glDrawBuffers() mit den zwei Attachments brauche, damit gl_FragData[i] mit i > 0 auch "wirkt". Steht nicht im Tutorial, daher poste ich das mal. Korrigiert mich bitte, wenn ich was falsches sage^^
[Edit] Man braucht es doch nicht, im Gegenteil, kostet einen Haufen Performance[/Edit]


Zuletzt geändert von Flips am Mo Dez 05, 2011 20:50, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Dez 04, 2011 23:28 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Ähmm..gibts eigentlich analog zu texelFetch2D sowas wie texelSet2D?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Dez 05, 2011 19:36 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Ähmm..gibts eigentlich analog zu texelFetch2D sowas wie texelSet2D?

Nein, du kannst Texturen nie gleichzeitig lesen und schreiben. Hier liegt nämlich der Grund für die hohe Geschwindigkeit der Grafikkarte im Vergleich zur CPU: Die GPU kann parallel auf hunderten Shaderunits arbeiten ohne das es Konflikte gibt.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Dez 05, 2011 21:30 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Ok das macht Sinn. Dann hab ich noch eine weitere Frage, wieso sorgt der Physikshader für volle CPU-Auslastung? Also wenn ich die Use-Zeile auskommentiere (also den Shader aus lasse) dann ist die CPU-Auslastung minimal. Bei aktiviertem Shader maximal. Sollte der CPU das nicht egal sein? Ich mein die Texturen und die ganzen Buffer sind doch im Grafikkarten-Speicher, was muss die CPU hier tun?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Dez 06, 2011 20:06 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Wahrscheinlich wartet die CPU schlicht und einfach auf die GPU ;)
=> Gib der GPU was zu tun, dann auf der CPU was anderes machen....erst dann SwapBuffers, Flush, FBO-Wechsel, etc.
=> Alternative: Nutze einen Render-Thread und einen Arbeits-Thread. Der Render-Thread kann dann schlafen während er auf die GPu wartet.

_________________
Yeah! :mrgreen:


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


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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.021s | 15 Queries | GZIP : On ]