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

Aktuelle Zeit: Sa Jun 08, 2024 12:35

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



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Gauss-Shader
BeitragVerfasst: Di Apr 15, 2008 15:29 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
hi,

dieses Mal kein Problem, sondern einfach nur einen Shadercode den ich posten möchte.
Vielleicht kann ihn sich jemand noch einmal durchsehen, dann könnte er nämlich ins wiki.
Es handelt sich um einen Gauß-Shader. Die Standardabweichung lässt sich mittels uniform übergeben und die Größe der Filtermatrix lässt sich im Shader einstellen. (Vielleicht gibt es ja auch hier eine Möglichkeit diese zu übergeben)
Des weiteren muss noch die Texturgröße via width und height übergeben werden.

Vertex-Shader:
Code:
  1. varying vec2 texCoord;
  2.  
  3. void main(void)
  4. {
  5.   // Transformation (Modelview und Projection)
  6.   gl_Position = ftransform();
  7.   // Texturkoordinaten
  8.   gl_TexCoord[0] = gl_MultiTexCoord0;;
  9. }

Fragment-Shader:
Code:
  1. uniform sampler2D colorMap; // Textur
  2. uniform float width;
  3. uniform float height;
  4. uniform float standardderivation;
  5.  
  6. const int kernelsize = 5;
  7. // Um an die benachbarten Pixel zu kommen
  8. const float step_w = 1.0/width;
  9. const float step_h = 1.0/height;
  10.  
  11. // Konstanten
  12. const float e  = 2.71828;
  13. const float pi = 3.14159;
  14.  
  15. // Gauß Matrix berechnen
  16. void CalculateGaussMatrix(out int Matrix[kernelsize*kernelsize])
  17. {
  18.   int c=0;
  19.   float pconst = 1.0/(sqrt(2.0*pi)*standardderivation);
  20.   float variance = standardderivation*standardderivation;
  21.   for (float i=0.0; i<float(kernelsize); i=i+1.0)
  22.   {
  23.     for (float j=0.0; j<float(kernelsize); j=j+1.0)
  24.     {
  25.       Matrix[c] = int(ceil(pconst * pow(e, -((i*i) + (j*j)) / (2.0 * variance)) * 100.0));
  26.       c++;
  27.     }
  28.   }
  29. }
  30.  
  31. // Filter anwenden
  32. void main(void)
  33. {  
  34.   int c=0;
  35.   int sum=0;
  36.   int M[kernelsize*kernelsize];
  37.   vec2 offset;
  38.   vec4 ColorResult = vec4(0.0, 0.0, 0.0, 0.0);
  39.   CalculateGaussMatrix(M);
  40.   for (float i=0.0; i<float(kernelsize); i=i+1.0)
  41.   {
  42.     for (float j=0.0; j<float(kernelsize); j=j+1.0)
  43.     {
  44.       sum += M[c];
  45.       offset = vec2((-i + float(kernelsize)/2.0) * step_w, (-j + float(kernelsize)/2.0) * step_h);
  46.       ColorResult += texture2D(colorMap, vec2(gl_TexCoord[0]) + offset) * float(M[c]);
  47.       c++;
  48.     }
  49.   }  
  50.   ColorResult /= float(sum);
  51.   gl_FragColor = ColorResult;
  52. }

Sicherlich lässt sich da noch einiges optimieren, zumal die Gauß-Matrix hier ständig neu berechnet werden muss, vielleicht ließe sich dies auch irgendwie auf das Programm auslagern.

mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 15, 2008 15:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Hast du das ding mal ausprobiert, so wegen performance und so?
So wie das aussieht, wird das seeehr langsam sein, weil er jeden Frame die Matrix neu berechnet, noch dazu haben wir hier kernelsize² Texturzugriffe, was auch nicht gerade harmlos ist...

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 networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 15, 2008 16:56 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Ja, sonderlich schnell ist es wirklich nicht und wirklich großflächige Blurs sind damit nicht möglich.
Ich habe irgendwo gelesen, dass man das Ganze allerdings stark optimieren kann, indem man erst Horizontal und dann Vertikal (oder umgekehrt) blurrt.
Wie stelle ich das an ?

(die Gauß Matrix werde ich dann wohl entweder statisch machen oder mir etwas anderes überlegen ^^)

mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 15, 2008 18:06 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Nun, um erst horizontal und dann vertikal zu blurren, brauchst du entweder zwei Shader oder einen Shader mit einer If (nicht sehr gut auf älteren Karten), auf jeden Fall aber brauchst du zwei Renderpasses. So in der art:
Code:
  1.  
  2. 1. Szene rendern
  3. 2. Framebuffer in eine Textur schreiben
  4. 3. Framebuffer leeren
  5. 4. Die Textur auf den ganzen Bildschirm mit dem 1. Shader rendern
  6. 5. Die Textur mit dem aktuellen Framebufferinhalt überschreiben
  7. 6. Die Textur erneut auf den ganzen Bildschirm rendern, diesmal mit dem 2. Shader


Welcher der beiden Shader jetzt horizontal und welcher vertikal blurrt, ist deine Entscheidung. Der Blur läuft ansonsten ganz normal ab, nur dass du anstatt kernelsize² "nur" kernelsize Texturzugriffe hast und der Shader auch auf älteren karten, wo die Schleife entrollt werden müsste, noch eine Chance hat durch den Maximal Instruction-Filter durchzukommen :wink:. Du musst halt anstatt einen Kreisförmigen Blur anzustellen nur nach oben und unten oder zur Seite gehen.

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 networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 16, 2008 12:26 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
hi, das scheint in der Praxis ganz gut zu funktionieren. Ich nutze allerdings momentan eine Textur in die ich rendere. Lande aber gerade einmal bei 30fps, fast unabhängig von der Texturgröße, hat also vielleicht nichts mit dem Shader zu tun.

mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 16, 2008 17:49 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Es könnte daran liegen, dass dein Shader in Softwaremodus gehauen wird, wegen den vielen Texturzugriffen und instruktionen.

Und wenn du eine Textur nutzt, in die du renderst sehe ich gerade kein Problem, eine Horizontal/Vertikal Lösung zu verwenden oder reden wir da gerade aneinander vorbei?

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 networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 16, 2008 18:39 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
nein, genauso mache ich es ja momentan ;)
die shader sind nicht sehr lang, wie kann ich überprüfen ob der im SW modus läuft ?

Das hier ist der horizontale, der vertikale sieht genauso aus:
Code:
  1. uniform sampler2D colorMap; // Textur
  2. uniform float width;
  3. uniform float height;
  4.  
  5. // Um an die benachbarten Pixel zu kommen
  6. const float step_w = 1.0/width;
  7. const float step_h = 1.0/height;
  8.  
  9. // Konstanten
  10. const float e  = 2.71828;
  11. const float pi = 3.14159;
  12.  
  13. // Filter anwenden
  14. void main(void)
  15. {  
  16.   int c=0;
  17.   int sum=0;
  18.   int M[49];
  19.   M[0]=0;M[1]=1;M[2]=1;[3]=1;M[4]=1;M[5]=1;M[6]=1;M[7]=1;M[8]=1;
  20.   M[9]=2;M[10]=2;M[11]=2;M[12]=2;M[13]=2;M[14]=2;M[15]=3;M[16]=3;
  21.   M[17]=3;M[18]=3;M[19]=3;M[20]=3;M[21]=3;M[22]=3;M[23]=3;M[24]=3;
  22.   M[25]=3;M[26]=3;M[27]=3;M[28]=3;M[29]=3;M[30]=3;M[31]=3;M[32]=3;
  23.   M[33]=3;M[34]=2;M[35]=2;M[36]=2;M[37]=2;M[38]=2;M[39]=2;M[40]=1;
  24.   M[41]=1;M[42]=1;M[43]=1;M[44]=1;M[45]=1;M[46]=1;M[47]=1;M[48]=0;
  25.  
  26.   vec2 offset;
  27.   vec4 ColorResult = vec4(0.0, 0.0, 0.0, 0.0);
  28.   for (float i=0.0; i<49.0; i=i+1.0)
  29.   {
  30.     sum += M[c];
  31.     offset = vec2((-i + 49.0/2.0) * step_w, 0);
  32.     ColorResult += texture2D(colorMap, vec2(gl_TexCoord[0]) + offset) * float(M[c]);
  33.     c++;
  34.   }  
  35.   ColorResult /= float(sum);
  36.   gl_FragColor = ColorResult;
  37. }

height und step_h kann ich in diesen fall ja entfernen ;)

mfg


// Edit Lossy: Matrix umgebrochen. Geht von der Seitenbreite ja nicht mal auf einem 24"er.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 24, 2008 07:12 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
Ich glaube garnicht, das wurde doch schon öfters gefragt, oder?
Auf jeden Fall dürfte es in der Performance doch was gebracht haben, dass du nicht in jedem Durchlauf die Gauß-Matrix berechnest. Das war sicher mit der größte Flaschenhals

_________________
__________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Foren-Übersicht » Programmierung » Shader


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 8 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 14 Queries | GZIP : On ]