Ein doppelt so nahes Objekt erscheint doppelt so groß?

16

Deshalb habe ich überlegt, ein 2D-Spiel zu erstellen, bei dem Sie sich auch entlang der Z-Achse bewegen können, indem Sie die Ebene ändern, in der Sie sich befinden. Abhängig von der Tiefe möchte ich meine 2D-Sprites skalieren.

Einmal hatte mir jemand eine Demo gezeigt, in der er viele 2D-Sprites hatte, und durch Scrollen konnte er die Tiefe der Kamera ändern. Wenn Sie also hineinzoomen, nähern sich die Objekte dem Player und erscheinen größer. Dann habe ich mich gefragt, wie viel größer ein Objekt sein soll, wenn es 1 Einheit näher kommt. Wie würden Sie das berechnen? Also sagte der Typ zu mir: Es gibt eine Grundregel, die ich verwende: "Objekte, die doppelt so nah sind, erscheinen doppelt so groß."

Wenn ich es jetzt selbst teste, weiß ich, dass die Regel in der realen Welt nicht gilt;) Aber gibt es eine Konstante, die in Berechnungen der realen Welt für die Perspektive verwendet wird, oder so? Oder eine Formel?

Ich weiß, dass dies möglicherweise nicht der beste Ort ist, um eine solche Frage zu stellen, aber da dies die einzige Site ist, die ich für spielbezogene Fragen verwende, und mein Kontext ein Spiel ist, dachte ich, ich würde es versuchen. Außerdem erwarte ich, dass es hier jemanden gibt, der alles über 3D-Perspektiven und -Matrizen weiß, da es sich möglicherweise um 3D-Spiele handelt;)

tl; dr:

"Ein Objekt, das doppelt so nah ist, erscheint doppelt so groß" Das ist in der realen Welt nicht der Fall. Aber welche Konstante oder Formel ist richtig?

Beere
quelle
3
Ich habe keine Ahnung, was die Antwort ist, aber ich weiß, wie ich es herausfinden könnte. Mach ein paar Bilder von etwas. Vielleicht ein Stück Papier. Nehmen Sie sie aus verschiedenen bekannten Entfernungen und rechnen Sie dann aus, wie viel Bild das Blatt Papier einnimmt, und bestimmen Sie das Verhältnis. Könnte ein lustiges Experiment sein!
SpartanDonut
Ich frage mich, warum niemand etwas über natürliche Logarithmen erwähnt hat ...
Chad Harrison
4
Warum ist es nicht wahr? Ich denke es ist wahr.
Ivan Kuckir
@hydroparadise Was haben natürliche Logarithmen mit dieser Frage zu tun?
Nathan Reed
Ich bin hier nur pedantisch, aber "Zweimal so nah" ist eine seltsame Phrase. Sollte es nicht "halb so weit weg" sein? "Zweimal" ist größer, aber wenn etwas näher kommt, wird der Abstand kleiner.
MrVimes

Antworten:

19

Im Allgemeinen ist dies abhängig von Ihrem Blickwinkel und der Richtung, in die er sich bewegt hat.

Beispiel für Perspektiven für Objekte

Beachten Sie, dass in der ersten Kameraansicht das Objekt, da der rote Block senkrecht zur Kameraansicht steht, doppelt so groß zu sein scheint, und zwar in einem perfekten Verhältnis von 1: 2 (Beachten Sie den Pfeil, der darauf hinweist, dass es nach dem Verschieben auf den Rand der Ansicht trifft doppelt so nah)

Der zweite Block hat dieselbe Größe und ist um 45 Grad gedreht. Wenn es gedreht wird, befindet sich die Unterkante nicht mehr im gleichen Abstand von der Kamera wie die Oberkante. Sie wird daher nicht korrekt im Verhältnis 1: 2 skaliert, ist aber tatsächlich doppelt so groß (wie bei derselbe Winkel auf dem weiter entfernten blauen Block wie auf dem nahen blauen Block.)

Zusammenfassend bedeutet dies, dass Ihr Freund korrekt war und ein Verhältnis von 1: 1 ("Objekte doppelt so nah, erscheinen doppelt so groß.") Für Ihre Objekte eine gute Wahl ist.

