Wie erstelle ich einen 2.5d-Parallaxeeffekt?

8

Ich habe einen anständigen Hintergrund in 3D-Grafik und Programmierung, aber ich bin neu in der Spieleentwicklung. Ich erkunde gerade verschiedene Möglichkeiten und möchte wirklich ein RPG-Spiel machen. Ich habe über die klassische isometrische 2D-Ansicht nachgedacht, aber ich liebe es wirklich, wie Diablo 2 aussieht und sich anfühlt, um zu spielen.

Meine Frage ist: Wie kann ich den Parallaxeeffekt von Diablo 2 erzielen ? Alles sieht von Hand gezeichnet mit gebackenen Lichtern und Schatten aus und sieht fantastisch aus, aber wenn Sie sich bewegen, bemerken Sie eine Perspektive .

Nehmen wir zum Beispiel an, ich habe in Photoshop eine große Halle mit Spalten mit einer orthografischen Perspektive gezeichnet (klassischer Pixelkunststil, nur parallele Linien). Wie würde ich dieser Szene einen Parallaxeeffekt verleihen , wenn sich der Charakter bewegt? Wenn ich für alles Sprites mit Blick auf die Kamera verwende, sieht es in der Ferne wahrscheinlich in Ordnung aus, aber es wäre wirklich falsch, wenn sich ein Zeichen beispielsweise einer Spalte (einem Zylinder) nähert.

Irgendwelche Vorschläge? Wie hat Blizzard den Parallaxeeffekt in Diablo 2 erzielt?

Siehe diesen Screenshot: http://guidesmedia.ign.com/guides/10629/images/act2tombs.jpg

Nikolay Dyankov
quelle
Es ist eine Kamera im RTS-Stil. google.com/#q=rts+game+camera
LiquidFeline
1
Ich habe nicht nach der Kamera gefragt, es ist eine perspektivische Kamera in einem bestimmten Winkel vom Boden, das ist offensichtlich. Meine Frage betraf die Umwelt und wie die Perspektive funktioniert.
Nikolay Dyankov
1
AoE ist kein Duplikat und hat keinen Parallaxeeffekt. Bitte nehmen Sie sich Zeit, um meine ganze Frage noch einmal zu lesen.
Nikolay Dyankov
1
Bitte hören Sie auf, Ihre Nase in diese Frage zu stecken, wenn Sie keine Antwort haben. Sie verstehen die Frage eindeutig nicht, hören Sie also auf, sie zu bearbeiten!
Nikolay Dyankov
2
Wer ist der Idiot, der das abgelehnt hat? Einige Leute auf dieser Seite haben wirklich keine Ahnung! Nur jemand, der nie Diablo II gespielt hat, hätte abstimmen können, nehme ich an!
Ingenieur

Antworten:

5

Dies ist eine lange Antwort, aber tatsächlich ist die Grundvoraussetzung von Divide-by-Camera-Z sehr einfach: Je weiter etwas von Ihnen entfernt ist, desto kleiner erscheint es. Auch die kleineren Abstände zwischen zwei Dingen erscheinen.

Positionen (Nicht erforderlich, wenn Sie Unity verwenden!)

Zunächst müssen Sie Positionen / Punkte mit der richtigen Perspektive rendern.

Die Positionen liegen auf einer flachen Ebene. Sie möchten so etwas wie das Bild rechts ... betrachten Sie die Ecken der Kacheln als Beispielpunkte / -positionen.Geben Sie hier die Bildbeschreibung ein

