Wie implementiere ich einen Echtzeit-2D-Lichtrenderer mit Nebel / farbigem Licht auf der GPU?


7

Seit langem wollte ich einen 2D-Blitzalgorithmus implementieren, der auf einer Idee basiert , die ich auf YouTube gesehen habe . Das Video ist in Echtzeit, läuft aber auf der CPU und die Auflösung ist ziemlich niedrig. Ich bin gespannt, ob jemand eine Idee hat, wie das auf der GPU geht.

Der Algorithmus funktioniert folgendermaßen:

  • Wir haben Lichtdatenkarten, die die Farbe des Materials enthalten (z. B. ein rotes Glas hat 0xFF0000) und wie transparent dieses Pixel ist.
  • Berechnen Sie die Lichtwerte jedes Pixels in wachsenden Kreisen von einer Lichtquelle. Mit anderen Worten, berechnen Sie zuerst Werte direkt neben dem Licht (8 Pixel), dann die Nachbarn dieser Pixel und so weiter. Die Farbe eines Pixels ist sein Wert aus der Blitzdatenkarte, sein Alpha ist gleich: (Alpha des Pixels daneben, das der Lichtquelle am nächsten liegt - eigenes Alpha). Es handelt sich also um eine Art Ray-Casting-Algorithmus, der den Wert für jedes Pixel berechnet und mit farbigem Glas und Nebel / Rauch umgehen kann.

Die CPU-Implementierung ist also ziemlich trivial. Mein Problem ist, dass ich dies in einem Handyspiel verwenden möchte, aber ich weiß nicht, wie dies als Shader funktionieren würde. Wie kann dies auf der GPU implementiert werden (die auf Mobilgeräten ausgeführt werden würde, also mit OpenGL ES 2.0 / 3.0, möglicherweise mit Metal - wenn dies nicht möglich ist, dann mit OpenCL / CUDA)?

Hinweis: Ich suche keine vollständigen Implementierungen, sondern nur Ideen / Shader-Pseudocode, wie dies möglich wäre.

Antworten:


6

Wenn Ihre Wandgeometrie Vektorgrafiken sind, können Sie das Segment einfach von der Lichtposition weg extrudieren. Dies bedeutet 2 Dreiecke pro Draw-Aufruf. Alle Extrusions-Offsets können im Vertex-Shader verarbeitet werden.

Geben Sie hier die Bildbeschreibung ein

Bild 1 : Erzeugen Sie für jede Wand eine Schattenvolumenextrusion.

Schnelle und extrem schmutzige Beispielimplementierung von Schattenvolumes hier:

Da Ihr Shader die Dreiecke nach Belieben färben kann, können Sie einen Shader auf die farbigen Dreiecke anwenden. Genau wie Sie transparente Oberflächen rendern würden. Um dies richtig zu machen, benötigen Sie möglicherweise einen Offscreen-Puffer, um einen ordnungsgemäßen Farbakkumulationsmodus zu erhalten.

Geben Sie hier die Bildbeschreibung ein

Bild 2 : Färben der Volumina basierend auf der Entfernung zum Licht.

Sicherlich kann der Färbealgorithmus beliebig sein. Zum Beispiel könnte die Farbe dunkler werden, je näher Sie der Extrudierkante usw. sind.

Und hier ist sehr schnell ein extrem schmutziges Live-Beispiel für farbige Schattenvolumina fertig :

Dies ist nur ein Weg, den andere hoffentlich verbessern werden. Sie können auch genau die gleichen Methoden wie in 3D verwenden. Für ungleichmäßigen Nebel können Sie einfach einen Raymarcher verwenden.


Danke für die Antwort! Aber ich suche nicht nach einem einfachen 2D-Schattenalgorithmus (es gibt viele im Web), sondern nach einem Schatten- / Lichtalgorithmus, der mit volumetrischem Nebel und farbigen transparenten Oberflächen umgehen kann (wie im Youtube-Video zu sehen).
Sydney

@sydd das ist nur ein Shader auf dem Schattenvolumen. Einfach zu erweitern.
Joojaa

@sydd fügte farbiges Beispiel hinzu
joojaa

danke, es sieht gut aus! Aber während ich meinen Beitrag schrieb, ging es darum, den von mir beschriebenen Algorithmus auf die GPU zu portieren. Tatsächlich gab jemand eine Antwort auf SO unter stackoverflow.com/questions/34708021/… . Diese Antwort ist das, wonach ich suche, aber sie ist langsam, daher denke ich nicht, dass dieser Algorithmus für ein echtes Spiel machbar ist.
Sydney

@sydd Raycasting kann beschleunigt werden, indem die Daten in eine bessere Datenstruktur vorberechnet werden.
Joojaa
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.