Kann ich in einem 2D-Spiel einen Fackeleffekt (hellerer Bereich um eine Lichtquelle) erzielen?

16

Ich denke darüber nach, mir ein einfaches 2D-Spiel zu schreiben. Es wird zunächst nicht mit perfekter Grafik oder perfektem Gameplay glänzen, aber ich würde es als meinen ersten Schritt in der PC-Spieleentwicklung betrachten. Stellen Sie sich ein solches einfaches Sprite-basiertes 2D-Spiel vor (wie Heroes IV oder Startcraft BroodWar).

Ich möchte, dass das Gameplay Tag / Nacht mit den entsprechenden Beleuchtungsänderungen unterstützt und es gleichzeitig wahnsinnig wird, für jede Beleuchtungsnuance Sprites erstellen zu müssen. Daher habe ich beschlossen, dass das Hinzufügen einer halbtransparenten Ebene über anderen Objekten ausreicht.

Das Problem bei dieser Lösung ist, dass wenn ich ein Lichtquellenobjekt im Spiel habe (wie der Held, der eine Fackel trägt oder ein brennendes Gebäude), es einen helleren Bereich geben muss, oder? Wie würden Sie vorschlagen, um den gewünschten fackellichten visuellen Effekt zu erzielen, da ich meine halbtransparente Schicht über alles lege? Vielleicht diese Ebene neu zeichnen und "Lücken" oder andersfarbige Bereiche hinzufügen, basierend auf dem Lichteffekt?

Ivaylo Slavov
quelle
2
Maske kann der richtige Weg sein
Gustavo Maciel
5
"Torchlight" im Titel kann aufgrund des Spiels mit dem Namen Torchlight verwirrend sein.
Tetrad
4
@Tetrad Sollte in Ordnung sein, solange es nicht groß geschrieben wird. Was mich betrifft, ist mir Fackellicht erst in den Sinn gekommen, als ich Ihren Kommentar gelesen habe.
famousgarkin
Trotzdem schlug ich eine Bearbeitung vor, um den Titel genauer zu definieren.
famousgarkin
2
mögliches Duplikat von Wie wird 2D-Beleuchtung implementiert?
Mistzack

Antworten:

12

Ich weiß nicht, in was Sie programmieren, aber so habe ich es in XNA gehandhabt:

  1. Beim Zeichnungsaufruf wird ein List<Light>Objekt erstellt / gelöscht.
  2. Während der Kachel-Zeichenschleife wird für jede Kachel geprüft, ob mit ihr Lichter verknüpft sind. Wenn dies der Fall ist, werden die LightObjekte an die angefügt List<Light>.
  3. Die Kacheln werden einzeln gezeichnet RenderTarget2D.
  4. Nach der Kachelschleife wird die Liste von Lights iteriert und RenderTarget2Dmit einer von mir erstellten Textur wie folgt gezeichnet :
    Leichte Textur(Hinweis: Ich habe hier die Werte R, G und B verwendet, aber Sie sollten wahrscheinlich den Alphakanal in Ihrer verwenden tatsächliche Textur.)
  5. Mit einem benutzerdefinierten Shader rendere ich die Kacheloberfläche auf dem Bildschirm und übergebe die Beleuchtungsoberfläche als Parameter, der für den "Dunkel" -Wert bei jedem Pixel abgetastet wird.


Nun gibt es ein paar Dinge zu beachten:

Zu Punkt 4:

Eigentlich habe ich zwei benutzerdefinierte Shader, einen zum Zeichnen der Lichter zum Beleuchtungs-Rendering-Ziel (Schritt 4) und einen zum Zeichnen des Kachel-Rendering-Ziels zum Bildschirm unter Verwendung des Beleuchtungs-Rendering-Ziels (Schritt 5).
Mit dem unter Punkt 4 verwendeten Shader kann ich einen "Leuchtkraft" -Wert hinzufügen (was ich nenne). Dieser Wert wird floatmit jedem Pixel in der Textur multipliziert, bevor er zum Render-Ziel hinzugefügt wird, damit ich die Lichter im Wesentlichen heller oder dunkler machen kann.
An dieser Stelle berücksichtige ich auch den "Skalierungs" -Wert des Lichts, was bedeutet, dass ich mit nur einer Textur große oder kleine Lichter haben kann.

Zu Punkt 5:

Stellen Sie sich das Beleuchtungs-Rendering-Ziel so vor, dass es im Wesentlichen einen Wert für jedes Pixel von 0 (schwarz) bis 1 (weiß) aufweist. Der Shader multipliziert diesen Wert im Wesentlichen mit den RGB-Werten für ein Pixel im Kachel-Rendering-Ziel, um das endgültig gezeichnete Bild zu erhalten.

Ich habe hier auch etwas mehr Code, in dem ich (an den Shader) einen Wert übergebe, der als Tag / Nacht-Overlay-Farbe verwendet werden soll. Dies wird auch mit den RGB-Werten multipliziert und in die Berechnungen der Beleuchtungsrenderingziele einbezogen.


Auf diese Weise können Sie nicht verhindern, dass Licht um Objekte herumgeht, und so weiter, aber zumindest für meine Zwecke ist es einfach und funktioniert gut.