Tom 'Blue' Piddock
quelle
Gute Antwort! Die Bilder machen es definitiv klarer. Eigentlich fühle ich mich jetzt wirklich dumm, da ich das versucht habe, bevor ich die Frage gestellt habe, indem ich meine Hand vor mein Gesicht gehalten und näher herangezogen habe. Und dann dachte ich: nein, es fühlt sich nicht doppelt so groß an ... ich hätte es genauer messen sollen;) Perspektive ist eine lustige Sache! Ich fühle mich auch so, als hätte ich mir die Bilder selbst einfallen lassen sollen;) Aber tolle Antwort! Vielen Dank!
Berry
@ Mason Wheeler - Sortiert: P
Tom 'Blue' Piddock
8

Ein doppelt so nahes Objekt erscheint doppelt so groß. Es ist eine Konsequenz von Thales 'Satz und es ist wahr in der realen Welt.

Man könnte argumentieren, dass Thales 'Theorem das zentrale mathematische Werkzeug für die perspektivische Projektion ist und das, was in der Grafik-Pipeline (OpenGL oder DirectX) als perspektivische Division bezeichnet wird . Es ist ein Satz, den Sie auf jeden Fall kennen und zu erkennen lernen sollten, wann er verwendet werden kann.

sam hocevar
quelle
Tolle Referenzen! Ich werde das Thales-Theorem auf jeden Fall überprüfen und versuchen, die Grafik-Pipeline besser zu verstehen.
Berry
7

Eigentlich ist das so ziemlich wahr (wenn Sie ein Objekt doppelt so weit weg bewegen, sieht es halb so groß aus), aber es verdeckt, wie sich die visuelle Größe von Objekten ändern sollte, wenn sich der Betrachter bewegt. Insbesondere scheinen Objekte umso schneller größer zu werden, je näher sie sich befinden. Dies liegt daran, dass der Betrachter die Hälfte der Entfernung viel schneller zurücklegt, wenn sich das Objekt in der Nähe befindet, als wenn sich das Objekt in größerer Entfernung befindet. Oder anders ausgedrückt, während die Geschwindigkeit des Betrachters konstant ist, ändert sich der Wert von "halber Entfernung", wenn sich die Entfernung zum Objekt ändert.

schockierend
quelle
2

Da Sie nicht im 3D-Raum arbeiten, können wir davon ausgehen, dass sich die Sprites niemals drehen (Drehung kann durch Schrägstellen usw. simuliert werden). Diese einfache Einschränkung macht es ziemlich einfach, einigermaßen genaue Zahlen für die Größe zu erhalten, die von der Entfernung abhängen soll von der Kamera.

Zunächst müssen Sie verstehen, wie 3D-Objekte gerendert werden. Obwohl eine Kamera auf einen Punkt konvergiert, gibt es eine unsichtbare Ebene, die als Bildschirm dient, auf dem die Objekte gezeichnet werden. Das einzige, was Sie über den Bildschirm wissen müssen, ist, wie weit er von der Kamera entfernt ist.

Hier ist ein Diagramm, wie ein Objekt in zwei verschiedenen Abständen auf eine Kamera gerendert wird.

Wie zu erwarten ist, hängt die Höhe des Objekts von der Entfernung zur Kamera ab. ABER da das Zerreißen in der nahen Ausleseebene stattfindet, müssen wir die Höhe des Sprites an diesem Punkt berechnen.

Einige grundlegende Trigger-Berechnungen führen Sie zu folgender Formel:

f(d, v) = v/(v+d)
* Where f is the size ratio to the original sprite aka size factor
    and v is the distance to the near clipping plane (trial and error value)
    and d is the distance from the near clipping plane to the object

BEISPIEL:

Assuming you have a sprite that is 2.5x1.8 units in size and 10 units away 
   from the camera, and that the near clipping plane is 5 units from the camera.

sizeFactor = 5/(5+10) = 0.3

renderHeight = actualHeight * sizeFactor = 1.8 * 0.3 = 0.54
renderWidth  = actualWidth * sizeFactor = 2.5 * 0.3 = 0.75

Ich würde vorschlagen, mit zu beginnen v=5und von dort aus anzupassen, je nachdem, wie es aussieht. Ich kann eine Geige zusammenwerfen, mit der Sie die Änderungen in Echtzeit sehen können.

TL; DR

The change in height or width should be multiplied by the following factor:

