Entwicklertagebuch
Post Effekte in ANNO 1404

 

Was sind Postproduction Effekte?

In Film und Fernsehen werden schon seit langem Posteffekte (engl. postproduction-effects) eingesetzt. Wie die Bezeichnung vermuten lässt, werden die Effekte „nach der Produktion“, d.h. nachdem der Film fertig ist, über das gesamte Bild gelegt. Häufig eingesetzte Effekte sind z.B. monochrom- oder sepia-farbige Rückblenden. Auch kommen Verzerrungen oder verschwommene Bilder zum Einsatz, um Benommenheit oder Alkoholeinfluss zu vermitteln. Um eine kalte, postapokalyptische Welt anschaulicher zu machen, werden die Bilder entsättigt, wodurch sie trist und grau wirken. Hingegen erscheinen Szenen durch Sättigung und Weichzeichnen (Bloomfilter) märchenhafter. Auch lassen sich im Film unerwünschte Objekte aus Szenen entfernen oder z.B. Laserschwerter nachträglich einfügen.

In Videospielen müssen viele natürliche Effekte nachgestellt werden, da sie in einer sterilen Polygonumgebung nicht entstehen. Hier werden Effekte für Hitzeflimmern, Glühen, Bewegungs- und Tiefenunschärfe nachträglich hinzugefügt.


Posteffekte in Anno1404

Da in Anno1404 unterschiedlichste Posteffekte wie HDR-Tonemapping (high dynamic range), Bloom, Hitzeflimmern, Glühen und Tiefenunschärfe zum Einsatz kommen, ist ein flexibles System nötig, welches leicht erweiterbar und bedienbar ist. Hierfür wurde der Posteffect-Manager zur nachträglichen Bearbeitung von Szenenbildern entwickelt. Mit ihm ist die Erstellung von Posteffekten recht einfach, da fast alle nötigen Einstellungen on-the-fly in einer Script-Datei vorgenommen werden können und das Ergebnis direkt auf dem Bildschirm zu sehen ist.
Zu den Aufgaben des Posteffect-Managers gehören u.A. die Verwaltung von Rendertargets, also Texturen, auf die gezeichnet wird, und die Vorbereitung der Rendertargets für die Posteffekte. Weiterhin sorgt er dafür, dass Sub-Posteffekte zu einem Posteffekt zusammengefügt werden. Es lassen sich beliebig viele Posteffekte in beliebiger Reihenfolge aneinander hängen und zu dem endgültigen Bild abmischen.

Wie zur Simulation der Refraktion und Reflektion benötigen auch die dynamischen Wellen eine Textur, die Dynamic-Wave-Map. Anstatt, wie normalerweise üblich, dort Farben von Objekten zu speichern, verwendet die Dynamic-Wave-Map ihre Farbkanäle um Informationen über die dynamischen Wellen zu speichern. Dazu zählt z.B. die Höhe der Welle und wie viel Schaum die Welle erzeugt. Aus diesem Grund werden in die Dynamic-Wave-Map nur spezielle Effekte gezeichnet und keine Objekte. Nach dem Erstellen der Dynamic-Wave-Map wird der Wellengang des Meeres mit den dynamischen Wellen kombiniert und innerhalb einer Displacement-Map gespeichert. Während dieser Berechung kann der Wellengang verändert werden, unter anderem die Höhe der Wellen oder deren Geschwindigkeit. Dadurch kann die Engine von ruhiger See (flache langsame Wellen) bis hin zur rauen See (mit spitzen und sehr hohen Wellen) jeden Meereszustand darstellen und zur Laufzeit ändern.



Vorbereitung der Rendertargets

Zunächst wird die komplette Anno-Szene mit Terrain, Wasser, Objekten sowie Partikeleffekten regulär in den Backbuffer gezeichnet, das Rendertarget, welches das Spiel auf dem Bildschirm anzeigt. Um Heat- und Glow-Posteffekte zu ermöglichen, werden jeweils ein Heat- und ein Glow-Rendertarget angelegt. Danach werden alle Objekte, die glühen sollen, wie z.B. Feuereffekte, in das Glow-Rendertarget gerendert. Objekte, die ein Hitzeflimmern erzeugen, werden in einem weiteren Vorgang in das Heat-Rendertarget geschrieben.

Im Folgenden ein Beispiel, welches ein Glow-Rendertarget definiert:

RENDERTARGET RT_GLOW
{
DEPTH_REQUIRED
DIMENSION -2 -2
}


Hier wird ein Rendertarget mit dem Namen „RT_GLOW“ angelegt, welches einen Depthbuffer als Rendertarget benötigt, um für Glow-Partikel einen z-Test durchführen zu können. Das Rendertarget erhält die halbe Bildschirmauflösung. Positive Zahlen bei der Dimension geben exakte Pixelauflösung an, negative Zahlen geben den negativen Divisor zum Berechnen der gewünschten Auflösung abhängig von der Bildschirmauflösung an.

Ein weiteres wichtiges Rendertarget ist der Depthbuffer, der die Entfernung der Objekte bzw. Pixel zum Betrachter enthält. Er wurde ursprünglich entwickelt, um im Depth-Test zu verhindern, dass im Hintergrund liegende Objekte die im Vordergrund liegenden überzeichnen. Der manuelle Zugriff auf den Depthbuffer ist für viele moderne Effekte wie Softparticles[1], volumetrischer Rauch/Nebel oder für Per-Pixel-Tiefenunschärfe notwendig. Unter DirectX10 ohne Multisampling (Antialiasing) kann man den Depthbuffer mit einer entsprechenden Einstellung anlegen und im Pixelshader auslesen.
Da bei aktiviertem Multisampling DirectX10 keinen Zugriff auf den Depthbuffer mit Multisampling erlaubt, muss eine gleichgroße Textur für die Tiefeninformationen anlegt werden. Man kann z.B. einen Depth-Renderpass vor dem regulären Rendering der kompletten Szene durchführen, um die Tiefeninformation in das Depth-Rendertarget zu schreiben. In Anno1404 werden MRTs (multiple render targets) eingesetzt. Während des regulären Renderings wird parallel zu der Farbinformation, die auf den Backbuffer gezeichnet wird, die Tiefeninformation in das Depth-Rendertarget unabhängig vom Depthbuffer geschrieben. Da dies ein Multisampling-Rendertarget sein muss und DirectX10 den direkten Zugriff auf dieses nicht erlaubt, muss ein weiteres Rendertarget mit der Größe des Backbuffers angelegt werden, in das die Multisampling-Tiefentextur kopiert wird. Somit ist auch ein per-pixel-depth-of-field unter DirectX10 mit Multisampling möglich. Grafikkarten mit DirectX10.1 Unterstützung erlauben es hier speicher- und performance-optimierter zu programmieren.

Schließlich werden alle vorherigen Schritte im letzten Schritt kombiniert. Dazu wird zuerst die Geometrie anhand der erzeugten Displacement-Map verändert, wodurch sie ihre Wellenform annimmt. Zusätzlich wird die Refraction- und Reflection-Map auf das Wasser projiziert, die Beleuchtung für das Wasser berechnet, der Schaum generiert und dem Meer seine Farbe gegeben.


Sub-Posteffekte

Zu einem einzelnen Posteffekt sind meist mehrere Schritte nötig, die in Sub-Posteffekte unterteilt sind. Für einen einfachen Blur-Filter, der ein verschwommenes Bild erzeugt, sampled[2] man mehrere Pixel in horizontaler Richtung, mischt sie im Pixelshader ab und speichert das Ergebnis in einem niedriger aufgelösten Rendertarget. In einem zweiten Schritt sampled man die zuvor abgespeicherten Pixel in vertikaler Richtung, mischt diese und speichert das Ergebnis ab. Diesen Vorgang muss man ggf. mehrfach wiederholen, je nach gewünschtem Grad und Qualität der Unschärfe. Für Anno1404 lassen sich recht einfach solche Effekte definieren. Im Posteffect-Script legt man den zuvor erstellten Shader fest, gibt an, welche Texturen, Rendertargets und Shader-Konstanten benötigt werden. Zum Schluss bestimmt man, wo und in welcher Auflösung das Ergebnis ausgegeben werden soll. Das Resultat des Effektes steht dann bereit, um für andere Posteffekte weiterverwendet zu werden oder landet direkt auf dem Backbuffer.


Hier ein Beispiel für einen solchen Effekt:

EFFECT PST_GLOW_BLUR_H
{
DIMENSION 128 128
SHADER "postfx_blur.fx"
POSTTEXTURE POST_TEXTURE0
ENABLE_DEFAULT_REGISTER cPostConstants
CONSTANT cUsrConstant1 1.0 0.0 0.0 0.0
}


