Wie erreicht man Licht, das auf halbem Weg seine Farbe ändert?


11

Ich dachte daran, Lichtquellen und einige farbige Fenster zu schaffen. Jetzt sind die Fenster halbtransparent. Wie könnte ich es so machen, dass wenn das Licht (z. B. reines Weiß) auf das Glas trifft und durch dieses hindurchgeht, aber die Farbe in die gleiche Farbe ändert wie das Glas, durch das es hindurchgegangen ist?

Ich weiß, dass der hier beschriebene Effekt durch die Verwendung von Flächenlichtern auf der "farbigen" Seite des Fensters gefälscht werden kann, aber was ist, wenn ich nur ein weißes Punktlicht haben möchte?


Könnten Sie, anstatt die Farbe des Lichts zu ändern, die Grundfarbe der beleuchteten Objekte auf der anderen Seite des Glases ändern? Vielleicht würde das den Trick machen?
HumanCatfood

Das transparente Fenster wird als zweiter Durchgang gerendert. Der Shader ändert einfach die Farbbalance jeder Pixelausgabe. Würde das nicht funktionieren?
Patrick Hughes

Es scheint mir, dass dies analog zum Problem der Schatten ist; Wenn Sie einen netten Algorithmus für Schatten haben, die von halbtransparenten Objekten geworfen werden (ich weiß nicht, ob das praktisch ist), müssen Sie ihn nur für drei parallele Farbkanäle ausführen.
Kevin Reid

Antworten:


14

Es gibt eine Vielzahl von Möglichkeiten, dies zu tun. Dies erfordert die Verwendung eines Shaders, und ich gehe davon aus, dass Sie bereits eine Beleuchtung pro Pixel durchführen. Im Folgenden finden Sie einige Vorschläge. Um die für Sie geeignete Technik zu finden, ist jedoch möglicherweise viel mehr Forschung erforderlich.

Schnell und dreckig

Sie können Begrenzungsrahmen angeben, die Innenbereiche definieren. Befindet sich das Licht außerhalb der Boxen, aber die Geometrie (die nicht im Schatten liegt) innerhalb der Box, muss das Licht durch ein Fenster beeinflusst worden sein (dies gilt auch, wenn sich die Geometrie außerhalb der Box und des Lichts befindet ist drinnen). Das einzige Problem hierbei ist, wie die Box-Informationen an den Shader übergeben werden und wie die Auswirkung auf das Licht angegeben wird.

Eine andere Möglichkeit besteht darin, Fenster als Objekte anzugeben, die auf Ebenen liegen. Testen Sie zunächst, ob sich die Geometrie und das Licht auf gegenüberliegenden Seiten der Ebene befinden und ob der Weg zwischen ihnen die Ebene an einem Punkt innerhalb der Fenstergrenzen schneidet. Dies wäre genauer als die erste Methode und es wäre einfacher, Fenster in denselben Innenräumen mit unterschiedlichen Glasfarben zu haben.

Mit der geometrischen Darstellung der Fenster werden Sie immer detaillierter und Sie erhalten genauere Ergebnisse, aber die Berechnung wird auch schwerer.

Diese Techniken würden für einen Korridor-Shooter ziemlich gut funktionieren, aber für eine dynamische oder offene Welt nicht so gut, da wahrscheinlich viele Anpassungen erforderlich wären, um sie ohne zu viele Artefakte richtig aussehen zu lassen. Außerdem könnten diese Techniken schnell etwas intensiver werden, weshalb ein Wechsel zu einer verzögerten Schattierungspipeline empfohlen wird.

Schattenkarten

Eine andere Möglichkeit besteht darin, etwas Ähnliches wie die Schattenzuordnung zu tun.

In der Schattenzuordnung erzeugen Sie ein Bitmap-Bild der Welt, die von einem Licht betroffen ist. Jedes Pixel ist zwar immer noch eine Farbe, aber tatsächlich der Abstand des nächsten nicht transparenten Teils der Geometrie (Sie verwenden die vier Bytes für 1 Float anstelle von 4 Farben). Wenn Sie den Abstand vom Licht zu einem Geometrieteil berechnen und dieser über dem entsprechenden Wert in der Schattenkarte liegt, befindet sich Ihr Geometrieteil im Schatten (Sie verwenden im Allgemeinen den Strahl zwischen der Geometrie und dem Licht, um die Karte zu indizieren).