sizeFactor = v/(v+d)

Where v = Some number greater than 0 that never changes (try 1 thru 5)
  and d = the distance from the camera

So an object that is 2.5 units tall would be rendered at 2.5*sizeFactor units tall.

BEARBEITEN: Wenn Sie sagen, dass Sie sich entlang der Z-Achse bewegen möchten (wie bei den meisten 3D-Spielen, Schützen usw.), wird die Berechnung der Objektgröße basierend auf der Entfernung auch von der Position im Rahmen abhängen. ähnlich dem peripheren Sehen. Stattdessen würde ich es mit meiner Mathematik versuchen, die eine orthografische Sichtweise ist (denken Sie an Mario, Angry Birds, Super Smash Bros usw.). Ich kenne das Aussehen und das Gefühl nicht, das Sie erreichen wollen, aber solange es real zu sein scheint, werden die Spieler es nie erfahren!

DEMO!

Jim Buck
quelle
Ja, ich strebe tatsächlich eine orthographische Sichtweise an. Das Spiel, von dem ich meine aktuelle Inspiration "entlehne", ist Rayman Origins. In einigen Abschnitten des Spiels kannst du auf Blumen springen und dann in eine andere Ebene mit einer anderen Tiefe springen. Dann zoomt die Kamera entsprechend dieser Tiefe hinein oder heraus. In diesem Video sind einige Beispiele zu sehen , und zwar um 4:50 und 5:00.
Berry
Außerdem tolle Antwort! Aber da nur die Bestätigung, dass die Regel "doppelt so eng, doppelt so groß" zutrifft, ausreichend gewesen wäre, habe ich die Antwort von Blue als die beste gewählt.
Berry
Vielen Dank und viel Glück mit Ihrem Spiel! Aber ich möchte anderen klarstellen, dass "doppelt so nah, doppelt so groß" großartig funktioniert, wenn sich alles sehr nah an der Kamera befindet. Mit zunehmender Entfernung nimmt die wahrgenommene Größenänderung ab. Schauen Sie sich beispielsweise Ihren Daumen aus der Nähe an, strecken Sie dann Ihren Arm aus und betrachten Sie ihn. Die Größe Ihres Daumens erscheint drastisch kleiner. Schauen Sie sich danach etwas weit entferntes an. Machen Sie einen Schritt zurück (ungefähr so ​​viel wie Ihre Armlänge). Beachten Sie, wie sich die Größe kaum verändert hat? Wenn ein Spiel ein langes Sichtfeld hat, ist die Verwendung von ein wenig Mathematik ein langer Weg.
Jim Buck
EDIT: Ich habe in meinem vorherigen Kommentar einen Fehler gemacht. "Zweimal so nah, doppelt so groß" ist richtig, wenn die Objekte in Bezug auf ihren Abstand von der Kamera relativ nah beieinander bleiben.
Jim Buck
Hier ist eine kurze Demo, die ich zusammengestellt habe. Bewege mich mit der Maus und ändere die Tiefe mit dem Scrollrad.
Jim Buck
0

Dies wurde nicht behandelt, und ich dachte, dies könnte von Vorteil sein: Es sollte beachtet werden, dass sich die Gesamtfläche des Sprites vervierfacht , wenn Sie die Hälfte der Entfernung in X- und Y-Dimensionen verdoppeln . Das ist weil:

Area = X * Y

Nach dem Vergrößern:

NewArea = (x*2) * (y*2)

Dies kann den Eindruck erwecken, dass der Zoomeffekt schnell auftritt oder zu stark ist. Sie können den Faktor anpassen, indem Sie 2 in der obigen Formel auf einen Gleitkommawert wie 1,5 oder 1,33 ändern.

Alternativ habe ich die Kameratiefe (Entfernung) zu Ihren Kacheln in einem Bytewert zusammen mit der Kameraübertragung (X und Y) gespeichert und dann die projizierte Kachelgröße folgendermaßen berechnet:

XTileSize = (255 / CameraZ) * DefaultTileWidth
YTileSize = (255 / CameraZ) * DefaultTileHeight

Beachten Sie, dass CameraZdie Zeitspanne zwischen 1 und 255 liegen muss. Diese Einschränkung kann für Sie in Zukunft ein Vorteil oder ein Nachteil sein.

Mark H.
quelle