Blendeffekt zur Lichtextur hinzufügen

In diesem Tutorial möchte ich dir zeigen, wie du zu lichtemittierenden Texturen einen bereits vorhandenen oder auch selbst erstellten Blendeffekt, also ein so genanntes Flare erzeugen kannst. Bevor du aber loslegst, solltest du sicherstellen, dass du den Q3Map2-Compiler mindestens in Version 2.5.16 und den GtkRadiant 1.4 oder neuer für World of Padman installiert und konfiguriert hast. Mit älteren Versionen könnte es bei der Anwendung dieses Tutorials zu Fehlern kommen.

Allgemeines zu Flares

Als Flare wird eine Art Blendeffekt bezeichnet, der um eine Lichtquelle herum durch Streuung entsteht. Wenn du z. B. in den Abendstunden direkt in das Licht einer Straßenlaterne schaust, wirst du eine Korona um die Lichtquelle herum feststellen. Verursacht wird das durch die Streuung im Glaskörper deines Auges. Eine hohe Luftfeuchtigkeit kann den Effekt noch deutlich verstärken (z. B. Nebel). In Computerspielen finden Flares schon sehr lange Anwendung. Zum Beispiel wurde in Unreal anno 1999 dieser Blendeffekt sehr exzessiv eingesetzt. Dank ioquake3, auf dessen Quellcode World of Padman aufbaut, sind auch wir in der Lage dieses Feature zu verwenden und in unsere Maps zu integrieren. Es gibt dazu zwei Möglichkeiten, die ich dir vorstellen möchte. Die erste Variante, hier von mir als „dynamisches“ Flare bezeichnet, nutzt das Blendeffekt-Feature der Grafikengine. Die zweite Variante, hier von mir als  „statisches“ Flare bezeichnet, ist eigentlich nur ein Trick, um ein dynamisches Flare zu simulieren, kann jedoch in bestimmten Situation von Vorteil sein. Wann es sich empfiehlt, welche Variante zu nehmen, erfährst du in den folgenden Abschnitten.

Ein dynamisches Flare einbinden

Als dynamisches Flare wird hier in diesem Zusammenhang von mir jener Blendeffekt bezeichnet, der sich mit Änderung der Distanz eines Betrachters zu einer Lichttextur in Größe und Intensität verändert. Voraussetzung dafür ist also eine Textur, die über die Eigenschaft des zugehörigen Shaders Licht emittieren, also aussenden soll und in der Fläche nur begrenzt eingesetzt wird. Schlecht einzusetzen ist diese Art von Flare bei lang gezogenen, sehr großen oder auch mehrfach gekachelten Lichttexturen, da der Blendeffekt stets automatisch im Mittelpunkt der Textur angeordnet wird.

Lichttextur ohne Flare (links) und mit "dynamischen" Flare (rechts)

Lichttextur ohne Flare (links) und mit „dynamischen“ Flare (rechts)

Basis für den Blendeffekt in World of Padman ist eine spezielle Blendeffekttextur flareb.tga, die unter textures/pad_gfx zu finden ist. Diese Textur stellt eine kreisrunde Korona dar, die mit einem zugehörigen Shader pad_flare.shader ausgestattet ist, um sie in unterschiedlicher Intensität transparent zu machen. Der Shader sieht folgendermaßen aus:

flareShader
{
   cull none
   {
      map textures/pad_gfx/flareb.tga
      blendFunc GL_ONE GL_ONE
      rgbGen vertex
   }
}

Theoretisch könntest du auf dieser Basis auch eigene Blendeffekte erstellen, die andere Texturen verwenden. In jedem Fall sollten sich dann aber Name und Pfad deines Shaders von unserem unterscheiden, um unseren nicht aus versehen zu überschreiben! Im Spiel selbst wird der Blendeffekt stets automatisch über den Mittelpunkt der Lichttextur gelegt. Um Ihn nutzen zu können, muss er von dir direkt in den Shader deiner Lichttextur eingebunden werden. Der Shader einer Textur, die Licht aussenden soll, kann folgendermaßen aussehen:

