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:
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?
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:
- Was ist mit einer "Himmelskurve"? Hier ist ein Bild, das zeigt, was ich meine:
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: