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:
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glViewPort(0,0,640,480);// Normale Fenster-Größe
RenderScene;
RenderOrthoTexture;// Rendert meine erstellte Textur (tex) im Ortho-Modus
// 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.
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.
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.
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).
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
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:
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 network • my 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
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! Musste es noch ein wenig umbauesn, aber die Idee funktioniert. Man hätte sogar selbst drauf kommen können. 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...)?
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.
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.