Deutsch Startseite English

Mon, 23 Oct 2017

Sitemap

Lite-C,3d Game Studio

Postprocessing Shader Tutorial Teil II:

::.erste Special-Effekte.::

Seite 3: Im ersten Teil dieser Tutorialserie über das Programmieren von Postprocessing Shadern in HLSL haben wir uns mit den Grundlagen solcher Effekte beschäftigt. Nun sollen Sie die Möglichkeiten kennen lernen, zahlreiche interessante Effekte für Ihre Spiele zu erstellen, unter anderem Schwarz/Weiß-Filter, Sepia und einfaches Bloom.
Das Tutorial richtet sich an Anfänger und geht von den Grundlagen des vorangegangenen Teils aus.

Das gesamte Tutorial zusammen mit Codebeispielen steht hier zum Download bereit.

Schwierigkeit:**

Material: lite-c, 3DGS A7 Commercial oder Professional

Zusatzmaterial: postprocessdat2.rar

Er will doch nur spielen | Negativbild |
Monochrome/Graustufen | Schwarzweiß |
Sepia | Bloom | Sepia-Bloom

6. Einfacher Bloom Shader:

Machen wir einen kleinen Exkurs! Ein in Computerspielen sehr häufig verwendeter Effekt ist Bloom. Bloom macht im Endeffekt nichts anderes, als helle Pixel noch heller erscheinen zu lassen. Es entsteht ein schöner Kontrast im Bild. Sie sind bereits in der Lage einen einfachen Bloomshader zu programmieren. Durch einfaches Quadrieren der Farbkomponenten eines Pixels kann man die hellen Pixel besonders von den dunklen abheben. Denn je kleiner eine Zahl unter 1 ist, desto kleiner ist ihr Quadrat. Also reicht es aus jede Farbkomponente zu quadrieren um eine Steigerung des Kontrastes zu bewirken. Da sich die hellen Farben weniger oder kaum beeinflussen lassen, dunklere aber hingegen deutlich schwächer werden.
HLSL bietet einem hierfür einen extra Befehl, ähnlich dem in lite-c:
pow(Basis,Exponent);

Also:
[...]
float4 Color;
Color=tex2D(mySampler,Tex.xy);//Pixelfarbe auslesen
Color.rgb=pow(Color.rgb,2.0f);//Kontrast erhöhen
[...]

Das Ergebnis sieht zu dunkel aus? Dann hellen Sie es doch mit einem Faktor auf.

[...]
Color.rgb=pow(Color.rgb,2)*2.0f;//Kontrast erhöhen und aufhellen
[...]

Postprocessing Shader Bloom

Die Ähnlichkeit zum Sepiashader im Testlevel ist übrigens zufällig und kommt nur durch die Farbe der verwendeten Lichtquelle zustande.
Der Nachteil dieser Methode ist, dass der Bloom typische 'Schein' der leuchtenden Flächen fehlt und bei sehr dunklen Flächen die Details verloren gehen.

Ein selektiver Bloomshader würde also schönere und natürlichere Ergebnisse liefern.
Um diesen Bloomeffekt noch besser zu machen, müsste man die hellen Bereiche finden und zusätzlich durch einen Blurfilter z.B. Box Blur oder Gaussian Blur laufen lassen. Anschließend müsste man das Ergebnis zur Ausgabe hinzumischen. Dann hätte man auch schöne Leuchteffekte und Übergänge zu weniger gut beleuchteten Teilen des Bildes. Dies ist jedoch Thema eines der nächsten Shadertutorials.
Aber nichtsdestotrotz können wir auch diesen Effekt einfach simulieren. Dazu speichern wir vor der pow-Operation die tatsächliche Pixelfarbe temporär ab und mischen sie danach vor der Ausgabe hinzu. Je größer der Exponent desto schärfer werden die Leuchtpunkte. Denn die besonders dunklen Pixel werden so zu schwach um die Ausgangsfarbe zu beeinflussen. Die hellen hingegen bleiben hell genug um die Ausgabepixel deutlich heller zu machen. Somit schaffen wir uns eine Art Maske, die die dunklen Stellen wegretuschiert. Wer mit Programmen wie Photoshop oder GIMP arbeitet, kennt sich aus.
Um die gelesene Pixelfarbe zu speichern erstellen wir einen lokalen Fließkommavektor namens tempColor. Da wir uns nicht um den Alphawert des Pixels kümmern müssen, weil wir ihn nicht ändern, kann der Vektor hier nur drei Komponenten haben, also vom Typ float3 statt float4 sein.
Diesem können wir einfach die Werte von Color zuweisen. Durch automatisches Typecasting werden r,g und b von tempColor die entsprechenden Werte von Color zugewiesen. Color.a wird praktischerweise außer Acht gelassen... wie gesagt, HLSL ist syntaktisch sehr viel komfortabler als C.