Ich habe hier und hier detailliertere Blog-Beiträge verfasst , die dir vielleicht helfen. Ich habe momentan keine Zeit, aber wenn Sie möchten, kann ich hier auf gamedev näher eingehen.

Oh, und hier ist ein Blick darauf in meinem Karteneditor:Bildbeschreibung hier eingeben

Richard Marskell - Drackir
quelle
Eine Liste erstellen und löschen, jeder Frame ist möglicherweise nicht zu teuer?
Gustavo Maciel
@Gtoknu Macht in meinem Spiel keinen nennenswerten Unterschied. Die Liste enthält lediglich Verweise auf Objekte, die bereits im Speicher vorhanden sind, sodass nicht jedes Licht neu erstellt wird, sondern nur eine Liste.
Richard Marskell - Drackir
du magst recht haben, nicht ganz, aber du bist. Natürlich erstellen Sie keine vollständigen Objekte, aber Sie fügen Zeiger zu Referenzen hinzu, die zwar noch wenig genutzt werden, aber dennoch aufwendig sind. Sie machen das auf eine gute Art und Weise, aber ich denke, es ist besser, wenn Sie die Liste außerhalb der Zeichenmethode platzieren, da die Logik beim Aktualisieren viel schneller ist als beim Zeichnen
Gustavo Maciel
@Gtoknu Sicher, Sie können die Liste deklarieren, wo immer Sie wollen, aber der Punkt ist, dass die Lichter den Kacheln zugeordnet sind. Mit der Kachelmethode können DrawSie herausfinden, ob eine Kachel über Lichter verfügt oder nicht. Ich durchlaufe nicht alle gezeichneten Kacheln in der UpdateMethode, daher würde ich dafür zusätzlichen Overhead hinzufügen. Außerdem versucht XNA zu gewährleisten, dass dieser Code Update60 Mal pro Sekunde aufgerufen wird, sodass möglicherweise DrawAufrufe dafür geopfert werden. Dies bedeutet, dass dieser Code tatsächlich seltener aufgerufen wird.
Richard Marskell - Drackir
Alles in allem ist es ein strittiger Punkt, weil ich die Lichter schließlich auf der Grundlage der räumlichen Unterteilung in ihre eigenen Listen verschoben habe und einfach alle Lichter in Abschnitte gezeichnet habe, die den Bildschirm schneiden. Ich habe in meinem Post aus Zeitgründen nicht darüber gesprochen, aber es wird in dem zweiten Blog-Post erwähnt, den ich verlinkt habe.
Richard Marskell - Drackir
9

Normalerweise wird die Beleuchtung in 2D-Spielen ausgeführt, indem für alle Sprites eine normale Karte erstellt und anschließend die 3D-Beleuchtungseffekte für die 2D-Sprites berechnet werden. Dies ist locker als "2.5D" bekannt. Ich würde es jedoch nicht empfehlen, dies in Ihrem ersten Spiel zu tun, da es komplex ist.

Hier ist ein fantastisches Video von jemandem, der dies in XNA getan hat: http://www.youtube.com/watch?v=-Q6ISVaM5Ww

Das heißt, es gibt wahrscheinlich Möglichkeiten, ein Pseudo-Beleuchtungssystem zu betrügen und zu erhalten, das mit verschiedenen Annahmen funktionieren könnte.

John McDonald
quelle
Ich habe dieses Video bereits gesehen, +1 für die Erwähnung einer solch unglaublichen Technik.
Gustavo Maciel
Vielen Dank für den Rat und den Videolink. In der Tat scheint eine Karte eine Lösung zu sein. Ich selbst würde versuchen, die Karte auf meiner obersten Ebene zu verwenden, um eine "Lücke" zu erstellen oder um den Effekt zu ändern, den sie auf die zugrunde liegenden Objekte hat.
Ivaylo Slavov
5

Es ist schwierig, einen Ansatz vorzuschlagen, wenn Sie nicht genau wissen, welchen Effekt Sie erzielen möchten. Details wie ob die Lichter durch die Umgebung behindert werden sollen oder nicht, was ist der Standpunkt Ihres Spiels, inwieweit sollte das Licht mit der Umgebung interagieren, etc.

Ich werde aber meine zwei Cent fallen lassen. Sehen Sie, ob dieses Tutorial von Catalin Zima mit dem Titel Dynamic 2D Shadows zu Ihrer Rechnung passt. Wie Sie sehen, hat das Licht einen Radius und geht nicht durch Hindernisse. Sie können den Radius und die Farbe ein wenig animieren, damit sie einem echten Fackellicht näher kommen.

Bildbeschreibung hier eingeben

In diesem Fall fungiert das Licht als eine Art Überlagerung über Ihrer Szene, interagiert jedoch nicht in demselben Maße wie in Johns Beispiel, obwohl Hindernisse berücksichtigt werden.

Bearbeiten

Catalin verlinkt auf einen anderen Artikel, den er als Referenz verwendet hat, aber der Link ist unterbrochen. Hier ist ein aktualisierter Link .

David Gouveia
quelle
Danke, ich denke, das ist nicht der Effekt, den ich anstrebe, aber trotzdem danke fürs Teilen :)
Ivaylo Slavov