Kategorien
OpenClonk

OpenClonk: Parallaxes Scrollen und Zoom

Clonk unterstützt parallaxe Objekte und Hintergründe schon eine Weile. Parallaxes Scrollen ist eine Methode, um einen 3D-Effekt allein mit 2D-Methoden zu imitieren, indem Objekte langsamer oder schneller bewegt werden wenn die imaginäre Kamera über die Landschaft bewegt wird. Dieser Ansatz funktioniert allgemein gut, aber bei geänderter Zoom-Stufe sahen seine Auswirkungen etwas ungünstig aus. Anstatt bei Zoom parallaxe Objekte und Hintergründe einfach genauso aussehen zu lassen wie die anderen Objekte, haben Clonk-Karl und ich ausgetüftelt wie sie sich verhalten würden, wären sie tatsächlich vor oder hinter der Landschaft. Die erste Frage, die es zu beantworten galt war, was verschiedene Zoom-Stufen in der virtuellen Welt darstellen: Ändert sich der Abstand zwischen Kamera und Landschaft, oder verstellt sich die Kameraoptik wie bei einem Zoom-Objektiv? Letztendlich kamen wir zu dem Schluss, dass wir beides benötigten: Das Zoom-Objektiv, damit jeder Spieler ungefähr das selbe Bild sieht, unabhängig von der Pixelzahl seines Monitors, und die Distanzänderung um Zoom darzustellen. Während Zoom im echten Leben ein Zoom-Objektiv nutzt, ist dies bei echten, unmodifizierten Menschen nicht der Fall, demnach müsste sich die Distanzänderung natürlicher anfühlen.

Danach war es ganz einfach, mit Hilfe eines Diagramms herzuleiten wie die Objekte dargestellt werden sollen. Man setze einen Punkt für die Kamera, eine Linie für die Landschaft und den Bildschirm (denn sie ist immer auf der selben Ebene wie der Bildschirm. Der Bildschirm sorgt dafür, dass Himmelsinseln nicht abstürzen), und noch eine Linie für das Objekt. Dann zeichne man Linien von den Ecken des Objektes zur Kamera. Das Objekt sollte dann dort angezeigt werden, wo diese Linien den Bildschirm schneiden. Allerdings brauchten wir mehrere Durchgänge dafür, dies in die Formeln zu fassen die in der Engine verwendet werden, weil wir noch nicht völlig verinnerlicht hatten was die gegebenen Werte bedeuten. So bezeichnet die Position eines Objektes nicht den Punkt, an dem sich das Objekt in der virtuellen Welt befindet, sondern wo es in der Landschaft angezeigt wird wenn sich die Kamera an Position 0/0 befindet und der Zoomfaktor 1 ist. Und die Kamera ist an dieser Position wenn die linke obere Ecke des Bildschirms dort ist. Das ist so, als ob nur das rechte untere Viertel der Kamerasicht angezeigt würde. Der Grund ist, dass die Parallax-Berechnungen dadurch recht nett rauskommen: Beim umsetzen von Landschafts- auf Bildschirm-Koordinaten, wird einfach die Position der oberen linken Bildschirm-Ecke mit dem Parallax-Faktor multipliziert, und von der Objektposition abgezogen. Unsere ersten Diagramme hatten aber noch die Kameraposition in der Mitte des Bildschirms, was etwas verwirrend war, da dadurch die Bildschirmgröße in den Formeln auftaucht. Wir wussten aber, dass dies im Engine-Code nicht der Fall war.

Schließlich gelangten wir zu Formeln, die wir für korrekt hielten, und bauten sie in die Engine ein. Das Ergebnis war größtenteils zufriedenstellend, besonders der Himmel verhielt sich nett. Aber manche Objekte bewegten sich auf dem Bildschirm umher, wenn man den Zoomfaktor änderte, während sie sich wie erwartet bewegten wenn man nur die Kamera umher bewegte. Ich entdeckte schließlich den Grund dafür, als ich folgendes Diagramm ein paar Tage später konstruierte:

Diagramm zur Parallaxe

Das Diagramm zeigt eine Seitenansicht von Kamera, Landschaft, und einem Objekt. Da die Formeln für X und Y unabhängig voneinander und identisch sind, wird hier nur eine Dimension dargestellt.

Die schwarzen Abstände sind gegeben, die roten sind die, die wir berechnen wollen. Die grünen sind Zwischenergebnisse. Die gestrichelten Linien sind die Sichtlinien zwischen Kamera und Objekt.

In der oberen linken Ecke des Diagrammes befindet sich die Kamera, die die internen Objekt-Positionen definiert: Die Position eines Objektes ist dort, wo diese Kamera das Objekt in der Landschaft sehen würde. Etwas weiter rechts ist eine Kamera an Position 0/0, aber mit einem anderen Zoomfaktor (genannt „Zoom“). Unsere erste Version verwechselte diese Kamera mit der erstgenannten. Für Objekte an Position 0/0 macht das keinen Unterschied, was auch erklärt warum der Himmel richtig funktionierte: Wir testeten nur in einem Szenario, in dem sich der Himmel nicht mit dem Wind mitbewegte.

Unterhalb der zweiten Kamera ist die dritte, die, für die die Berechnungen gemacht werden sollen. Sie hat einen Abstand „TargetX“ vom Ursprung, und einen Zoomfaktor „Zoom“, wie die zweite Kamera.

Rechts ist das Objekt, das dargestellt werden soll. Es ist hinter der Landschaft, aber glücklicherweise funktionieren die Formeln genauso gut für Objekte vor der Landschaft. Sein Abstand zur ersten Kamera auf der Z-Achse ist „1/Par“, wobei „Par“ der Parallax-Faktor ist. Folglich ist der Abstand zur Landschaft „1/Par-1“, weil die erste Kamera den Abstand „1“ zur Landschaft hat. Die Position in der virtuellen Welt auf der X-Achse ist „VX“.

Sobald ich dieses Diagramm hatte, war die Berechnung des Ergebnisses eine simple Anwendung des Strahlensatzes. Diejenigen, die am Ergebnis interessiert sind, können einen Blick auf die Funktion C4Object::GetDrawPosition() in der Engine werfen.

Ursprünglicher Artikel von Günther, Stand: 12. Oktober 2010

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert