Diffuses Licht / Schatten

9

Ich habe gerade ein Lichtsystem in meinem Motor eingebaut. Im folgenden Screenshot sehen Sie ein Licht (das gelbe Quadrat) in Aktion:

Berücksichtigen Sie, dass neben dem Licht, das das Szenario beleuchtet, auch ein FOV implementiert wurde, das alles außerhalb Ihres Sichtfelds verdeckt. Deshalb scheint der linke Teil des Schattens so aus.

Wie Sie sehen können, sind die Schatten des Lichts ziemlich "hart", da sie nicht einmal ein Stück außerhalb der direkten Reichweite beleuchten. Um die Lichter besser aussehen zu lassen, habe ich einen Filter auf sie angewendet, der die zu beleuchtende Reichweite ziemlich begrenzt und auch den Bereich innerhalb dieser Grenze leicht beleuchtet:

Im großen gelben Kreis können Sie sehen, wie der Bereich beleuchtet ist, auch wenn kein direktes Licht darauf trifft.

Diese Lösung hat jedoch einige unerwünschte Nebenwirkungen. Wie Sie im folgenden Screenshot sehen können, wird, selbst wenn kein Licht einen Bereich erreicht, es beleuchtet, wenn es zu nahe an der Lichtquelle ist:

Ich habe mich gefragt, ob es irgendeinen Weg gibt zu erreichen, was ich versuche, indem ich Shader richtig benutze. Das Hauptproblem, auf das ich stoße, kommt daher, wie ich diese Schatten zeichne.

1) Zuerst nehme ich die Strukturen innerhalb der Reichweite des Lichts.

An dieser Stelle arbeite ich mit Vertex, da sie den Bereich der Schattenwurfobjekte definieren:

2) Dann berechne ich für jedes dieser Objekte den Schatten, den sie einzeln werfen:

Der Schatten, den sie werfen, wird von der CPU ausgeführt, indem sie Projektionen für jeden Scheitelpunkt des Körpers berechnet.

3) Dann zeichnet die GPU diese Formen in eine Textur, um den endgültigen Schatten zu erstellen:

Das Problem, das ich finde, ist, dass ich den letzten Schatten brauche, um diesen diffusen Schatteneffekt zu machen. Wenn ich die diffusen Schatten in Schritt 2) berechnen würde, würde zwischen den Festkörpern B und C eine Lichtlücke entstehen.

Aber wenn ich die Schatten in Schritt 3 diffundiere, habe ich nicht mehr die Scheitelpunktinformationen, da alle Informationen, die ich habe, die 3 lokalen Texturen sind, die in einer endgültigen Textur zusammengefügt werden.

Also, gibt es das irgendwie, um das zu erreichen? Meine erste Idee wäre, eine Variation an den Fragmentierer zu übergeben, um zu berechnen, wie viel Licht in den dunklen Bereich kommt, aber da ich diese Informationen über den letzten Schatten verarbeite, der keine Vertex-Informationen hat, bin ich völlig verloren Ansatz sollte ich verwenden, um dies zu machen.

Ich könnte bei diesem Ansatz völlig falsch liegen, da ich sehr wenig Erfahrung mit Shadern habe.

Hier ist ein Beispiel von dem, was ich gerade habe und was ich begehre: Was ich habe: Einfache Beleuchtung mit dem Lichtradius (wodurch das Licht Wände durchtrennt).

Was ich will: Der Schatten ist umso intensiver, je weiter er vom Licht entfernt ist.

    
Leo 19.03.2014, 15:33
quelle

1 Antwort

1

Ich denke, egal, was Sie tun, müssen Sie den Lichtabfall für die Bereiche der Szene, die keine direkte Sichtbarkeit auf die ursprüngliche Lichtquelle haben, anders berechnen. Ich bin mir nicht sicher, wie Sie das Shadow-Volume tatsächlich auf die Szene anwenden, aber Sie können möglicherweise etwas wie die Kanten klassifizieren, während Sie das Schattenvolumen erzeugen (dh wenn sie von einer Wand oder von der Linie kommen) vom Licht in eine Ecke?) und behandle sie entsprechend.

Kurz gesagt, ich glaube nicht, dass es einen cleveren Shader-spezifischen Trick gibt, den Sie ausführen können, um dieses Problem zu beheben. Es ist eine Einschränkung des von Ihnen verwendeten Algorithmus. Daher müssen Sie den Algorithmus verbessern, um die unterschiedlichen Eigenschaften der Kanten in Ihrem Schattenvolumen zu berücksichtigen.

--- Bearbeiten ---

Ok, ich denke, es wird am besten sein, zwei Schatten-Volumes (oder besser Schattenbereiche, da wir in 2D arbeiten) zu erstellen. Einer wird genau so sein, wie Sie jetzt haben, der andere wird kleiner sein - Sie sollten die Bereiche ausschließen, die sich in "weichem" Schatten befinden. Dann haben Sie drei Kategorien in Ihrem Fragment-Shader: Total Shadow, Soft Shadow und Unshadowed.

Um die zweite Shadow Map zu erstellen, denke ich, dass Sie etwas wie einen festen Winkel zu den Kanten hinzufügen möchten, die durch das um eine Ecke leuchtende Licht erzeugt werden.

--- Bearbeiten # 2 ---

Ich denke, Sie können das Problem der Lücke zwischen den Objekten B und C lösen, indem Sie die Silhouette der Schattenbereiche und die äußere Box der Szene verwenden. Für jeden Ihrer Schattenbereiche würden Sie also die zwei äußersten Punkte finden, die die äußere Box schneiden, dann alle dazwischen liegenden Liniensegmente auswerfen und sie durch diesen Teil der Box ersetzen. Ich denke, ich sollte diesen Algorithmus benennen können, aber er entgeht mir im Moment ...

Originalszene:

Einzelne "harte" Schatten: Einzelne "harte" Schatten

Vereinigt nun die Schatten zusammen:

Schließe schließlich die Schatten ab und bleibe dabei an den Rändern der Box. Die Ecken, die Sie identifizieren möchten, sind die in Gelb. Während Sie den Schattenrand umfahren, möchten Sie über den Rand der Kiste schneiden, bis Sie die gegenüberliegende Ecke erreichen. Nicht die einfachste Sache zu programmieren, aber wenn du so weit gekommen bist, denke ich, dass du es herausfinden kannst:)

Alternativ könnte es einfacher sein, einfach die beleuchteten Bereiche zu betrachten. Zum Beispiel könntest du etwas wie den Unterschied zwischen der Szenebox und dem unionierten schattierten Bereich machen. Dies wird dir normalerweise mehrere Polygone geben; verwerfe alles außer demjenigen, der das Licht enthält, denn der Rest sind die falschen Lücken.

    
Nathan Monteleone 19.03.2014 21:21
quelle