Aufgabenstellung

Gegenstand dieser Aufgabe ist die selbstständige Recherche, prototypische Implementierung, schriftliche Ausarbeitung und abschliessende Präsentation einer nicht-trivialen Multi-Pass Technik. Entwerfen sie für Ihren Effekt eine geeignete Beispielszene, mit der sie die Besonderheiten des Effekts gut demonstrieren können. Verwenden sie zur Ausgestaltung der Beispielszene auch einige der anderen Techniken die bisher in Vorlesung und Übungen bearbeitet wurden.

Bloom-Shader Beispielbild

Ich setzte mich in dieser Aufgabe mit dem Bloom-Effekt auseinander.

Controls









Erläuterungen zur Übung

Was ist der Bloom-Effekt?

Der Bloom-Effekt (auch light bloom oder glow) bezeichnet das Überstrahlen dunkler Bildbereiche in der Nähe sehr heller Lichtquellen (vgl. Abbildung 1) und simuliert bzw. repoduziert somit Bildartefakte, wie sie auch bei normalen Kameraaufnahmen entstehen können. Das liegt daran begründet, das eine Linse nie perfekt fokussieren kann, sodass zwei benachbarte Punkte, welche einen sehr großen Helligkeitsunterschied haben, leicht verschwimmen und das helle Licht über die dunklere Kante strahlt. Ein weiteres typisches Beispiel (vgl. Abbildung 2) für diesen Effekt ist ein dunkler Raum durch dessen Fenster helles Licht, wie etwa Sonnenschein, fällt. Die Fensterkanten verschwimmen dann scheinbar, da das Licht im Gegensatz zur Helligkeit im Raum sehr hell ist und das Auge diesen Helligkeitsunterschied schwer verarbeiten kann. Eingesetzt wird dieser Effekt in Computerspielen, Demos oder beim High dynamic range rendering.

Bloom-Shader BeispielbildAbbildung 1: Das Licht des hellen Hintergrundes verdeckt teils Bereiche im Vordergrund, wie die Wand oder die Figur. Bloom-Shader BeispielbildAbbildung 2

Erstellung des Bloom-Effekts

Die Erstellung des Bloom-Effekts lässt sich grob in drei Schritte aufteilen. Siehe dazu Abbildung 2. Zunächst wird die Szene normal gerendert (a). Anschließend wird auf dieses Ergebnis ein Blur-Effekt angewendet (b und c, jeweils horizontal und vertikal). In einem letzten Schritt wird das geblurrte Bild mit dem originalen, ungeblurrtem Eingangsbild geblendet (d) um so die eigentliche Überstrahlung zu simulieren.

Bloom-Shader Schematische Darstellung Abbildung 3: Rendering-Schritte des Bloom-Effekts.

Gaussian Blur Filter

Ein Blur Filter bezieht für die Farbwertberechnung des aktuell betrachteten Pixels, je nach Kernel, umliegende Pixel bzw. deren Farbe mit heran und bildet aus ihnen den Mittelwert. Bei einem Blur Filter über eine Gaussschen Glockenfunktion werden die Farben je nach Abstand zu dem aktuell berechneten Pixel zusätzlich anders gewichtet, was schlussendlich zu einem glatten, verwaschenem Verlauf führt (siehe Abbildung 4). Im Gegensatz zu ungewichteten Implementierungen wie etwas einem Box-Filter ist dies nicht trivial, sodass Box-Filter oft als Annäherung für Gauß-Filter dienen. Unabhängig davon lassen sich bei beiden Filtertypen die Berechnungen in die jeweilige x- und y-Dimension unabhängig voneinander betrachten, was die Gesamtberechnung deutlich beschleunigt. Zunächst wird in horizontaler Richtung geblurrt und danach in vertikaler. Dieser Sachverhalt wird in Abbildung 3 verdeutlicht.

Blur in horizontal und vertikaler Richtung. Abbildung 3: Schrittweises Blurring in horizontaler und vertikaler Richtung. Gauß-FunktionAbbildung 4: Gauß-Funktion als Kurve