Wenn Sie diese Idee auf Ihr Problem anwenden, speichern Sie eine Karte der Entfernung vom Licht des nächsten transparenten Geometriestücks und erstellen nach dem Durchlaufen dieser Geometrie eine zweite Karte der Lichtfarbe ( einfach die Farbe der Geometrie, wenn das Licht weiß ist).

Wenn Ihr Geometrieteil weiter entfernt ist als der Abstand in dieser Karte, verwenden Sie die Kartenfarbe. Wenn dies nicht der Fall ist, verwenden Sie die ursprüngliche Lichtfarbe.

Die Funktion zum Berechnen der Farbe für jedes Pixel in der Karte sollte ungefähr lauten. lightColor - invertedWindowColor. Also für ein rein weißes Licht und ein rein rotes Fenster, das nichts von dem roten Spektrum absorbiert, das wir bekommen; (255,255,255) - (0,255,255) = (255,0,0). Die Lichtfarbe auf der anderen Seite ist also rein rot. Für ein komplexeres transparentes Objekt, z. B. ein Buntglasfenster, möchten Sie möglicherweise eine Textur-Suche durchführen, um die Materialfarbe zu erhalten.

Wenn Sie nach etwas Ähnlichem suchen, schauen Sie sich Reflective Shadow Maps an .

Diese Technik bietet ein hohes Maß an Wiedergabetreue und ist möglicherweise die beste, wenn Sie komplexe transparente Geometrien wie Buntglasfenster verwenden möchten.

Versuch einer allgemeinen Lösung

In letzter Zeit ist es populär geworden, Beleuchtungsinformationen in einer Voxeldarstellung zu codieren (sie dienen nicht nur der Geometrie). Die neueste Crytek-Engine verwendet diese Art von Strategie für fortschrittliche Beleuchtung ( Lichtausbreitungsvolumen ).

Hier ist die allgemeine Idee:

  • Erstellen Sie eine Karte mit gleichmäßig verteilten Würfeln, die Ihre Szene umfasst (verwenden Sie möglicherweise Kurven in Z-Reihenfolge ).
  • Finden Sie eine Möglichkeit, Informationen zur einfallenden Beleuchtung für jedes Voxel zu speichern (sphärische harmonische Darstellungen sind hier hilfreich).
  • Finden Sie das Voxel, das ein Licht enthält, und stellen Sie dieses Licht im Voxel dar.
    • Verbreiten Sie das Licht nach außen durch die angrenzenden Voxel (ähnlich wie Minecraft-Wasser)
    • Berechnen Sie, wie sich die Geometrie in jedem Voxel auf das durch ihn hindurchtretende Licht auswirkt (absorbieren, reflektieren, durchlassen).
    • Wiederholen, bis das Licht verblasst ist

Es gibt viele Möglichkeiten, diese Voxelinformationen zu erstellen, aber die obige Liste gibt eine allgemeine Vorstellung. Beispielsweise; Sie können beginnen, indem Sie Schattenkarten / -volumina generieren und diese Informationen dann in die Voxelkarte projizieren, damit Sie schnell eine Karte mit direkter Beleuchtung erstellen können. Dann starten Sie die Ausbreitung von den Voxeln entlang der Kante des betroffenen Bereichs. Beachten Sie, dass Sie in diesem Fall beim Generieren der Schattenkarte / des Schattenvolumens ignorieren möchten, ob die Geometrie transparent ist oder nicht.

Im letzten Durchgang eines verzögerten Renderers verwenden Sie bei der Berechnung der Beleuchtung eines Geometriepunkts einfach die Geometrieposition, um Ihre Voxelkarte zu indizieren und herauszufinden, wie die einfallende Beleuchtung an diesem Punkt im Raum aussieht. Anschließend können Sie eine Bildschirmkarte der CPU-Seite für einfallende Beleuchtung erstellen oder dies möglicherweise mit cuda tun.


Danke für den langen Beitrag! Ich untersuche derzeit, ob ich für das aktuelle Projekt, an dem ich arbeite, vorwärts oder verzögert rendern werde. Im Moment wird es wahrscheinlich verschoben. Wie würden Sie vorgehen, wenn das Fenster mehrfarbig ist (z. B. ein Buntglas in einer Kirche)?
Manabreak

@manabreak - Ich würde die Schattenkartenerweiterung verwenden, da sie für diesen Fall die beste Wiedergabetreue bietet. Ich werde den Beitrag bearbeiten, um dies zu erklären.
OriginalDaemon

Boah, danke! Dieser Beitrag hat mir wirklich den Tag gemacht, ich habe wahrscheinlich noch nie so viel Mühe in einen einzelnen Beitrag gesteckt.
Manabreak
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.