textures/meinemap/meinlicht_100
{
   q3map_surfacelight 100
   q3map_flareShader flareShader
   q3map_lightRGB 0 0 1
   surfaceparm nolightmap
   {
      map textures/meinemap/meinelichttextur.tga
   }
}

Kurz zur Bedeutung der einzelnen Shaderzeilen:

textures/meinemap/meinlicht_100

Hier sind Pfad und Name des Lichttextur-Shaders angegeben. Später wird der Shader im Radiant in dem Verzeichnis meinemap mit dem Namen meinlicht_100 angezeigt. Bei Lichttexturen solltest du möglichst immer hinzu schreiben wie hell das Licht ist. In diesem Beispiel beträgt die Intensität 100.

q3map_surfacelight 100

Über den Key q3map_surfacelight kannst du festlegen, wie hell das ausgesendete Licht sein soll. In diesem Beispiel beträgt die Intensität 100.

q3map_flareShader flareShader

Über den Key q3map_flareShader bindest du den Blendeffekt-Shader mit dem Namen  flareShader ein. Hier könntest du auch Pfad und Name deines eigene Blendeffekt-Shaders angeben, sofern du einen erstellt hast.

q3map_lightRGB 0 0 1

Zusätzlich kannst du den Flare natürlich farblich an die zu emittierende Lichtfarbe deiner Licht-Textur anpassen, indem du die 3 gewünschte RGB-Farbwerte (Dezimalwerte zwischen 0 und 1) über den Key q3map_lightRGB <Rot> <Grün> <Blau> definierst. Im Beispiel wird hier eine blaue Farbe erzeugt. Wird dieser Key weggelassen, bleibt der Blendeffekt einfach weiß.

Hinweis: Normalerweise werden die Farbintensitäten in der RGB-Farbpalette mit Werten zwischen 0 und 255 angegeben. Die id-Tech3 Grafikengine verarbeitet aber nur Dezimalwerte, daher musst du deine RGB-Werte durch 255 dividieren, um zu Dezimalwerten zu gelangen. Als Beispiel wird aus einer Farbe mit den Werten 200 34 255 dann 0,784 0,133 1,0. Bitte beachte die amerikanische Schreibweise mit Dezimalpunkt anstelle des Kommas, also:  0.784 0.133 1.0!

surfaceparm nolightmap

Der Parameter nolightmap beschreibt eine Eigenschaft der Textur und definiert, dass sie beim Kompilieren der Lightmap keine Berücksichtigung findet. Ergo kann auf die Blendeffekttextur selbst kein Schatten fallen, was auch unsinnig wäre.

map textures/meinemap/meinelichttextur.tga

Über den Parameter map definierst du den Pfad zu der Textur, die das Licht aussenden soll. Die Textur muss nicht im unbedingt im TGA-Format vorliegen, jedoch muss im Shader tga stehen bleiben!

Damit das dynamische Flare auch in der Map später funktioniert, bedarf es des neuen Parameters -flares im BSP-Stage beim Kompilieren, der direkt hinter -meta ergänzt werden sollte. Wir haben den Parameter im Build-Menü des GtkRadiants bereits an den drei Stellen ergänzt. So kannst du einerseits mittels single flares den BSP-Stage frei mit nachfolgenden Stages deiner Wahl kombinieren oder die Map über wop test flares bzw. wop final flares in einem Rutsch testweise bzw. final berechnen lassen. Falls du Q3Map2Build zum Kompilieren verwendest musst du den Parameter -flares im BSP-Stage zusätzlich markieren.

Build-Menü des NetRadiant mit zusätzlichen Flare-Befehlszeilen

Build-Menü des NetRadiant mit zusätzlichen Flare-Befehlszeilen

Ein statisches Flare einbinden