Ein weiterer interessanter Punkt ist auch, das die BlurMap nicht die selbe Auflösung haben muss, wie das Render-Fenster. Das bedeutet auch, das bei kleineren Auflösungen der Kernel kleiner sein kann, was sich widerrum direkt positiv auf die Performance auswirkt. Und da die BlurMap in den meisten Fällen nicht sehr detailiert sein muss, bietet sich eine kleine Auflösung an. Es kann sogar passieren, das bei zu hohen Auflösungen, der Bloom-Effekt fast nicht mehr zur Geltung kommt, da unter Umständen der Kernel einfach zu klein ist. Als Workaround könnte man, um nicht die Kernelgröße stark erhöhen zu müssen, einen höheren BlurScale setzen. Das bedeutet das der Kernel gleich groß bleibt, jedoch werden bei jeder Iteration X Pixel übersprungen. Dadurch wird ein größerer Kernel simuliert, jedoch leidet die Bildqualität darunter. Schlussendlich sollte immer probiert werden, die Auflösung zu verringern, um diesen Problemen aus den Weg zu gehen. Die richtige Balance aus Auflösung und dem Blur-Ergebnis ist entscheidend.

BlurStrength: Die Gauß-Formel resultiert in einem intensiveren Farbwert, je näher aktuell betrachtete Pixel am Ursprung ist. Also je näher x sich 0 annähert (siehe Grauß-Formel im Wiki, x = positiver/negativer Abstand zum Ursprung). Wenn man nun das eingehende x mit einem Wert kleiner 1.0, reduziert das den Abfall im Blur-Verlauf und führt zu einem noch überbelichtetem Ergebnis.

Blending

Als Blending Mode zwischen dem finalen, geblurrten Bild und dem orginalen Eingangsbild kommt einfaches Additives Blending zum Einsatz, wobei die jeweiligen Farbwerte der entsprechenden Pixel der beiden Texturen einfach addiert werden. Dieser Blendmode ist sehr schnell und zeigt gute Ergebnisse.

Implementierung

Der Bloom-Effekt lässt sich mit Hilfe von Multi-Pass-Rendering simulieren. Als Multi-Pass-Rendering bezeichnet man eine Technik, bei der eine Szene nicht direkt in den Backbuffer gerendert wird, sondern zunächst in einen weiteren Speicher, unter OpenGL Frame Buffer Objects (FBO) genannt. Nun kann die Szene, als Textur an das FBO gebunden, nocheinmal in einem zweiten Render-Pass verändert werden, beispielsweise indem diese Textur in einem Fragment-Shader gesetzt wird (render to texture). Es sind beliebig vieler solcher Passes denkbar.

Zunächst werden drei FBO's und ein BackBuffer angelegt, indem am Ende das finale Bild gerendert wird. Das erste FBO colorBuffer beinhaltet das orginale, unveränderte Bild, mit dem am Schluss geblendet wird. Das FBO blurMap ist zunächst leer und hält später das geblurrte Bild. Es gibt nur ein FBO im dem das horizontale Blurring (horizontalBlur) ausgeführt wird, da das vertikale Blurring direkt in der blurMap stattfindet. Ist das Blurring beendet, wird der BackBuffer gebunden, in welchem die blurMap mit dem colorBuffer geblendet wird.

Rendern der Szene in den colorBuffer.

Das erste, horizontale Blurring wird erstellt, indem ein Quadrat, in der Größe des Render-Fensters, mit einem entsprechendem Blur-Fragment-Program gerendert wird. Als Eingangstextur wird hier die Textur des colorMap FBO übergeben. Der Viewport wird auf die entsprechende Auflösung der BlurMap gesetzt.

Das zweite, vertikale Blurring wird hinzugefügt, indem die bislang leere blurMap gebunden wird und in deren Textur wieder ein Quadrat mit einem Blur-Fragment-Program gerendert wird. Als Eingangstextur wird aber diesmal die bereits horizontal geblurrte Textur des horizontalBlur FBO gegeben. Die blurMap ist damit in beide Richtungen geblurrt und liefert ein fertiges Ergebnis zum Blenden.

Nun wird der BackBuffer gebunden indem erneut das Quadrat gerendert wird, jedoch diesmal mit einem Shader, der das Additive Blending vornimmt. Dieser Shader bekommt erwartungsgemäß die orginale, unveränderte Textur des colorBuffer FBO's und die gerade geblurrte Texture des blurMap FBO übergeben. Wichtig ist hierbei das Zurücksetzten des Viewports auf die entsprechende Fenstergröße.

Verwendete Ressourcen und Quellcode