[...]
float4 Color;//Ausgabefarbe rgba(temporär)
float3 tempColor;//weiterer temporärer Vektor
Color=tex2D(mySampler,Tex.xy);//Pixelfarbe auslesen
tempColor=Color;//und zwischenspeichern
Color.rgb=pow(Color.rgb,2.0f);//Kontrast erhöhen, Maske
Color.rgb*=tempColor;//Maske anwenden und die Originalfarbe wieder dazu mischen
Color.rgb+=tempColor;
return Color;

[...]

Das Anwenden der Maske geschiet durch Multiplikation mit dem zwischengespeicherten Originalbild. Danach stellt Color die Leuchtfleckenfarbe dar. Durch Addition der Originalfarbe erhalten wir ein stellenweise aufgehelltes Bild mit allen urspünglichen Details.
Leider funktioniert das automatische Typecasting nicht in umgekehrte Richtung, also konnten wir einem größeren Vektor(Color) nicht direkt tempColor (float3) zuweisen. Logisch, schließlich ist diese Zuweisung nicht eindeutig. Denn r,g,b und a sind lediglich Kurzschreibweisen für die Stelle im Array (Vektor), [0],[1],[2] und [3]. Und man kann nicht sagen, was mit der 4. Stelle ([3]) bei der Zuweisung passieren soll. Dennoch wird sie angesprochen.
Deshalb war es nötig zu spezifizieren, welche Komponenten von Color für die Zuweisung verwendet werden sollen. 'Color.rgb' hat Color auf float3 Größe gebracht. So konnte die automatische Zuweisung vonstatten gehen.

Und um diesem Shader den letzten Schliff zu geben und die Übergänge von hellen zu dunklen Bereichen sanfter zu machen, können wir noch das Ergebnis der pow-Operation in ein Graustufenbild umwandeln. Unsere Maske war bisher ja auch farbig statt graustufig, wie sie sein sollte:

[...]
float4 Color;//Ausgabefarbe rgba(temporär)
float3 tempColor;//weiterer temporärer Vektor
Color=tex2D(mySampler,Tex.xy);//Pixelfarbe auslesen
tempColor=Color;//und zwischenspeichern
Color.rgb=pow(Color.rgb,2.0f);//Kontrast erhöhen, Maske
Color.rgb=(Color.r+Color.b+Color.g)/3.0f;//Maske monochrom machen Color.rgb*=tempColor;//Maske anwenden und die Originalfarbe wieder dazu mischen
Color.rgb+=tempColor;
return Color;

[...]

Postprocessing Shader Bloom

Die Stärke der Leuchtflecken kann übrigens durch Erhöhung des Kontrasts und Helligkeit der Maske erreicht werden. Hierzu bei Wunsch einfach einen Faktor nachstellen.

↑Top

7. Sepia-Bloom:

Zum Abschluss dieses Tutorials sollten wir noch das Kombinieren verschiedener Operationen in einem Pass durchgehen. Denn je nach Shadermodell hat man eine unterschiedliche Beschränkung an der Zahl der Operationen z.B. tex2D. Wir werden jetzt den Sepia Shader mit dem stark vereinfachten Bloomshader kombinieren.

/*Außerhalb der Pixelshader-Funktion! Am Anfang der fx Datei*/
const float strength=0.15f;

[...]
//an der bekannten Stelle im Pixelshader
float4 Color;
Color=tex2D(mySampler,Tex.xy);
Color.rgb=pow(Color.rgb,2.0f)*2.0f;//unsere Bloom Operation
Color.rgb=(Color.r+Color.g+Color.b)/3.0f;//danach Sepia Operationen
Color.r+=strength;//färbe in Sepia Töne
Color.b-=strength;
return Color;
[...]

Postprocessing Shader Bloom

Unsere Bloom-Shader Specialversion kann selbstverständlich auch auf dem selben Weg mit Sepia kombiniert werden. Die Monochrome-Operation muss da aber nicht doppelt vorkommen. Denn die Ergebnisse unterscheien sich nur geringfügig, jeder zusätzliche Befehl kostet aber Rechenleistung pro Pixel. Und ein Shader muss immer optimiert sein, damit der auch auf älterer Hardware läuft.

/*Außerhalb der Pixelshader-Funktion! Am Anfang der fx Datei*/
const float strength=0.15f;

[...]
//Pixelshader float4 PP_Shader (float2 Tex: TEXCOORD0):COLOR0
{
 float4 Color;//Ausgabefarbe rgba(temporär)
 float3 tempColor;//weiterer temporärer Vektor
 Color=tex2D(mySampler,Tex.xy);//Pixelfarbe auslesen
 Color.rgb=(Color.r+Color.b+Color.g)/3.0f;//monochrom machen
 tempColor=Color;//und zwischenspeichern
 Color.rgb=pow(Color.rgb,2.0f);//Kontrast erhöhen, Maske
 Color.rgb*=tempColor;//Maske anwenden und die Originalfarbe wieder dazu mischen
 Color.rgb+=tempColor;
 Color.r+=strength;//färbe in Sepia Töne
 Color.b-=strength;
 return Color;//schließlich Resultat zurückliefern
}
[...]

Postprocessing Shader Bloom

zurück | Anfang | ↑Top | Teil 3 coming soon...

Sitemap | Kontakt | Impressum

Copyright von kstudios.de © 2007-2017 bei Grygoriy Kulesko

News

28.05.2012
Something,
Something is coming...
#^+o

24.12.2010
Frohe Weihnachten,
Und wieder ist fast ein ganzes Jahr vergangen. Leider gab es 2010 nur wenige Aktualisierungen auf kstudios. Und auch wenn der veröffentlichte erste Prototyp von BlackBox zu den Highlights gehörte, waren viele versprochene Dinge nicht dabei. Wird sich das im nächstes Jahr ändern? Das hoffe ich aber versprechen kann ich nichts. kstudios wird in jedem Fall weitergeführt. Denn diese Seite ist wie ein Teil von mir.
Für alle, die glauben ein Informatik-Studium sei das einfachste, was man studieren kann: Informatik gehörte nicht umsonst ursprünglich ausschließlich zur Mathematik. Aber spannender und weltbezogener ist es allemal.
Was sind meine Vorsätze fürs Neue Jahr? Die Prüfungen zufriedenstellend bestehen, mich mal in Unity 3.1 einzuarbeiten (mal ehrlich, wenn man kostenlos ein derartiges Entwicklungstool hinterher geworfen bekommt, greift man doch zu), an BlackBox weiter zu basteln und mich in den neuen Blender einzuarbeiten. Ich denke das klingt ganz passabel.
Nun denn:
Ein frohes Fest und guten Rutsch ins Neue Jahr wünscht euch kstudios.de!

Neuestes Video


Quick terrain/ Schnelles Terrain Tutorial (no sound) from Grygoriy Kulesko on Vimeo.

Zufallsbild

aus dem Screenshot- und Artworkbereich

Vote

Derzeitig finden keine Votings statt.

Partner

Werden Sie Link-Partner von kstudios.de und an dieser Stelle erscheint ein Link zu Ihrer Website!
Kontakt