Himmel

Autor: Florian Janosch

SkyDome

Im Gegensatz zu dem aus anderen Anwendungen und Spielen bekannten Konzept einer SkyBox oder eines SkyDomes, nutzen wir ein etwas anderes Konzept. Plantex nutzt Kugelkoordinaten, beschrieben durch die - aus der Vorlesung bekannten - Winkel Theta und Phi auf Basis eines Oktaeders, welcher die Welt umschließt. Die SkyBox wurde aus offensichtlichen Gründen der Ästhetik und dem Anspruch an den Himmel, als Konzept verworfen. Eine Sphäre, welche die Welt umschließt wurde nicht genutzt, da diese zu vielen Polygone und dem entsprechend Vertices hätte um performant bei jedem Shader-Aufruf berechnet zu werden.

Der Oktaeder, in Zukunft weiterhin als SkyDome bezeichnet, auch wenn es an den Vertices gemessen kein wirklicher Dome ist, beschränkt sich durch seinen Aufbau auf 6 Vertices mit insgesamt 8 Flächen. Durch diese 6 Vertices und einige Umrechnungen im Shader ist es möglich aus den kartesischen Interpolierten Koordinaten des Fragments welches gerade im Shader verarbeitet wird, die Winkel Theta und Phi zu berechnen und das Fragment auf Basis dieser zu färben und zu rendern.

Als Eckpunkte dieses SkyDomes wurden Punkte gewählt, welche automatisch immer gleich weit weg von der Kamera bzw. dem Spieler sind. Dies wird umgesetzt indem der Mittelpunkt des SkyDomes bei jedem Durchlauf seiner draw-function auf die Position der Kamera gesetzt wird.

pub fn draw_skydome<S: glium::Surface>(&self,
    surface: &mut surface: &mut S,
    camera: &Camera,
    daytime: &DayTime) {

    let pos = Point3::new(0.0, 0.0, 0.0);

    // skydome-octaeder position is set to camera position
    let view_matrix =
    Matrix4::look_at(pos, pos + camera.get_look_at_vector(), Vector3::unit_z());

Durch den Parameter SKYDOME_SIZE im Code ist es möglich einen Abstand der Eckpunkte zu definieren, sodass all diese eine gleich weite Entfernung von der Kamera haben. Dies ermöglicht es, dass der Himmel, auch bei der fortlaufend unendlich weit generierten Welt, immer so aussieht, als ob er unendlich weit weg ist und verhindert gleichzeitig das Erreichen eben dieses.

Diese Eckpunkte sind sich als Punkte auf der Oberfläche der durch dieses Oktaeder simulierten Kugel zu verstehen (wie in folgendem Bild veranschaulicht).

Oktaeder in Kugel

Farbe des Himmels

Die Farbe des Himmels hängt von der Sonnenposition ab, welche wiederum von der Tages- und Jahreszeit abhängt, auf die hier jedoch nicht weiter eingegangen wird, da diese in einem anderen Abschnitt dieser Dokumentation beschrieben wird.

Es gibt insgesamt vier verschiedene Hauptstadien in denen sich der Himmel befinden kann.

Sonnenaufgang

Sonnenaufgang

Der Sonnenaufgang beschreibt einen Verlauf von Rot über Gelb über ein helles Blau bis zu einem dunkleren Blau.

Der Sonnenaufgang bzw. -untergang wurde hier am Beispiel eines echten Bildes modelliert und es wurde versuch die verschiedenen Abschnitte des Himmels möglichst realitätsnah darzustellen. Dies geschieht über eine Fallunterscheidung, in welchem Bereich des Himmels sich das Fragment, Bezug nehmend auf den Winkel Theta befindet (also auf welcher Höhe des Himmels). Dann wird zwischen den beiden Grenzwerten dieses Abschnitts linear interpoliert. Ist all dies getan, wird abhängig von der Sonnenposition noch jeweils zwischen dem Sonnenaufgang bzw. dem Untergang und dem Tag bzw. der Nacht interpoliert.

Tag

Der Tag selber beschreibt einen Verlauf von einem dunklen Blau am Zenit zu einem helleren, weißlichen Blau am Horizont.

Sonnenuntergang

Sonnenuntergang

Der Sonnenuntergang ist grundsätzlich gleiche Verlauf wie der Sonnenaufgang, nur mit einem etwas anderen Start- und Endpunkt, korrespondierend zu der Position der Sonne, welcher durch zwei Parameter im Shader beeinflusst werden kann.

Nacht

Nachthimmel

Die Nacht liegt im Gegensatz zu den anderen Tageszeiten nicht in einem sehr erhöhten HDR Bereich sondern befindet sich als Farbe bei RGB (0.0, 0.0, 1.0), also noch im RGB-Spektrum, bei einer sehr dunklen Farbe. Dies gewährleistet, dass die weißen Sterne, die mit ihrer Farbe noch im RGB Spektrum liegen, am Tage von der Helligkeit des Himmels überstrahlt werden und kaum, beziehungsweise gar nicht sichtbar sind. Dadurch sind die Sterne erst in der Nacht, wie auch in der Realität, gut zu erkennen.

Dieser Übergang ist im folgenden Bild (ohne eine gerenderte Welt) deutlich sichtbar zu erkennen.

HDR Übergang bei Sternen

Der Shader selber interpoliert je nach Zeit, beziehungsweise der aus ihr errechneten Sonnenposition, zwischen den verschiedenen Stadien des Himmels um so einen gleichmäßigen Übergang zwischen diesen zu gewährleisten.

Sterne

Die Sterne werden über eine, aus einer open_simplex2-Noise generierten, Textur erstellt. Hierbei wird anhand dieser durch Noise generierten Textur, welche in einem anderen Kapitel dieser Dokumentation erklärt wird, im Fragment-Shader, abhängig von den berechneten Winkeln Theta und Phi, eine Position dieser generierten Textur abgefragt und je nach Wert des Punktes entschieden, ob an diesem Fragment ein Stern entstehen soll oder nicht.

Für eine realistische Darstellung der Sterne ist es erforderlich, eine Streckung der Sterne (beispielhaft im nachfolgenden Bild dargestellt) zu verhindern, welche sich durch das Mappen einer rechteckigen Noise-Textur auf einen sphärischen Körper normalerweise ergeben würde.

Sternenhimmel mit gestreckten Sternen

Des Weiteren muss verhindert werden, dass im Zenit des Himmels keinerlei Sterne sichtbar sind, da diese vom Spieler bzw. der Kamera deutlich weiter weg und daher zu klein sind um durch den Bildschirm darstellbar zu sein.

Daher wird im Shader die folgende Operation ausgeführt:

vec3 test = normalize(vec3(sin(theta)*cos(phi),sin(theta)*sin(phi),0));
    test *= theta;
    float star = texture(u_star_map, vec2(test.x, test.y)).r;

Diese Operation sorgt dafür, dass eine runde Fläche aus der Textur ausgewählt wird, die deutlich besser zu verwenden ist für die theoretischen Kugel, welche durch den Himmel beschrieben ist.

results matching ""

    No results matching ""