Es wird zunächst ein Effekt mit dem Namen „PST_GLOW_BLUR_H“ angelegt, der auf ein Rendertarget mit einer Auflösung von 128x128 Pixel gerendert werden soll. Dazu soll der Shader „postfx_blur.fx“ verwendet und das Ergebnis eines vorherigen Effektes ihm als POST_TEXTUR0 zur Verfügung gestellt werden. Auf diese Weise werden die Effekte miteinander verknüpft. Anschließend werden dem Shader Standard-Informationen wie Bildschirmauflösung oder ein Timer mit ENABLE_DEFAULT_REGISTER mitgeteilt. Als letztes wird eine Effekt-Konstante gesetzt, die in diesem Fall dem Shader mitteilt, wie stark und in welche Richtung der Blur-Effekt das Bild verwischen soll.

Posteffekt

Ein Posteffekt besteht nun aus mehreren Sub-Posteffekten. Der Glow-Posteffekt z.B. speichert das ursprüngliche Szenenbild für eine weitere Verarbeitung ab, holt sich das Glow-Rendertarget, verwendet ein Horizontal-Blur, ein Vertikal-Blur und mischt das Ergebnis im letzten Schritt mit dem ursprünglichen Szenenbild ab.

SEQUENCE SEQ_GLOW
{
PST_STORE
PST_GLOW
PST_GLOW_BLUR_H
PST_GLOW_BLUR_V
PST_GLOW_ADD
}


Das Posteffektmanagment von Anno1404 erlaubt es nun, beliebig viele Posteffekt-Sequenzen aneinander zu hängen, so wie es die Spielsituation erfordert.

Im folgenden Beispiel wird eine Spielszene mit einem Produktionsgebäude in der Postkartenansicht erläutert. Dieses Beispiel enthält u.a. einen Heat- und Glow-Posteffekt sowie Tiefenunschärfe mit adaptivem Autofokus. Der Autofokus bei Anno1404 ist eine reine Shader-Lösung mit Hilfe des Posteffect-Managers. Hier wird zunächst die aktuelle Entfernung zum Blickzentrum aus dem Depthbuffer ermittelt. Als nächstes wird die Entfernung vorheriger Bilder über die Zeit hinweg an die aktuelle Entfernung angepasst. Das Ergebnis wird in einem 1 Pixel großem Rendertarget gespeichert, damit es für das nächste Bild verfügbar ist. Auf diese Weise passt sich der Fokus langsam und automatisch an das aktuelle Blickzentrum des Betrachters an.

Zunächst das Bild vor den Posteffekten, wie es nach dem regulären Rendering ausgegeben wird:
Als nächstes wird das Glow-Rendertarget für den Glüheffekt mit dem horizontalen und dem vertikalen Blur-Effekt vorbereitet, um ein Flackern des Glow-Effekts zu verhindern und eine schemenhafte Aura zu erzeugen.
Daraufhin wird das überarbeitete Glow-Rendertarget über die Szene gelegt:
Im Folgenden werden die im Heat-Rendertarget definierten Bereiche mit einer Verzerrung versehen:
Dann wird das ursprüngliche Bild mit einem horizontalen und vertikalen Blur für die Tiefenunschärfe vorbereitet:
Die folgenden Bilder enthalten das Depth-Rendertarget, welches die Tiefeninformation enthält und mit Hilfe des Autofokus so angepasst wird, dass die hellen Bereiche im darauf folgenden Schritt unscharf dargestellt werden und die dunklen scharf.

So erhält das endgültige Bild unscharfe Bereiche abhängig von der Entfernung zum Betrachter:


[1] Partikel ohne harte Schnittkanten.
[2] Ein Pixel aus einer Textur ermitteln.

von Robert Eichhorn (Software Developer, Related Designs)

 

               

© © 2015 Ubisoft Entertainment. All Rights Reserved. Anno 2205, Ubisoft and the Ubisoft logo are trademarks of Ubisoft Entertainment in the US and/or other countries.
Anno, Blue Byte and the Blue Byte logo are trademarks of Ubisoft GmbH in the US and/or other countries.
Datenschutz | Nutzungsbedingungen | Impressum | Kontakt | Jobs | Presse | Händler | Support | Über Ubisoft