Atmosphärische Streuung und Himmelsgeometrie

7

Ich versuche, eine atmosphärische Streuung in meiner Grafik- (Spiel-) Engine basierend auf dem GPU Gems-Artikel zu implementieren: Link . Eine Beispielimplementierung aus diesem Artikel verwendet einen Skydome. Meine Szene ist anders - ich rendere nicht eine ganze Erde mit einer Atmosphäre, die auch vom Raum aus sichtbar ist, sondern einen endlichen flachen (rechteckigen) Bereich mit Objekten, zum Beispiel einer Rennstrecke. Tatsächlich ist dies das häufigste Szenario in vielen Spielen. Jetzt frage ich mich, wie man in einem solchen Fall einen Himmel rendert:

  1. Welche Art von Geometrie sollte ich verwenden: Skydome, Skybox oder ein Vollbild-Quad - dann muss ich fast alle Berechnungen auf den Fragment-Shader verschieben, aber ich weiß nicht, ob dies in Bezug auf Qualität / Leistung sinnvoll ist?

  2. Wie platziere ich die Himmelsgeometrie auf der Szene? Meine Idee: Ich habe eine Halbkugelgeometrie (Skydome) mit Radius = 1 und Zentrum in vec3 (0, 0, 0) - im Objektraum. Diese Scheitelpunkte werden an den atmosphärischen Streuscheitel-Shader gesendet:

    Layout (Position = 0) in vec3 inPosition; Als nächstes transformiere ich im Vertex-Shader den Vertex folgendermaßen:

    v3Pos = inPosition * 0,25f + 10,0f; Uniform v3CameraPos = vec3 (0.0f, 10.0f, 0.0f), Uniform fInnerRadius = 10.0f, Uniform fCameraHeight = 10.0f

Dann habe ich einen inneren / äußeren Radius (10 / 10.25) korrigiert, oder? Ich sende dem Vertex-Shader auch eine Modellmatrix, die eine Position der Hemisphäre auf die Position der mobilen Kamera vec3 (myCamera.x, myCamera.y, myCamera.z) festlegt:

vec4 position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(inPosition, 1.0);
gl_Position = position.xyww; // always fails depth test.

Die Halbkugel bewegt sich zusammen mit der Kamera (umschließt nur einen Raum um die Kamera mit dem Radius = 1, aber es besteht auch immer ein Tiefentest nicht.)

Leider ist eine Himmelsfarbe, die ich bekomme, nicht korrekt:

Bildschirm1

  1. Was ist mit einer "Himmelskurve"? Hier ist ein Bild, das zeigt, was ich meine:

image1

Wie soll ich eine Himmelskurve einstellen?

Edit1 - Debugging: Im Vertex-Shader habe ich der v3Pos-Position des "höchsten" Vertex in der Hemisphäre zugewiesen:

vec3 v3Pos = vec3(0.0f, 10.25f, 0.0f);

Jetzt enthält der ganze Himmel eine Farbe dieses Scheitelpunkts: Screen2

Irbis
quelle
3
Ich denke, Ihre Frage geht zwischen dem Debuggen Ihres aktuellen Codes und Vorschlägen, was zu tun ist, verloren. Vielleicht hilft es Ihnen, Ihre Frage neu zu formulieren, um bessere Antworten zu erhalten.
Konzept3d

Antworten:

1

Sie müssen Ihre Optimierungswerte durch einheitliche Daten und nicht durch Scheitelpunktdaten übergeben.

Scheitelpunktdaten komplexisieren immer die Exportpipeline und die Bindung (Eingabesignatur).

Ich empfehle ein Bildschirmquad für die Stützgeometrie des Himmels und rendere es am Ende Ihres Rahmens, wenn alle anderen Objekte gerendert werden. Verwenden Sie dazu eine Tiefentestoperation, bei der alle Tests fehlschlagen sollen, sodass nur Ganzes gerendert werden. (Sie können dafür eine spezielle orthografische Kameramatrix verwenden, bei der Sie wissen, dass dies 1der tiefste Wert ist, und Sie stellen Ihr Bildschirm-Quad auf 0.99, um weites Abschneiden zu vermeiden, damit alle Tiefentests immer noch nicht bestanden werden.)

Dann ist die Leistung optimal, es handelt sich um eine klassische verzögerte Rendering-Technik. (leider mit den klassischen Antialiasing-Problemen, die wir kennen)

Sie können auch einen Skycube oder eine Skysphere verwenden. Unternehmen haben zufällig die drei oben beschriebenen Techniken verwendet, sodass es keine universelle Antwort gibt.

v.oddou
quelle
Alle Abstimmwerte werden durch einheitliche Daten geleitet. Sie irren sich über eine Himmelsgeometrie für diesen Streualgorithmus. Siehe hier: gamedev.net/topic/…
Irbis
0

Ich habe nicht persönlich an diesem Problem gearbeitet, daher habe ich wahrscheinlich viele Nuancen übersehen, aber ich habe ein Projekt geleitet, in dem wir genau diese Art von Streumodell implementiert haben. Wir haben dies tatsächlich zweimal gemacht, einmal für eine vorwärts gerenderte Pipeline und erneut für eine verzögerte Beleuchtungspipeline. In beiden Fällen haben wir alles im Bildschirmbereich mit den wenigen dynamischen Daten erledigt, die wir als Shader-Konstanten hochladen mussten, und die statischen Daten wurden vorberechnet und in 3D-Texturen codiert. Die Vorwärtsversion wurde als Nachbearbeitungsschritt ausgeführt (obwohl dies alle möglichen Kopfschmerzen verursachte, insbesondere das Beleuchten von Alpha-Polys, die nicht im Tiefenpuffer dargestellt waren). In der verzögerten Beleuchtungskonfiguration haben wir dies als Teil des Beleuchtungsdurchlaufs mit weitaus weniger Problemen durchgeführt.

Tut mir leid, dass ich ein bisschen vage bin, aber hoffentlich zumindest ein bisschen Hilfe.

Claude
quelle