So nähern Sie sich der Transformation von Punkten:

  • Ihr Koordinatensystem ist wie folgt: Positiv zläuft in den Bildschirm, xläuft von links nach rechts und yläuft nach unten. Kamera z ist Welt z. Das ist die Verknüpfung, die dies viel einfacher macht als das Schreiben einer vollständigen 3D-Engine. Nachteil? Die Kamera kann die Ausrichtung nicht ändern (obwohl sie die Position ändern kann).
  • Speichern Sie die ursprüngliche 3D-Position Ihrer Kamera. Setzen Sie es etwas zurück (minus z) vom Ursprung der Welt.
  • Speichern Sie eine Sammlung von 3D-Punkten in der xz-Ebene (geben Sie sie an y=0). Versuchen Sie , sie auf der ganzen Welt Ursprung zentriert in x, (0,0,0)dh von negativ nzu positiv n. Dies dient dazu, sie im Ansichtsfenster zu zentrieren, wenn das Rendern beginnt.
  • Betrachten Sie den Ursprung des Verkleinerungspunkts / Pixelplots als die Mitte des Bildschirms.
  • Legen Sie einen Abstand von der Kamera fest, in dem 1 Weltraumeinheit = 1 Pixel ist. Das heißt, wenn Sie die Kamera nur um eine Weltraumeinheit bewegen, wird jedes Objekt, das 10 Einheiten entfernt ist, nur um 1 Pixel verschoben - ziemlich weit! Speichern Sie diesen Abstand als Konstante K.
  • Rendern Sie nun für jeden Punkt an einer Position mit der folgenden Formel: screenPosition(x,y) = screenOrigin + (worldPosition(x,y) - cameraPosition(x,y)) / ((worldPosition(z) - cameraPosition(z)) * K)... Wie Sie sehen können, basiert die Renderposition auf dem zAbstand zwischen dem aktuellen Punkt und der Kamera.

  • Spielen Sie mit der Z-Position der Kamera, bis Sie Punkte sehen, die gerendert werden. Sie werden jedoch sehen, dass alle Punkte auf der Mittellinie des Bildschirms angezeigt werden. Also müssen wir Abhilfe schaffen. Versuchen Sie K=1vs. K=10, um den Unterschied zu sehen.

  • Sie können die Kamera jetzt nach innen bewegen, um yzu sehen, wie sich Ihre Kamera über und unter der Ebene der Punkte befindet (dh die Punkte werden perspektivisch korrekt unter oder über der Mittellinie des Bildschirms gerendert, wenn Sie die Kamera nach oben und unten bewegen ).

Dies sind sehr grobe Richtlinien. Es gibt verschiedene Implementierungsdetails, die Ihnen überlassen bleiben. Der erste Schritt besteht darin, etwas anzuzeigen und von dort aus zu ändern. Ein Detail, das Ihnen in den Sinn kommt, ist, dass Sie, wenn Sie möchten, dass die Kamera eher so aussieht, als würde sie auf den Boden blicken, Ihren Rendering-Ursprung nach oben und näher an den oberen Rand des Ansichtsfensters verschieben müssen. Ein weiteres Detail ist, dass Ihre Entfernung zwischen Kamera und Punkt möglicherweise ein Trigger-Verhältnis enthalten muss ... Ich denke, die Verwendung tanbietet eine realistischere Perspektive. Erinnern Sie sich nicht genau daran, aber Sie werden schnell sehen, ob die Perspektive seltsam aussieht und sich entsprechend anpassen kann. Ich kann nicht genauer sein, ohne ein Beispiel neu zu schreiben.

Verziehen und Skalieren pro Werbetafel (erforderlich)

Jetzt, da Sie die Perspektive unter Ihren Punktpositionen sehen und Positionen (wie bei Zeichen) nach Belieben hinzufügen, entfernen oder verschieben können, müssen Sie auch die Perspektive auf die einzelnen Sprites anwenden, die an diesen Positionen verwurzelt sind.

In D2 schien es mir immer eine einfache seitliche Warp-Funktion zu sein, die mehr auf die Werbetafeln am unteren Bildschirmrand als auf die oberen angewendet wird, und auch mehr, wenn Sie sich weiter von der nach unten laufenden Mittellinie entfernen der Bildschirm.

