Ich habe an einem 2D-Kachelspiel gearbeitet und eine scharfkantige Beleuchtung implementiert:
Ich möchte, dass es ein bisschen geglättet wird. Ich brauche keine Schatten oder ähnliches, nur einfache Beleuchtung. Ich möchte, dass es eher so aussieht:
Mein aktuelles System verwendet Lichtstärken für jede Kachel auf der Welt und sie werden neu berechnet, wenn eine Kachel platziert oder entfernt wird. Ich benutze, batch.setColor(...)
um die Fliesen zu beschatten. Was ist ein guter Weg, um diese gleichmäßige Beleuchtung zu erreichen?
Ich möchte die Light Map Overlay-Methode nicht verwenden, das habe ich bereits versucht und war mit dem Ergebnis nicht zufrieden. Ich möchte einstellen können, wie viel Licht durch einen Block hindurchtreten kann. Zum Beispiel sollte ein Schmutzblock einen Teil des Lichts absorbieren, aber ein Glasblock sollte kein Licht blockieren. Dies war mit der Light Map Overlay-Methode nicht wirklich möglich. UPDATE: Ich habe falsch verstanden, was diese Methode eigentlich ist. Ich verstehe jetzt. Ich habe falsch gedacht. Es tut uns leid!
Antworten:
Eine einfache Möglichkeit, in einem auf Kacheln basierenden Spiel eine gleichmäßige Beleuchtung zu erzielen, besteht darin, eine "Lichtkarte" auf ein Renderziel zu zeichnen und dieses Renderziel dann über Ihre Szene zu zeichnen, während Sie es mit Alpha mischen.
Ihr Lichtkarten-Rendering-Ziel hat die Größe Ihrer Kachelkarte, jedoch in Pixel. Jedes Pixel würde die helle Farbe seiner entsprechenden Kachel darstellen. Diese Rendertextur würde ungefähr so aussehen (Textur oben links in Schwarzweiß):
Sobald Sie diese leichte Kartentextur haben, können Sie sie als Überlagerung über Ihre Spielwelt zeichnen (ausgestreckt). Sie müssen es richtig festklemmen, damit es sich perfekt über Ihre Kacheln in der Spielwelt erstreckt.
Dann geht es darum, diese Textur in libGDX auf Ihre Spielwelt zu mischen. Um LibGDX zu integrieren (ich persönlich weiß nicht wie), müssen Sie sich möglicherweise die
Gdx.gl.glBlendFunc
Funktion ansehen .quelle
Ein motorunabhängiger Weg, dies zu tun, ist die Verwendung einer durchschnittlichen Lichtabbildung. Zunächst müssen Sie eine Schwarzweißkarte als 2D-Array von Booleschen Werten generieren, die der Größe der Welt entspricht, in der die Blöcke wahr und leer falsch sind.
So (1 ist schwarz, 0 ist weiß):
Anschließend müssen Sie ein neues 2D-Array erstellen, das dieselbe Größe wie das erste Array hat, jedoch ein Array von Floats ist. Dann wechseln Sie vom schwarzen (True) Block zum schwarzen Block im Array und mitteln den nahegelegenen Abtastwert (siehe unten).
Dieses Bild hilft:
Dieses Bild stellt die Stichprobe dar (wobei + falsch und | wahr bedeutet). Wir behandeln True-Werte als 1 und False-Werte als 0. Dann mitteln Sie die 9 Zahlen und fügen sie in den richtigen Teil des Arrays ein. HINWEIS: Stellen Sie sicher, dass Sie beim Abtasten von Kanten äußere Werte als kontextsensitiv behandeln. Zum Beispiel: Unterirdisch könnte die Karte außerhalb der Welt 1 sein und der Himmel sollte 0 sein.
Es sollte so aussehen (aus einem anderen Beitrag):
Dann müssen Sie nur noch jeden Block im Array mit tönen
(Farbton = der aktuell gemittelte Blockwert im zweiten Array und Alpha spielt keine Rolle). Hinweis: Dies setzt voraus, dass die Pseudofunktion rgba Gleitkommazahlen von 0-1 anstelle von 0-255 nimmt. Wenn dies der Fall ist, gehen Sie einfach wie folgt vor:
Hoffe das hat ein wenig Sinn gemacht :) Wenn Sie Code wollen, fragen Sie bitte!
quelle
Da Sie über Dinge sprechen, die Licht blockieren, gehe ich davon aus, dass Sie ein Modell dafür haben, wie sich Licht ausbreiten soll. Zum Beispiel ist alles ohne Blöcke vollständig beleuchtet, das Licht breitet sich auf alle benachbarten Zellen aus, verliert jedoch eine gewisse Helligkeit.
Sie sollten in der Lage sein, diese Regeln auf der Softwareseite ziemlich einfach zu implementieren, zumindest ist der Glättungsteil nur eine Frage des Werfens eines Shaders auf die von Ihnen erzeugte Lichtkarte.
Die Methoden, die andere beim Überlagern einer Lichtkarte vorgeschlagen haben, sollten Sie sowieso tun. Sie können jedoch ändern, wie Sie diese Lichtkarte erstellen. Sie können es zunächst nur mit den Blockinformationen füllen, dann aber beispielsweise skalieren und in einem Shader glätten. Ein zusätzlicher Vorteil des Lichtkartenansatzes besteht darin, dass Sie einfach auch dynamisches Licht in Ihre Lichtkarte zeichnen können, um Explosionen hervorzuheben oder was Sie haben, und es wird sich natürlich mit dem Rest Ihrer Welt vermischen.
Additive Blend-Inhalte in Ihre Lichtkarte und multiplikative Mischung Ihrer Lightmap mit der Spielwelt.
Ich habe das vor einiger Zeit gemacht, wobei die gleichen Prinzipien angewendet wurden. Dieses System unterstützt nicht, dass der Lichteinfall für verschiedene Geländetypen unterschiedlich ist, sollte jedoch zumindest die Nützlichkeit der Überlagerung einer Lichtkarte veranschaulichen.
quelle
Für eine Taschenlampe ist es ziemlich einfach: Mit einem benutzerdefinierten Pixel-Shader berechnen Sie den Abstand zwischen jedem Fragment und der Taschenlampe. Sie können dann berechnen, wo sich die erste dichte Kachel befindet, die das von der Fackel kommende Licht blockiert. Sie berechnen dann die Entfernung, in der das Licht nicht blockiert ist, multiplizieren diese mit etwas <1, damit die Fackel die Sonne nicht beleuchtet, subtrahieren diese von der Gesamtentfernung und wiederholen sie für den Rest der Entfernung (wo das Licht um um blockiert wurde) mindestens eine Kachel) mit einem viel kleineren Multiplikationswert ... Ich weiß, wie man diese Mathematik macht und es ist nicht zu kompliziert, sie in opengl zu implementieren.
BEARBEITEN: Für eine einfache Lichtquelle mit einem bestimmten Mittelpunkt ist meine Methode extrem einfach. Meins funktioniert jedoch nicht mit Sonnenlicht, aber während die Alpha-Karte für Sonnenlicht sehr gut funktioniert, wäre es für eine Taschenlampe KEINE gute Idee, da es sich möglicherweise um ein sich bewegendes Objekt handelt und das Erstellen einer neuen Karte für jeden Frame nicht angenehm ist Lebenserfahrung. Die beste Lösung ist meiner Meinung nach eine Mischung: Entfernungsberechnung für bestimmte Lichter, die tatsächlich Objekte im Spiel sind, ein separater Shader, den Sie einfach auf die Alpha-Karte werfen, die Sie prozedural mithilfe der oben genannten Technik generiert haben: eine Textur von allen Die Kacheln alphas von Ihrer harten Schattierung, als viele Quadrate, und spielen mit Techniken herum, um es zu glätten.
quelle
Verwendet Ihr Rendering Scheitelpunktfarben (oder können Sie diese ändern)?
Angenommen, jeder Block ist ein Quadrat mit 4 Scheitelpunkten, das Ihnen einige Optionen bietet, zum Beispiel:
Wenn Ihr aktueller Beleuchtungsalgorithmus einen Lichtwert pro Block anzeigt, können Sie diesen ändern, um einen Wert pro Scheitelpunkt zu erhalten. Alternativ können Sie an jedem Scheitelpunkt die helle Farbe des aktuellen Blocks plus seiner drei Nachbarn mitteln. Jede Lösung wäre kostengünstig.
quelle