GtkRadiant logo

Quake 3 Radiant – Eigener Lampenshader

Last Updated on 19. March 2022 by Victor Karp

In den Texturkategorien base_light und gothic_light gibt es jede Menge Lichttexturen. Oftmals könnte man aber Texturen mit einer Helligkeit oder Farbe gebrauchen, die es leider nicht gibt. In diesem Tutorial werdet ihr lernen, wie man sich per Shader eigene Lampen mit beliebiger Farbe und Helligkeit zusammenstellen kann.

Um dem Tutorial folgen zu können, müsst ihr Tutorial Einstieg in Shader und Shadererstellung mit Q3ASE – Das Interface gelesen haben. Das Lesen von Tutorial Ein transparentes Gitter ist nicht zwingend notwendig, wird euch das Verstehen dieses Tutorials aber vereinfachen.

Ein Lampenshader ist in seiner Grundform sehr einfach aufgebaut und kann mit ein paar Extras erweitert werden, die die Lampe z.B. besonders stark glühen oder pulsieren lassen. Fangen wir mit der einfachsten Variante an, einer simplen Lampe.

Die Shaderdatei in diesem Tutorial wird wie schon in Tutorial 43 “myshader” heißen. Wenn ihr Tutorial 43 also schon gelesen und den dort gezeigten Shader nachgebaut habt, könnt ihr den Shader in diesem Tutorial als weiteren neuen Shader in der Datei anlegen. Wer Tutorial 43 noch nicht gelesen hat: startet Q3ASE und speichert die leere Shaderdatei als “myshader” im baseq3/scripts Ordner und fügt der shaderlist.txt im gleichen Ordner die Zeile “myshader” hinzu.

Ein einfacher Lampenshader

Klickt den leeren Shader in Q3ASE doppelt an und benennt ihn in textures/mytextures/lamp5000 um. Bei den General Keywords aktiviert ihr im Edit SurfaceParm Menü die Box No marks. Das verhindert, dass man auf den Lampen Einschussspuren sieht.

In der Texture Stage wählen wir eine der Lampentexturen aus, die vom Spiel mitgeliefert werden. Wenn ihr eine eigene Textur erstellt habt, könnt ihr natürlich auch diese verwenden. Für dieses Tutorial habe ich mich für die Textur base_light/ceil1_30 entschieden.

Nach einem Rechtsklick auf die Texture Stage, gefolgt von Edit RGB Source, erscheint ein Menü, in dem bereits identity ausgewählt ist. Das wollen wir genau so haben, deshalb könnt ihr das Menü einfach wieder mit OK schließen. Die Zeile rgbGen identity wird zur Texture Stage hinzugefügt. Mehr zu diesem Befehl erfahrt ihr im Tutorial über transparente Gitter.

Fügt eine zweite Texture Stage hinzu und stellt sie per Doppelklick im erscheinenden Menü auf Lightmap um. Fügt wie üblich für Lightmaps blendfunc -> filter hinzu. rgbGen identity braucht ihr auch wieder.

Fehlen noch die Lichtfarbe und -helligkeit. Die Helligkeit könnt ihr über einen Rechtsklick auf General Keywords, gefolgt von q3map_ -> surfacelight angeben. In das Popup Fenster tippt ihr den Wert 5000 ein. Dieser Wert steht bei vielen der Originalshader schon im Shadernamen. Das macht es bei vielen verschiedenen Lampen einfacher, die Lichtstärken auseinanderzuhalten.

Für den Lampenshader werden wir einen Befehl brauchen, den ihr in vielen Shadern benutzen müsst. In Tutorial 43 war er nicht nötig, weil der Name des Shaders und der Name der Zauntextur identisch waren. Bei unserem Lampenshader aber heißt die Textur base_light/ceil1_30 und der Shader mytextures/lamp5000. Wenn wir nichts weiter ändern würden, würde der Radiant nicht wissen, welches Vorschaubild er verwenden soll. Er benutzt in so einem Fall eine Platzhaltertextur:

Um das zu verhindern, klickt ihr mit der rechten Maustaste auf die General Keywords und wählt qer_ -> editorimage. Hier ladet ihr dann die gleiche Datei, die ihr auch als Textur für die Lampe  verwendet habt.

Die Lichtfarbe habt ihr bereits angegeben, denn die berechnet sich aus dem Durchschnittsfarbwert der Textur. Wenn ihr sie unabhängig von der Lampentextur ändern wollt, könnt ihr das über General Keywords -> q3map_ -> lightimage tun. Für volle Farbkontrolle empfiehlt sich bei dieser Option eine einfarbige Textur, die ihr extra zu diesem Zweck anlegt.

Ihr müsst den Shader noch einmal speichern.

Ingame sehen die Lampe nach einem Compile so aus:

Und hier der fertige Shader:

textures/mytextures/lamp5000
{
    qer_editorimage textures/base_light/ceil1_30.tga
    surfaceparm nomarks
    q3map_surfacelight 5000
    {
        map textures/base_light/ceil1_30.tga
        rgbGen identity
    }
    {
        map $lightmap 
        blendfunc filter
        rgbGen identity
    }
}

Stärkeres Glühen

Durch das Hinzufügen einer weiteren Texture Stage lässt sich ein Glüheffekt erzeugen, der die Lampe kräftiger und glaubhafter erscheinen lässt. Fügt dazu eine weitere Stage zwischen der ersten Stage und der Lightmap Stage hinzu. Die bekommt wie immer erstmal rgbGen identity verpasst.

