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

Aktuelle Zeit: Do Jul 10, 2025 08:54

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



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: glConvolution Filter & Blur
BeitragVerfasst: Mi Okt 03, 2007 17:24 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
Hallo,
ich habe ein Problem mit dem glConvolution Filter.
Ich möchte damit eine Textur blurren, die ich per Laufzeit via RenderToTexture erstellt habe.

Als Faltkern benutze ich eine 7x7 Gauss-Matrix, die als 2-dim Array im Speicher liegt:
Code:
  1. mat : Array [0..6, 0..6] of Single =
  2.   ((0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067),
  3.    (0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292),
  4.    (0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117),
  5.    (0.00038771, 0.01330373, 0.11098164, 0.22508352, 0.11098164, 0.01330373, 0.00038771),
  6.    (0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117),
  7.    (0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292),
  8.    (0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067));


Jetzt wende ich den Conv. Filter an:
Code:
  1.   // Render-Code:
  2.  
  3.   glClearColor(0.0, 0.0, 0.0, 0.0);
  4.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  5.   glViewPort(0, 0, 128, 128);  // Viewport-Größe an die Textur anpassen
  6.   RenderScene;  // Rendert eine Test-Scene
  7.  
  8.   glEnable(GL_CONVOLUTION_2D);
  9.   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 7, 7, GL_RGBA, GL_FLOAT, @mat[0, 0]);
  10.   tex.Bind;
  11.   glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 128, 128, 0);
  12.   glDisable(GL_CONVOLUTION_2D);
  13.  
  14.   glClearColor(0.5, 0.5, 0.5, 0.0);
  15.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  16.   glViewPort(0, 0, 640, 480);  // Normale Fenster-Größe
  17.   RenderScene;
  18.   RenderOrthoTexture;  // Rendert meine erstellte Textur (tex) im Ortho-Modus
  19.                // mittels Blending drüber.


Irgendwas habe ich wohl falsch gemacht, denn
erstens : meine Framerate sinkt drastisch ab (>4000 auf ~39)
zweitens : die Textur scheint irgendwie verschoben zu sein (siehe attachement)

Was ist denn hier schief gelaufen?
Vielen Dank im voraus!


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
http://texelviews.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 03, 2007 18:01 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Muss gestehen mit glConvolutionFilter2D habe ich bisher noch nichts gemacht. Allerdings im Wiki steht nicht, dass glCopyTexImage2D unterstützt wird.

Allerdings die drastische Geschwindigkeitsverschlechterung lässt vermuten, dass es in Software abläuft. Evtl solltest du auch mal testen wie groß der Filter überhaupt sein darf. glGetInteger mit GL_MAX_CONVOLUTION_WIDTH und GL_MAX_CONVOLUTION_HEIGHT. Ansonsten wüsste ich nicht was es sein könnte, da der Convolution-Filter ja eigentlich keine sonderlichen Einstellungen bietet.

Ansonsten wird ja generell so etwas über Shader gelöst. Und ich vermute einfach mal, dass es einen Grund hat warum man für so etwas keinen Convolution Filter benutzt sondern Shader.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 03, 2007 18:41 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 02, 2002 15:41
Beiträge: 867
Wohnort: nahe Stuttgart
Dazu sind eigentlich nicht mal Shader notwendig. Man kann stattdessen auch in eine etwas kleinere Textur per RTT rendern, diese dann 8 mal in vertikaler Ausdehnung mit Gaußfkt. zeichnen, das wiederum 8 mal in horizontaler Ausdehnung wieder RTT und die letztendlich erzeugte Textur einfach drüberblenden.

So hab ich es hier schonmal wo gelesen und es auch so in Matrionx gemacht.

MfG


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 03, 2007 19:28 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 27, 2005 12:44
Beiträge: 393
Wohnort: Berlin
Programmiersprache: Java, C++, Groovy
Hallo MatReno,

du könntest es auch mit der Funktion glSeparableFilter2D probieren, da sich deine Matrix idealerweise als dyadisches Produkt zerlegen lässt.
Als col und row übergibst du dann einfach jeweils den Vektor (0.0008185352772, 0.0280415762, 0.2339264201, 0.4744296787, 0.2339264201, 0.0280415762, 0.0008185352772).

Viele Grüße
dj3hut1


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 03, 2007 21:42 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
Danke für die Antworten!

