OpenGL Tutorial (Version 3.3) – Post Processing und Spezialeffekte (Download)

Das aktuelle OpenGL-Programmbeispiel ist der Startschuss zu einem zweiteiligen Post-Processing-Update unseres „Planet mit Nebel“-Demoprogramms. Ein Kritikpunkt an der bisherigen Darstellung ist sicherlich der recht blass wirkende Nebel. Auch sind noch keinerlei Spezialeffekte implementiert, wie beispielsweise Flimmern und Unschärfe innerhalb des Nebels. Dies werden wir nun alles nachholen. Im zweiten Teil werden wir uns dann um eine Verbesserung der Performance bemühen – durch die Verwendung von multiplen Render Targets (MRT) im Zuge des Post Processings.

Im Unterschied zum vorangegangenen Demoprogramm rendern wir die Szene nun in zwei Durchgängen:

Durchgang 1: Hintergrund + Planet (alle opaquen Objekte)
Durchgang 2: (alle transparenten Objekte) Nebelwolken unter Berücksichtigung des Tiefenabbilds von Render-Durchgang 1.

In beiden Durchgängen wird ein separates Post Processing durchgeführt. Grundlage ist in beiden Fällen die Helligkeit aus Render-Durchgang 2, weil hier die Helligkeitsschwankungen am stärksten sind (Blitze, zu einem späteren Zeitpunkte auch Feuer, Explosionen, usw.).
Für die Realisierung der Spezialeffekte werden die Nebelwolken zusätzlich in eine zweite Screen-Textur mit deutlich geringerer Auflösung gerendert, welche dann nach dem ersten Render-Durchgang im CombineScreenTextures-Shader mit der primären Screen-Textur kombiniert wird. Nachdem die neuen Spezialeffekte generiert worden sind, werden wie gehabt die Nebelberechnungen sowie die weiteren Post Processing Schritte durchgeführt. Schauen wir uns einmal an, wie genau die Spezialeffekte im Fragment Shader (CombineScreenTextures.frag) realisiert werden:

vec4 SecondaryScreenCol = texture(SecondaryScreenTexture,
                                  gs_TexCoord[0].st);

float intensity = SecondaryScreenCol.r + SecondaryScreenCol.g +
                  SecondaryScreenCol.b;

// Vor dem Betrachter befindet sich keine Nebelwolke:
if(intensity < 0.05)
    gs_FragColor = texture(PrimaryScreenTexture, gs_TexCoord[0].st);

// Vor dem Betrachter befindet sich eine Nebelwolke, Spezialeffekte
// berechnen (Flimmern und Unschärfe):
else
{
   // Unschärfeeffekt kommt durch das Zweifach-Sampling zustande.

   // Parameter für die Berechnung des Flimmereffekts:
   // CombinationValues.w := aktuelle Zeit
   // CombinationValues.z := Wellenzahl
   // CombinationValues.x, CombinationValues.y := Amplitude
   // Je stärker die Texturkoordinaten modifiziert werden, um so stärker
   // der Flimmereffekt!

   vec2 ModifiedTexCoord1 = gs_TexCoord[0].st + intensity*
        vec2(sin(CombinationValues.w+CombinationValues.z*gs_TexCoord[0].x)*
             CombinationValues.x,
             sin(CombinationValues.w+CombinationValues.z*gs_TexCoord[0].y)*
             CombinationValues.y);

   vec2 ModifiedTexCoord2 = ModifiedTexCoord1 + vec2(0.0015, 0.0015);

   gs_FragColor = 0.5*(texture(PrimaryScreenTexture, ModifiedTexCoord1)+
                       texture(PrimaryScreenTexture, ModifiedTexCoord2));
}


Alle Parameter für die Berechnung des Post Processings sowie der Spezialeffekte finden sie wie gewohnt in der Datei ResolutionAndRendering.txt.

Hinweis:
Für die Ausführung dieses Programmbeispiels muss der Treiber Ihrer Grafikkarte die OpenGL Version 3.3 unterstützen.

Visual C++ 2010: DemoWithOpenGL2010_Tut17