Als Textur wählen wir textures/base_light/ceil1_30.blend. Diese Variante der blauen Lampentextur ist dort schwarz, wo die Lampe nicht leuchtet. Klickt mit der rechten Maustaste auf die neue Stage und wählt blendfunc -> add. Ihr werdet sehen, dass die Lampe jetzt deutlich stärker glüht als vorher. Für einen Vorher-Nachher Vergleich könnt ihr die Stage per Rechtsklick -> Hide in preview ein- und ausblenden.

blendfunc add addiert die Farbwerte einer Textur zu den Farbwerten der darunterliegenden Textur hinzu. Weil schwarz mathematisch mit Null gleichzusetzen ist, passiert auf dem Rahmen der Lampe nichts, während die Lampe selbst heller wird. Im Extremfall heißt das: legt ihr  die ceil1_30.blend Textur auf einen schwarzen Hintergrund und gebt blendfunc add an, ändert sich überhaupt nichts.

Die Lampe pulsieren lassen

Klickt mit der rechten Maustaste auf die neue Texture Stage und wählt Edit RGB Source. Stellt von identity auf waveform um und klickt auf den Edit Button rechts daneben. In dem neuen Fenster muss oben in dem kleinen Dropdownmenü sine eingestellt sein.

Darunter seht ihr vier Felder: Base value, Amplitude, Phase und Repeats per second. Bis auf Phase werden wir alle Werte benutzen, um ein langsam an- und abschwellendes Licht zu erstellen.

Fangen wir mit Base value (“Grundwert”) an. Base value gibt an, welchen Helligkeitswert (von schwarz bis weiß) die Textur haben soll. 0 steht für schwarz, 1 für weiß, 0.5 ist die ganz normale Darstellung der Textur. Stellt 0.5 ein, damit wir als Ausgangsposition die unveränderte Textur haben.

Amplitude (“Ausschlag”) steht für die Abweichung vom Grundwert. Wir haben als waveform sine ausgewählt. sine pendelt immer zwischen einem Maximum und einem Minimum hin und her, diese beiden Werte bekommen wir durch eine simple Rechnung.

Das Minimum ergibt sich aus Base value minus Amplitude. Das Maximum aus Base value plus Amplitude. Der ideale Wert für Amplitude ist für uns 0.5, weil das einmal 0 und einmal 1 ergibt. Auf Deutsch heißt das: die Textur wird einmal schwarz und einmal weiß.

Fehlt noch Repeats per second (“Wiederholungen pro Sekunde”). Der Wert hierfür steht momentan noch auf 1, was ziemlich viel ist. 1 bedeutet, dass unsere Textur pro Sekunde einmal dunkel und wieder hell wird, was für ein subtiles Wabern viel zu schnell ist.  Ein Wert von 0.1 ist besser. Das ist ein kompletter Zyklus in 10 Sekunden.

Wenn ihr eine Vorschau sehen möchtet, könnt ihr auf den Preview Button an der rechten Seite des Fensters klicken. Dort gibt es dann eine vereinfachte schwarz-weiß Darstellung. Wollte ihr eine richtige Vorschau für die Textur haben, müsste ihr das Fenster mit OK schließen. Ihr könnt es danach wieder über den Edit Button öffnen oder durch einen zweiten Klick auf OK das Menü komplett verlassen.

Wenn ihr keinen ganz so starken Helligkeitswechsel haben wollt, ändert das Verhältnis zwischen Grundwert und Amplitude. Eine Textur mit Grundwert 0.8 und Amplitude 0.2 ist insgesamt eher hell und wird nur ein bisschen dunkler, während ein Grundwert von 0.3 mit einer Amplitude von 0.1 nur ein schwaches Glimmen erzeugt. Denkt auch daran, dass ihr die Repeats per second anpassen könnt.

Diese Helligkeitsspielerei bezieht sich übrigens nur auf die Textur. An der Helligkeit des Lichts in eurer Map ändert sie nichts. Quake 3 unterstützt in gewissem Maße aber auch echte flackernde Lichter.

Weitere Effekte

Mit ein bisschen Spielerei lassen sich interessante Effekte erzielen. Der Raum, in dem Base value und Amplitude funktionieren, ist nicht auf Werte von 0 bis 1 beschränkt. Das ist lediglich der Bereich, in dem sich sichtbar etwas ändert. Alles unter 0 wird nicht schwärzer und alles über 1 wird nicht weißer. Trotzdem passiert etwas, wenn die Werte über diese Markierungen rutschen: es vergeht Zeit. Was das bedeutet, erkläre ich an einem Beispiel.

Der Grundwert liegt bei 0.5, die Amplitude bei 2. Die Repeats per second sind bei 0.2. Ein kompletter Zyklus dauert also 5 Sekunden. Wir fangen bei 0.5 an. Normale Helligkeit. Rauf auf 1. Maximale Helligkeit. Rauf auf 2.5. Immer noch maximale Helligkeit. Runter auf 1. Immer noch maximale Helligkeit. Am Grundwert vorbei runter auf 0. Erst in diesem Bereich wurde das Bild einmal von hell zu dunkel umgekehrt. Dann wieder bis -2.5 Dunkelheit und auch von -2.5 bis zurück nach 0 Dunkelheit. Wieder zurück nach 0.5 zum Normalwert.

Durch diese Werte pendelt die Textur nicht unaufhörlich zwischen hell und dunkel, sondern verharrt immer eine bestimmte Dauer in einem Zustand.

Besuche die Quake 3 Mapping Tutorial Hauptseite für weitere Tutorials.

Scroll to top