@Lossy:
Kann schon sein, dass er in den Software-Modus zurückfällt... Das würde die Geschwindigkeitseinbußen erklären.
Das glCopyTexImage2D nicht unterstützt wird wusste ich nicht, klar stand davon nix explizit im Wiki, aber ich dachte, dass es trotzdem funktionieren müsste, da ich es so schon mal bei meiner Suche im Forum gefunden hatte: http://www.delphigl.com/forum/viewtopic.php?t=5601&highlight=blur+textur

@WhiteHunter:
Das hört sich interessant an, und ich weiß zumindest dass es funktioniert, das Ergebnis habe ich ja in deinem Spiel gesehen ;)
Jedoch ist mir etwas unklar, wie du das mit der Gauß-Funktion und dem mehr-mal zeichnen meinst... Könntest du mir da vielleicht noch etwas weiterhelfen?

@dj3hut1:
Danke für den Tip. Werde es probieren, aber nachdem was Lossy anmerkte mache ich mir nicht gerade viel Hoffnung...
Denn wenn RTT generell (oder zumindest wie ich es benutze) von glConvolutionFilter2D nicht unterstützt wird, denke ich bringt das auch nicht viel... Aber wie gesagt, probieren tue ich's ;)

_________________
http://texelviews.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 03, 2007 23:48 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 02, 2002 15:41
Beiträge: 867
Wohnort: nahe Stuttgart
MatReno hat geschrieben:
@WhiteHunter:
Das hört sich interessant an, und ich weiß zumindest dass es funktioniert, das Ergebnis habe ich ja in deinem Spiel gesehen ;)
Jedoch ist mir etwas unklar, wie du das mit der Gauß-Funktion und dem mehr-mal zeichnen meinst... Könntest du mir da vielleicht noch etwas weiterhelfen?


Code sagt ja bekanntlich mehr als tausend Worte, auch wenn er nicht ganz so schön ist:

Code:
  1. const
  2.   GAUSSIAN_BLUR: array[-8..+8] of Single = (0.0323913089903, 0.039893901959,
  3.     0.0477882137422, 0.0556764252591, 0.0630896551547, 0.0695314407149,
  4.     0.0745316210611, 0.077702710876, 0.0787894444856, 0.077702710876, 0.0745316210611,
  5.     0.0695314407149, 0.0630896551547, 0.0556764252591, 0.0477882137422, 0.039893901959,
  6.     0.0323913089903);
  7. // unsere Gaußfkt. im Voraus berechnet
  8.  
  9. procedure TMatrionx.Render;
  10. ...
  11. ...
  12.     if Blooming then
  13.     begin
  14.       glViewport(0, 0, 256, 256);
  15.  
  16. // passende benötigte Statechanges / Perspective / Clear
  17. ...
  18. // Szene für Bloom zeichnen
  19.         Draw(rpBloom);  
  20.  
  21. // in Textur übernehmen
  22.         Tex.Bind('bloom');
  23.         glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 256, 256, 0);
  24.        
  25. // passende benötigte Statechanges / Perspective / Clear
  26. // hier einmal ausführlich:
  27.         glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  28.         glClearColor(0, 0, 0, 1);
  29.        
  30.         glMatrixMode(GL_PROJECTION);
  31.           glLoadIdentity;
  32.           glOrtho(0, 1, 0, 1, 0, 1);
  33.         glMatrixMode(GL_MODELVIEW);
  34.           glLoadIdentity;
  35.  
  36. // DepthTest & Blending passend setzen
  37.           glDisable(GL_DEPTH_TEST);
  38.           glEnable(GL_BLEND);
  39.           glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  40.  
  41. // jetzt die Textur jeweils um i Pixel auf der X-Achse verschoben zeichnen        
  42.         Tex.Bind('bloom');
  43.         for i := -8 to +8 do
  44.         begin
  45.           glColor4f(1, 1, 1, GAUSSIAN_BLUR[i]);
  46.           Draw2DQuad((i/256), 0, 1+(i/256), 1, 0);
  47.         end;
  48.        
  49. // wieder in Textur übernehmen, dann gleiches Spielchen nochmal
  50.         glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 256, 256, 0);
  51. // wieder passende Statechanges / Perspective / Clear
  52. ...
  53.  
  54. // jetzt die vertikal geblurrte Textur jeweils um i Pixel auf der Y-Achse verschoben zeichnen
  55.         for i := -8 to +8 do
  56.         begin
  57.           glColor4f(1, 1, 1, GAUSSIAN_BLUR[i]);
  58.           Draw2DQuad(0, (i/256), 1, 1+(i/256), 0);
  59.         end;
  60.        
  61. // in die Textur
  62.         Tex.Bind('bloom');
  63.         glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 256, 256, 0);
  64.  
  65. // alten Viewport wiederherstellen
  66.       glViewport(0, 0, MForm.ClientWidth, MForm.ClientHeight);
  67.     end;
  68.   end;
  69.  
  70. // passende Statechanges / Perspective / Clear
  71. // und in jedem Fall die normale Szene zeichnen
  72.   Draw(rpDraw);
  73.  

In Draw muss man dann im normalen Renderpass die erzeugte Textur einfach nur noch drüberblenden.

Hier findet sich das nacheinander blurren auch nochmals erklärt:
http://www.gamasutra.com/features/20040 ... es_pfv.htm

MfG


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glConvolution Filter & Blur
BeitragVerfasst: Do Okt 04, 2007 14:26 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
MatReno hat geschrieben:
Irgendwas habe ich wohl falsch gemacht, denn
erstens : meine Framerate sinkt drastisch ab (>4000 auf ~39)


Ich wollte auch mal meine Glow-Methode auf ConvolutionFilter umstellen, das Ergebnis war ähnlich. ConvolutionFilter eignet sich eigentlich fast garnicht für solche aktionen. Er ist relativ lahm. Sinnvoller ist da schon die Methode von WhiteHunter, die Textur also mit Alpha und ggf. Additivem Blending drüberlegen, jeweils entsprechend verschoben. Damit kann man auch schon nen ganz Ordentlichen Effekt mit passabler Leistung hinbekommen.

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: Fr Okt 05, 2007 08:24 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
Ich hab es erstmal mit dem glSeparableFilter2D probiert, aber ohne Erfolg. Irgendwie hab ich dabei eine DivisionDurchNull-Exception bekommen, was wahrscheinlich auch darauf schließen lässt, dass ich im Software-Modus war...

Dann der Versuch nach dem Rezept von WhiteHunter und siehe da, es klappt! :P
Musste es noch ein wenig umbauesn, aber die Idee funktioniert. Man hätte sogar selbst drauf kommen können. :wink:
Jedoch ist mir 8 faches blurren horizontal und vertikal etwas zu viel... Ich würde lieber 6-faches verwenden.
Doch dazu kann ich ja nicht die Werte von WhiteHunter benutzen, da es ja zusammen 1 Ergeben muss...
Ich muss also die Gauß-Funktion in 13 gleichgroße (auf der X-Achse) Stücke zerlegen (Mitte, 6 links, 6 rechts), und davon jeweils die Fläche berechnen. Das würde ich dann mit der Stammfunktion machen... -> viel Arbeit.
Gibt es noch eine andere Möglichkeit, die mir das ersparen würde (...Ich hoff doch mal...)?

Vielen Dank!

_________________
http://texelviews.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 05, 2007 11:38 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 02, 2002 15:41
Beiträge: 867
Wohnort: nahe Stuttgart
Ich erkläre mal, wie ich mir damals den Weg zurechtgeschustert habe...

Entscheide dich einfach für das Verhältnis das hellster und dunkelster Punkt zueinander haben sollen. zB. V = 1:10 = 0,1.
Sei f(x) = ( 1/sqrt(2*pi) ) * e^(-0.5x²) die Standardnormalverteilung, dann gilt:
f(a)/f(0) = V
Nach Umformen und Einsetzen lässt sich dann sagen:
a = sqrt(-2 ln(V))
Logischerweise wird der Term nur bei V <= 1 in R lösbar.

Betrachte jetzt einfach f(x) auf dem Intervall [-a;+a] sprich wenn du ein Array[-n..+n] willst, berechne die Werte f(a/n), f(2a/n), f(3a/n) ... bis f(na/n) = f(a)
Diese setzt du in Array[1..+n] ein. Array[0] ist f(0) und Array[-1..-n] ist f(-a/n) = f(a/n) ... bis f(-a) = f(a)

Dann teilst du jedes Arrayelement durch die Summe aller Arrayelemente.
So hast du dein gewünschtes Helligkeitsverhältnisarray quasi normiert, denn jetzt ergeben alle Elemente zusammen 1.

Inwieweit das mathematisch richtig oder doch vollkommen Quatsch ist, kann ich nicht beurteilen. Aber zumindest für kleine f(a) funktioniert das Verfahren recht gut.

MfG


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 05, 2007 20:24 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
Danke für die Erklärung!
Werde mir mal ein paar schöne Werte zusammenrechnen :wink:

Gruß
MatReno

_________________
http://texelviews.delphigl.com


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 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.009s | 16 Queries | GZIP : On ]