Möglicherweise werden auch die Werbetafeln vertikal skaliert, z. Bäume werden im Vergleich zu ihrer erwarteten Größe kürzer, näher am unteren Bildschirmrand (damit es so aussieht, als ob die Kamera auf die Bäume herabblickt - ich fand, dass Tristrams Bäume der beste Weg sind, dies sicher zu erkunden, damals in der Tag ;) ).

Was ich tun würde ist:

  1. Bewältigen Sie die grundlegende Skalierungsfunktion basierend auf der Entfernung von Kamera zu Boden an verschiedenen Punkten. Sie hätten also eine ähnliche Skalierung für jede Scanlinie.
  2. Erst nachdem ich das getan hatte, würde ich mir die seitliche Verzerrung ansehen - zuerst basierend auf dem Abstand von der Mittellinie, die über den Bildschirm läuft.
  3. Zuletzt würde ich untersuchen, wie diese seitliche Verzerrung durch die Entfernung auf dem Bildschirm beeinflusst wird (und ich habe das Gefühl, dass ein einfaches Triggerverhältnis das Herzstück davon sein würde).

Perspektivisch korrekte Kacheln (Nicht erforderlich, wenn Sie Unity verwenden!)

Das Obige gibt Ihnen hoffentlich korrekt positionierte, verzogene "Stand-up" -Sprites (dh Objekte, die senkrecht zur Grundebene sitzen, wie Charaktere, Bäume, Häuser).

Sie müssen jedoch auch überlegen, wie sich die Bodenfliesen korrekt und nahtlos verformen lassen. Und ich denke, Sie werden feststellen, dass dies der Teil ist, für den insbesondere eine GPU auf D2 erforderlich war. Ich erinnere mich, dass auf Systemen ohne GPU die Perspektivoption deaktiviert war. Der Grund dafür wäre mit ziemlicher Sicherheit gewesen, dass die GPU eine Texturoberfläche aufnehmen und sehr schnell eine perspektivische Korrektur darauf anwenden kann, ohne Störungen zwischen den Kacheln und ohne Bedenken hinsichtlich der Durchführung nicht affiner Transformationen im Anwendungscode, die einige Matrixmathematik beinhalten und kann ein bisschen teuer sein:

Geben Sie hier die Bildbeschreibung ein

Ich habe ein paar Vorschläge für Sie, um damit umzugehen:

  • (Einheit) Verwenden Sie eine Einheitskamera, um das Rendering der flachen, strukturierten Grundebene bereitzustellen, und behandeln Sie die Verzerrungen der Werbetafeln separat basierend auf den Positionen des Bildschirmbereichs.
  • Führen Sie diese Logik (oder sogar die gesamte Renderlogik) in GPU-Shadern aus.
  • Verwenden Sie überhaupt keine Bodenfliesen. Verwenden Sie stattdessen einfach Punkt-Sprites - genau wie die Zeichen selbst - auf einer einheitlich gefärbten Ebene (z. B. Grün für Gras), um Details bereitzustellen, damit diese Ebene nicht langweilig aussieht. Dies erhöht Ihre Rendering-Kosten, ist jedoch sicherlich der einfachste Weg, um dieses Problem zu lösen.
Ingenieur
quelle
Leider war das einzige, was ich verstand, "vertikale Skalierung". Vielleicht sollte ich mich vorerst an isometrisches 2D halten.
Nikolay Dyankov
Ok, lassen Sie mich meine Frage vereinfachen, wie würden Sie einen 2d gezeichneten Zylinder 3d aussehen lassen? So etwas gezeichnet - media.web.britannica.com/eb-media/49/63049-004-C560D293.gif
Nikolay
Darauf gibt es keine Perspektive. Möchten Sie im Chat diskutieren?
Ingenieur
Klar, bitte starte den Chat, ich weiß nicht wie :)
Nikolay Dyankov
^ Seitenanfang ^
Ingenieur