İki kat daha yakın bir nesne iki kat daha büyük görünüyor?


16

Bu yüzden, hangi katmanda olduğunuzu değiştirerek Z ekseni boyunca da hareket edebileceğiniz bir 2D oyun oluşturmayı düşünüyordum. Derinliğe bağlı olarak 2D spritelarımı ölçeklendirmek istiyorum.

Bir keresinde birisi bana çok fazla 2d sprite yaptığı bir demo göstermişti ve kaydırarak kameranın derinliğini değiştirebilirdi. Bu yüzden yakınlaştırırken nesneler oynatıcıya yaklaşır ve daha büyük görünür. Sonra bir nesne 1 birim yaklaştığında ne kadar büyük olması gerektiğini merak ettim. Bunu nasıl hesaplarsın? Adam bana şöyle dedi: Kullandığım temel bir kural var: "iki kat daha yakın nesneler, iki kat daha büyük görünüyor."

Şimdi, kendim test ederek, kuralın gerçek dünyada geçerli olmadığını biliyorum;) Ama perspektif ya da bir şey için gerçek dünya hesaplamalarında kullanılan bir sabit var mı? Yoksa bir formül mü?

Bunun böyle bir soru sormak için en iyi yer olmayabileceğini biliyorum, ancak bu, oyunla ilgili sorular için kullandığım tek site olduğundan ve bağlamım bir oyun olduğundan, denemeyi düşündüm. Ayrıca, 3D oyunlarla ilgili olabileceğinden, 3D perspektifler ve matrisler veya herhangi bir şey hakkında her şeyi bilen bu kişinin olduğunu umuyorum;)

tl; dr:

"İki kat daha yakın bir nesne, iki kat daha büyük görünür" Bu gerçek dünyada doğru değildir. Fakat hangi sabit veya formül doğrudur?


3
Cevabın ne olduğu hakkında hiçbir fikrim yok ama nasıl bulabileceğimi biliyorum. Bir şeyin fotoğraflarını çekin. Belki bir parça kağıt. Bunları bilinen farklı mesafelerden alın ve görüntünün ne kadarının kağıt parçası tarafından alındığını hesaplamak için biraz matematik yapın ve oranı bu şekilde belirleyin. Eğlenceli bir deney olabilir!
SpartanDonut

Neden kimsenin doğal logaritma hakkında bir şey söylemediğini merak ediyorum ...
Chad Harrison

4
Neden doğru değil? Bence bu doğru.
Ivan Kuckir

@hydroparadise Doğal logaritmaların bu soru ile ne ilgisi var?
Nathan Reed

Burada sadece bilgiçlik yapıyorum, ama "İki kat daha yakın" garip bir ifade. "Yarı uzakta" olmamalı mı? 'İki kez' daha büyük, ama eğer bir şey yaklaşırsa mesafe azalır.
MrVimes

Yanıtlar:


19

Görüş noktanıza ve hangi yöne hareket ettiğine ve görüş açısına bağlı olarak genellikle doğrudur.

Nesneler için perspektif örneği

İlk kamera görünümünde, Kırmızı blok kamera görünümüne dikey olduğu için, nesnenin mükemmel 1: 2 oranında iki kat daha büyük göründüğüne dikkat edin (Taşındıktan sonra görünümün kenarına çarptığını gösteren oka dikkat edin iki kat daha yakın)

İkincisi 45 derecede döndürülmüş aynı büyüklükte bloktur. Döndükçe, alt kenar artık kameradan üst kenarla aynı mesafede değildir, bu nedenle SEEM doğru bir şekilde 1: 2 oranına ölçeklenmez, ancak gerçekte iki kat daha büyüktür (olduğu gibi) daha uzak mavi blokta, aynı mavi bloktaki ile aynı açı.)

Sonuç olarak bu aslında arkadaşınızın doğru olduğu ve nesneleriniz için 1: 1 oranının ("iki kat daha yakın nesneler, iki kat daha büyük göründüğü" anlamına gelir) iyi bir seçimdir.



Mükemmel cevap! Resimler kesinlikle daha net. Aslında şimdi kendimi yüzümün önünde tutarak ve yaklaştırarak soruyu göndermeden önce denediğim için şimdi gerçekten aptal hissediyorum. Ve sonra düşündüm: hayır iki kat daha büyük hissetmiyorum .... Daha doğru bir şekilde ölçmeliydim;) Perspektif komik bir şey! Ayrıca, Ifeel gibi ben kendim resimleri ile gelip olmalıydı;) Ama harika cevap! Teşekkürler!
Berry

@Mason Wheeler - Sıralı: P
Tom 'Blue' Piddock

8

İki kat daha yakın bir nesne iki kat daha büyük görünür. Thales Teoreminin bir sonucudur ve gerçek dünyada doğrudur.

Thales Teoreminin perspektif projeksiyonunun ardındaki temel matematiksel araç ve perspektif bölümü olarak grafik boru hattında (OpenGL veya DirectX) bilinen şey olduğu iddia edilebilir . Kesinlikle bilmeniz gereken bir teorem ve ne zaman kullanılabileceğini tanımayı öğrenmek.


Harika referanslar! Kesinlikle Thales Teoremini kontrol edeceğim ve grafik boru hattını daha iyi anlamaya çalışacağım.
Berry

7

Aslında bu oldukça doğru (bir nesneyi iki kat uzağa taşırsanız, yarısı kadar büyük görünür), ancak görüntüleyenlerin hareket ettikçe nesnelerin görsel boyutunun nasıl değişmesi gerektiğini de gizler. Özellikle, nesneler daha yakınlaştıkça büyürler. Bunun nedeni, izleyicinin nesne yakın olduğunda nesnenin daha uzak olduğu zamana kıyasla mesafenin yarısını çok daha hızlı kapsamasıdır. Ya da başka bir deyişle, izleyicinin hızı sabitken, nesneye olan mesafe değiştikçe "mesafenin yarısı" değeri değişir.


2

Aslında 3B alanda çalışmadığınız için, spriteların asla dönmediğini varsayabiliriz (dönüş eğriltme ile simüle edilebilir, vb.) Bu basit kısıtlama, boyutun mesafeye bağlı olması gereken şey hakkında biraz doğru sayılar almayı oldukça kolaylaştırır. kameradan.

İlk olarak, 3D nesnelerin nasıl oluşturulduğunu anlamanız gerekir. Bir kamera tek bir noktaya yaklaşsa da, nesneleri çizmek için bir ekran görevi gören görünmez bir düzlem vardır. Ekran hakkında bilmeniz gereken tek şey kameradan ne kadar uzakta olduğudur.

Burada bir nesnenin iki farklı mesafeden bir kameraya nasıl yansıtıldığının bir diyagramıdır.

Beklediğiniz gibi, nesnenin yüksekliği kameradan uzaklığa bağlıdır. ANCAK işleme yakın ayıklama düzleminde gerçekleştiğinden, o noktada hareketli grafiğin yüksekliğini hesaplamalıyız.

Bazı temel trig hesaplamaları sizi aşağıdaki formüle götürecektir:

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

MİSAL:

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

v=5Nasıl göründüğüne bağlı olarak oradan başlamayı ve oradan ayarlamayı öneririm . Değişiklikleri gerçek zamanlı olarak görmenizi sağlayan bir keman atabilirim.

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.

DÜZENLEME: Z ekseni boyunca hareket derken perspektif bir görünüm isteyeceğinizi varsayıyorum (çoğu 3D oyun gibi; atıcılar, vb.) Mesafeye göre nesne boyutunu hesaplamak için matematik de çerçevedeki konuma bağlı olacaktır, çevresel görüşe benzer. Bunun yerine, ortografik bir görünüm olan matematiğimle denerdim (Mario, Angry Birds, Super Smash Bros, vb.). Ulaşmaya çalıştığınız görünüşü ve hissi bilmiyorum, ama gerçek göründüğü sürece oyuncular asla bilemeyecek!

DEMO!


Evet, aslında ortografik bir görüş hedefliyorum. Şu anki ilhamımı "ödünç aldığım" oyun Rayman Origins. Oyunun bazı bölümlerinde çiçeklere atlayabilir ve daha sonra farklı bir derinlikte başka bir katmanda zıplarsınız. Daha sonra kamera bu derinliğe kadar düzeltme veya yakınlaştırma yapar. Örnekler bu videoda 4:50 ve 5: 00'da görülebilir .
Berry

Ayrıca, harika bir cevap! Ancak "iki kat daha büyük, iki kat daha büyük" kuralının geçerli olacağına dair bir teyit yeterli olacağından, Blue'nun cevabını en iyisi olarak seçtim.
Berry

Teşekkürler ve oyununuzda bol şans dileriz! Ama diğerleri için, her şey kameraya çok yakın olduğunda "iki kat daha yakın, iki kat daha büyük" harika çalışacağını açıklığa kavuşturmak istiyorum. İşler ilerledikçe, algılanan boyut değişikliği azalır. Örneğin, başparmağınıza yakından bakın, sonra kolunuzu uzatın ve ona bakın. Başparmağınızın boyutu çok daha küçük görünür. Bundan sonra, uzaktaki bir şeye bak. Bir adım geri git (kol uzunluğunla aynı). Boyutun zar zor nasıl değiştiğini fark ettiniz mi? Bir oyunun uzun bir görüş alanı varsa, biraz matematik kullanmak uzun bir yol kat edecektir.
Jim Buck

EDIT: Önceki yorumumda bir hata yaptım. Öğeler fotoğraf makinesine olan uzaklıklarına göre birbirlerine oldukça yakın kaldığında, "iki kat daha büyük, iki kat daha büyük" doğrudur.
Jim Buck

İşte bir araya getirdiğim hızlı bir demo , hareket etmek için fareyi ve derinliği değiştirmek için kaydırma tekerleğini kullanın.
Jim Buck

0

Bu ele alınmadı ve bunun yararlı olabileceğini düşündüm: Hem X hem de Y boyutlarındaki boyutu iki katına çıkardığınızda, hareketli grafiğin toplam alanını dört katına çıkaracaksınız . Bunun nedeni ise:

Area = X * Y

Yakınlaştırdıktan sonra:

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

Bu size yakınlaştırma efektinin hızlı gerçekleştiği veya çok yoğun olduğu izlenimini verebilir. Yukarıdaki formülde 2 değerini 1.5 veya 1.33 gibi bir kayan nokta değerine değiştirerek faktörü ayarlayabilirsiniz.

Alternatif olarak, yaptığım şey, kamera çevirisi (X ve Y) ile birlikte karolarınıza kamera derinliğini (mesafe) bir bayt değerinde depolamak ve ardından yansıtılan karo boyutunu hesaplamaktır:

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

Bunun CameraZkesinlikle 1-255 arasında olması gerektiğini ve bu kısıtlamanın gelecekte size bir fayda ya da bane olabileceğini unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.