DGL
https://delphigl.com/forum/

Blur Shader
https://delphigl.com/forum/viewtopic.php?f=20&t=10434
Seite 1 von 1

Autor:  Bergmann89 [ Do Mai 17, 2012 20:12 ]
Betreff des Beitrags:  Blur Shader

Hey,

ich hab den GausianBlur-Shader aus der Shader-Sammlung leicht überarbeitet um damit schön GlowEffekte zu bauen. Ich hab einfach den Durchschnitt über einen bestimmten Bereich gebildet un das Ergebnis noch bisl nachbearbeitet. Leider frisst das Ding, so wie es jetzt ist, haufen FPS. Ich weiß das es an den vielen Texturzugriffen liegt. Und ich weiß auch, das ich es so machen könnte wie der GausianBlur-Shader. Erst nur vertikal Bluren und dann das Ergebiss nochmal horizontal. Das find ich aber sehr umständlich, weil ich da noch ein extra FBO benötige. Aus diesem Grund wollte ich erstmal fragen, ob es vlt ne andere Möglichkeit gibt den Shader zu verbesser?!

Code:
  1. #version 120
  2.  
  3. uniform sampler2D uTexture;
  4. uniform vec2 uShift;
  5. uniform vec4 uMul;
  6. uniform vec4 uClamp;
  7.  
  8. const int radius = 11;
  9.  
  10. void main() {
  11.     vec2 texCoord = gl_TexCoord[0].xy - float(int(radius /2)) * uShift;
  12.     vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
  13.     for (int j = 0; j < gaussRadius; ++j){
  14.         texCoord.x += uShift.x;
  15.         texCoord.y = gl_TexCoord[0].y - float(int(radius /2)) * uShift.y;    
  16.         for (int i = 0; i < gaussRadius; ++i){
  17.             color += /*gaussFilter[i] */ texture2D(uTexture, texCoord) / float(radius * radius );
  18.             texCoord.y += uShift.y;
  19.         }
  20.     }
  21.     gl_FragColor = min(color * uMul, uClamp);
  22. }


MfG Bergmann.

Autor:  Schläfer [ Fr Mai 18, 2012 00:19 ]
Betreff des Beitrags:  Re: Blur Shader

Wenn der Filter der Textur auf linear eingestellt ist, kann man auch auf den Durchschnitt von 4 benachbarten Texeln zugreifen, indem man eine Koordinate genau zwischen den Viern wählt.
Außerdem kannst du die Division in Zeile 17 aus der Schleife rausziehen.

Eine andere Möglichkeit wäre vllt direkt Mipmaps zu verwenden bei denen ja der Durchschnitt mehrere Pixel gebildet wird. Allerdings würde das bestimmt ziemlich blockig aussehen. Ohne Wichtung der Texel hat das auch wenig mit Gaussian Blur zu tun.
Was vllt besser aussieht und auch weniger Texturelookups benötigt wäre, wenn du statt einem quadratischen Filter Kernel einen runden nimmst. Dann spart man sich die Texel an den Ecken.
Möglicherweise sollte man dann aber die Schleifen "entrollen", weil sonst die Berechnungen zum Bestimmen ob ein Texel im Kreis liegt, zu viel Performance fressen.

Wenn du auch weiterhin auf eine Gewichtung der einzelnen Texel verzichtest, kannst du auch für deine Schleife statt i und j direkt die Texturkoordinaten verwenden. Das würde vllt 2 Register sparen, auch wenn das wohl weniger das Problem ist.

Autor:  Bergmann89 [ Fr Mai 18, 2012 01:55 ]
Betreff des Beitrags:  Re: Blur Shader

Hey,

Danke für die Tipps, aber das sind ja alles nur so kleine Optimierungsaufgaben, ich glaub nicht das die so viel Frames raus holen. Normalerweißse komm ich auf 3500+, mit aktiviertem Shader sin es nur noch ca. 400.
Ich hab auch nochma bisl gegoogelt un ich glaub die einzige vernünftige Möglichkeit ist über den vertikalen und horizontalen Renderdurchgang. Auch wenn es mit den FBOs bisl umständlich ist. Ma gucken vlt kann ich das in irgend ner Subroutine hübsch verpacken...

MfG Bergmann.

Autor:  Thmfrnk [ Fr Mai 18, 2012 06:24 ]
Betreff des Beitrags:  Re: Blur Shader

das hab ich bis heute auch nicht verstanden... warum soll das was bringen wenn man das in 2 Durchläufe trennt? Berechnet werden muss es ja so oder so pro frame.. Daher sagt mein Verstand das es vielleicht sogar Langsamer sein müsste, wenn man Horizontal und Vertical einzeln berechnet. Kann mir das ein erklären?

Autor:  Coolcat [ Fr Mai 18, 2012 07:42 ]
Betreff des Beitrags:  Re: Blur Shader

Zitat:
das hab ich bis heute auch nicht verstanden... warum soll das was bringen wenn man das in 2 Durchläufe trennt?

Angenommen du machst einen Blur mit wie in diesem Fall 11x11 Pixel. Beim 2D Ansatz brauchst du also 11*11 = 121 Texturzugriffe. Wenn du das Trennst in Horizontal und Vertikal machst du nur noch 2*11 = 22 Texturzugriffe, musst dafür aber zweimal rendern. Je größer der Blur-Radius, desto mehr bringt das natürlich: Die Komplexitätsklasse des 2D-Ansatzes ist O(n²), während der 1D Ansatz nur O(n) braucht.

Zitat:
Wenn der Filter der Textur auf linear eingestellt ist, kann man auch auf den Durchschnitt von 4 benachbarten Texeln zugreifen, indem man eine Koordinate genau zwischen den Viern wählt.

Wenn man dabei nicht einfach nur die Mitte wählt, sondern der Verhältnis exakt berechnet, kann man sogar das gleiche Ergebnis erhalten wie beim normalen Ansatz.
http://rastergrid.com/blog/2010/09/effi ... -sampling/

Autor:  Coolcat [ Fr Mai 18, 2012 08:57 ]
Betreff des Beitrags:  Re: Blur Shader

Nachtrag:
Zitat:
Möglicherweise sollte man dann aber die Schleifen "entrollen", weil sonst die Berechnungen zum Bestimmen ob ein Texel im Kreis liegt, zu viel Performance fressen.

Das sollte der Shader-Compiler automatisch machen.

Zitat:
Ich hab einfach den Durchschnitt über einen bestimmten Bereich gebildet un das Ergebnis noch bisl nachbearbeitet.

Es gibt einen Grund warum man die einzelnen Texel mit einer Gauss-Funktion gewichtet. Diese minimiert die auftretenden Artefakte. Bei deinem Durchschnitt-Verfahren bekommst du leichte Ring-Artefakte um extreme Farbunterschiede im Bild.

Autor:  Bergmann89 [ Fr Mai 18, 2012 12:21 ]
Betreff des Beitrags:  Re: Blur Shader

Hey,
Coolcat hat geschrieben:
Es gibt einen Grund warum man die einzelnen Texel mit einer Gauss-Funktion gewichtet. Diese minimiert die auftretenden Artefakte. Bei deinem Durchschnitt-Verfahren bekommst du leichte Ring-Artefakte um extreme Farbunterschiede im Bild.
Ich weiß, aber ich finde, dass das bei einem Glow Effekt ein sehr schöner Nebeneffekt ist :)

MfG Bergmann

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/