Fallen JLI MVP
Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 13.10.2006, 22:46 Titel: Postprocessing - Bloom |
|
|
Ahoi, ich möchte euch mal mit dem Bloom Nachbearbeitungsfilter ein wenig vertraut machen, viele werden ihn kennen und sogar verfluchen (da er übertrieben eingesetzt nerven kann).
1. Einführung
Bloom beschreibt eine Situation in der Fototechnik in der bestimmte Fotozellen so stark belastet werden das sich ihre Helligkeit auf Nachbarzellen ausweitet. Dabei scheint das fertige Foto zu überstrahlen, helle Bereiche wirken also auf dunklere Nachbarbereiche und hellen diese auf. Alte Filme oder Serien weisen diese Eigenschaft auf, zB J.A.G wenn ein dunkler Raum mit einer Lichtquelle gezeigt wird.
Auch wird Bloom als gefaktes (simuliertes) HDRR (High dynamic range rendering) Bezeichnet.
2. Die simple Technik
Wie man das ganze innerhalb einer Grafikengine simuliert ist recht einfach, kann sich aber über viele verschiedene Themengebiete ausweiten.
Die simpelste Methode ist dabei das zu bloomende Bild in eine Textur zu kopieren, und einige male, nach links, rechts, oben und unten verschoben mit additiven Blending über das Orignalbild zu rendern. Die zu blendenden Bilder werden je nach Bloomstärke und Anzahl der Schichten durch eine simple Vertexfarbe abgeschwächt/moduliert. Das ganze läuft komplett ohne Shader ab, was diese Möglichkeit für rein FFP (Fixed function pipeline) basierte Engines nützlich macht.
Allerdings ist diese Methode zienmlich ineffektiv (viele Schichten sind nötig um ein relativ passablen Gesammteindruck zu hinterlassen, was je nach Bildschirmauflösung ziemlich viele Schichten werden kann)
3. Die andere Technik
Die bessere Version benötigt allerdings die Anwendung von Shadern ermöglicht es aber auch ohne die massive Anzahl an Schichten auszukommen sowie mehr Flexiblität.
Dabei geht beginnt man wie in der simplen Technik in Punkt 2 damit die zu bloomende Szene in eine Textur zu kopieren (oder gleich zu rendern, was effektiver sein kann, auch bei der simplen Technik!) und diese zu verkleinern, 25% der Orignalgrösse ist dabei ein recht passabler Wert.
Orignal:
25% grosse Textur:
Orignal:
[img]http://www.dragonfx.de/download/Images/Bloom/Orignal25Percent[/img]
Diese verkleinerte Version verwischt man nun einige male.
Dies kann ein GaussianBlur Shader wunderbar erledigen, hier ein kleines Beispiel für den Aufbau eines solchen Shaders, zu beachten wäre hier noch das es 2 Versionen dieses Shaders gibt, einmal um horizontal und einmal um vertikal zu bluren. Dies ermöglicht es uns die aktuellen Grafikkartenlimitierungen gut auszunutzen.
(GLSL Shader mit hardgecodeten Gaussianbblurwerten, für horizontales bluren)
CPP: | uniform sampler2D texture_2D;
uniform float ddx;
uniform float ddy;
void main(void)
{
//Initialisierungen
vec4 outp = vec4(0.0, 0.0, 0.0, 0.0);
// Texturen auslesen
// und vertikal bluren (gauss)
outp += 0.015625 * texture2D(texture_2D, gl_TexCoord[0].xy + vec2(ddx*-3.0, 0.0) );
outp += 0.09375 * texture2D(texture_2D, gl_TexCoord[0].xy + vec2(ddx*-2.0, 0.0) );
outp += 0.234375 * texture2D(texture_2D, gl_TexCoord[0].xy + vec2(ddx*-1.0, 0.0) );
outp += 0.3125 * texture2D(texture_2D, gl_TexCoord[0].xy + vec2(0.0, 0.0) );
outp += 0.234375 * texture2D(texture_2D, gl_TexCoord[0].xy + vec2(ddx*1.0, 0.0) );
outp += 0.09375 * texture2D(texture_2D, gl_TexCoord[0].xy + vec2(ddx*2.0, 0.0) );
outp += 0.015625 * texture2D(texture_2D, gl_TexCoord[0].xy + vec2(ddx*3.0, 0.0) );
gl_FragColor = outp;
}
|
Horizontal geblurt (das Beispiel ist etwas extrem normalerweise sieht man den Unterschied nicht so gravierend wenn man immer abwechselnd erst horizontal dann vertikal blurt):
Vollständig geblurt:
Nun wird die Textur noch gebloomt, beim Bloomprozess kann man viele Werte mit einfliessen lassen, die mitunter besten sind der Bias, um das Blooming absolut zu stärken/schwächen, die Helligkeit, sowie der Kontrast. Das gute ist, dass man alle 3 Werte im Shader als 3Dimensionale Vektoren darstellen kann, also für Rot, Grün Blau, so das man wiederum nur rote Bereiche hervorheben kann wenn man dies wünscht um die Atmosphäre des Bildes zu beeinflussen.
CPP: | uniform sampler2D texture_2D;
uniform vec4 Bias;
uniform vec4 Exponent;
uniform vec4 Brightness;
void main(void)
{
vec4 outp;
outp = texture2D(texture_2D, gl_TexCoord[0].xy );
outp += Bias;
outp = pow(outp, Exponent)*Brightness;
gl_FragColor = outp;
}
|
Gebloomte Textur:
Abschliessend wird nun die gebloomte Textur über die Orignal Szene gelegt, additives oder negativ multiplikatives Blending reichen dafür meist aus.
Fertiges Bild:
Nochmals zum Vergleich:
Ich hoffe dieses Tutorial war aussagekräftig und lehrsam.
Lob, Kritik, Kommentare sind gerne gesehen.
mfg Mark _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|