An dieser Stelle wird auf eine althergebrachte Möglichkeit eingegangen einen Blendeffekt in eine Map einzubinden. Ich will sie hier als statisches Flare bezeichnen, da ein statisches Flare, im Gegensatz zum dynamischen Flare, nicht in Größe und Intensität bei Distanzvariation des Spielers zur Lichtquelle verändert. Das statische Flare basiert zwar gleichermaßen auf einem Shader und einer Blendeffekttextur, jedoch wird diese nicht direkt im Shader der lichtemittierenden Textur aufgerufen. Dadurch is es sehr flexibel und in vielen Situationen einsetzbar und eignet sich besonders gut für das Aufwerten von Mapobjekten und komplexerem Brushwork, die im Spiel als Lichtquelle fungieren sollen. Der im Folgenden dargestellte Beispiel-Shader sorgt dafür, dass die Blendeffekttextur immer mit der gleichen Seite zur Position des Spielers zeigt, sich also mitdreht (auch als Autosprite bezeichnet).

textures/meinemap/meinstatischesflare
{
   deformVertexes autoSprite
   surfaceparm trans
   surfaceparm nomarks
   surfaceparm nolightmap
   {
      clampmap textures/meinemap/meineflaretextur.tga
      blendFunc add
   }
}

Kurz zur Bedeutung der einzelnen Shaderzeilen:

textures/meinemap/meinstatischesflare

Hier sind Pfad und Name des Blendeffekt-Shaders angegeben. Später wird der Shader im Radiant in dem Verzeichnis meinemap mit dem Namen meinstatischesflare angezeigt.

deformVertexes autoSprite

Die Eigenschaft deformVertexes mit dem Wert autoSprite sorgt dafür, dass die entsprechende Textur immer mit der gleichen Seite zur Position des Spielers zeigt, sich also mitdreht.

surfaceparm trans

Der Parameter trans definiert die transparente Eigenschaft der Textur.

surfaceparm nomarks

Der Parameter nomarks beschreibt eine Eigenschaft der Textur und definiert, dass Geschosse (z. B. Raketen) keine Einschlagspuren hinterlassen können.

surfaceparm nolightmap

Der Parameter nolightmap beschreibt eine Eigenschaft der Textur und definiert, dass sie beim Kompilieren der Lightmap keine Berücksichtigung findet. Ergo kann auf die Blendeffekttextur selbst kein Schatten fallen, was auch unsinnig wäre.

clampmap textures/meinemap/meineflaretextur.tga

Über den Parameter clampmap definierst du den Pfad zu der Textur, die das Licht aussenden soll. clampmap bewirkt im Gegensatz zu map dass die Textur immer genau in der Größe des Brushes hoch oder herunter skaliert wird und somit immer passt. Auch wenn sie im Radianten gekachelt dargestellt oder eine Skalierung vorgenommen wird, nimmt sie im Spiel immer die Größe des Brushes an. Die Textur selbst muss nicht im TGA-Format vorliegen, jedoch muss im Shader tga stehen bleiben!

blendFunc add

Die blendFunc definiert inwiefern die Textur mit der dahinter liegenden Textur verblendet wird. add ist dabei die Kurzschreibweise für GL_ONE GL_ONE und sorgt dafür, dass die Textur mit dem Hintergrund additiv überblendet wird.

Um ein statisches Flare einbauen zu können, benötigst du einen quadratischen Brush mit den ungefähren Abmessungen, die der Flare später im Spiel haben soll. Der Brush sollte eine Dicke von einer Unit nicht überschreiten und alle Seiten, bis auf die Seite mit der Blendeffekttextur, müssen mit der Textur nodraw versehen sein. Jetzt muss der Brush nur noch im Zentrum der Lichtquelle positioniert werden. Da es sich hier um den Einsatz einer einfachen Textur handelt benötigst du, im Gegensatz zum dynamischen Flare, keine zusätzlichen Parameter beim Kompilieren.

"Statisches" Flare im Radiant (links) und im Spiel (rechts)

„Statisches“ Flare im Radiant (links) und im Spiel (rechts)