Gönderen Konu: Merhaba retrojen (ve ilk 3D denemelerim)  (Okunma sayısı 597 defa)

0 Üye ve 1 Ziyaretçi konuyu incelemekte.

Çevrimdışı Alpyre

  • RAAT
  • Retromanik
  • *
  • İleti: 9
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #15 : 10 Temmuz 2017, 11:23:58 »
Bu başlığa güncelleme zamanı! Geç cevaplar için özür. Şehir dışındaydım... :(

Alıntı
fakat uzak duvarlardaki texture'lar sağa sola sallanıyor hatta bazen hepten yok oluyorlar, bu hiç hoş değil:

Bu problemin başka bir bug olmadığından emin misin. mesela precision'ı 6 bit yerine 8 bite veya 16 bite çıkarınca bug ortadan kalkıyor mu?...

Aynen abi. Duvarlara yaklaşınca oluşan bozulma precision’ı 10 bit'e çıkarınca ortadan kalkıyor. 16 bit'e ise hiç çıkarmak istemiyorum. Çünkü bazı hesaplamalarda precision’ı kaybetmemek için sola iki kez bitshift yapıyorum. Bu değişkenlerimi double yapmak zorunda bırakır. Bunu istemiyorum. Önerdiğin gibi 8 bit kullanıp, high word'ü doğrudan okumak süper olur. Yalnız C'de bunun için yazacağım kod ne kadar verimli olur bilemiyorum? Keşke Assembly bilsem. :D

Uzak duvarların kaybolmasının nedeni ise, mapping’de kullandığım bir değişkenin (her satırdaki duvar uzaklığı) de precise olması gerektiğindenmiş. Onu halledince o da düzeldi.

Bu arada görsellerden de anlaşılacağı gibi “perspective correct texture mapping” yapıyorum (her satırda duvar uzaklığı bu yüzden gerekli). Şehirlerarası yolda 90’lı yıllardaki öncü 3D oyunların görsellerini youtube’dan bol bol inceledim. “Legends of Valour” ve “Ultima Underworld” çok dikkatimi çekti. Bu ikisinin de PC versiyonu “perspective correct” kullanmıyor gibi. Affine kullanıyorlar sanki (bazı açılarda perspektif bozulmaları var çünkü texture’larda).

Ben de duvarları daha küçük duvarlara bölüp her duvar için Affine mapping yapmaya karar verdim.



Böylece satır başına birkaç çarpma bölme işleminden daha kurtulmuş oldum. Fakat bu defa da daha fazla vertex transform edilmek zorunda. Parça duvarların ve texture’ın genişliğini, perspektif bozulmasının fazla hissedilmeyeceği kadar büyütüp bir ortalama yakalamaya çalıştım. Hazır elim değmişken texture’ı da tümden değiştirdim. Belirttiğin gibi gradient’li bir şey yapmaya çalıştım. Gerçekten fark yarattı.



NOT: Bu arada Legends of Valour’un Amiga sürümüne de baktım. Zemin döşemesini çıkarmışlar, fakat duvarlar “perspective correct”! Çok ilginç değil mi? :)
Bu haliyle FPS 060 Amiga’mda üst sınır olan 50’ye dayandı. Fakat duvarlara yakın olunduğunda (en az 25’e kadar) düşebiliyor.
Tüm bu optimizasyonlara rağmen, hala stok A1200’de bir Legends of Valour FPS performansını yakalayabilmiş değilim (Affine kullanmama rağmen 7-10 FPS’in üzerine çıkamadım hala). Bir şeyleri doğru yapmıyor olmalıyım.

Tahminimce hesaplamalarda değil de, pikselleri ekrana yazdırırken oluyor ne oluyorsa.
Ya da bu oyunlar Assembly ile yazıldığı için mi daha hızlı, bilemiyorum?
Bir de gcc ile mi derlesem acaba? Bakıcaz… :)

Denemelerim sürecek, bakalım daha neler öğreneceğim.

Çok detaylı yazamıyorum şu aralar. Aslında bu thread bayağı bir güzelleme hakediyor. Kusuruma bakmayın. Ama süper gidiyor.

Yorumların hem fikir, hem gaz veriyor, hem de biraz şımartıyor abi. :)
Yoğun olduğunu biliyorum. Kıp kısa yazsan da hiç sorun değil. Zaten tek satırda bile 40 yıl düşünsem aklıma gelmeyecek fikirler veriyorsun. Çok sağol valla. :)

EDIT: Bir de executable atacaktım. Unutmuşum. Buyrun efendim.

Hareket için: W,A,S,D
Tam ekran  : F
Çıkış : Q

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 1977
  • Advanced User Simulator
    • ae unutmadan
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #16 : 11 Temmuz 2017, 01:04:39 »
Legends of Valour seninkinden yavaş çalışıyor gibi geldi bana alpyre.

stok a1200 üzerinde 7-17fps çiziyor.

Çevrimdışı Alpyre

  • RAAT
  • Retromanik
  • *
  • İleti: 9
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #17 : 12 Temmuz 2017, 17:24:48 »
Legends of Valour seninkinden yavaş çalışıyor gibi geldi bana alpyre.

stok a1200 üzerinde 7-17fps çiziyor.

Aaa!? Gerçekten mi? Yani aslında öyle de olması gerek, çok daha sade bizimkisi.
Benim makinede 10'un üzerini göremedim bir türlü.
Ben A1200'ümde custom graphics.library'si olan bir ROM kullanıyorum, sanırım ondan bu farklılık.
İyisi mi yeni bir ROM yapayım şu makineye! :)

17 FPS hiç fena değil. Basit bir labirent oyunu yapabilirim öyleyse. :)

Çevrimdışı nightlord

  • RAAT
  • Tedavideki Retromanik
  • *
  • İleti: 347
    • Night Network
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #18 : 12 Temmuz 2017, 21:14:53 »
Selam Alpyre, hızlı iki sorum var?

Alıntı
mapping’de kullandığım bir değişkenin (her satırdaki duvar uzaklığı)

hemen bir terminoloji senkronizasyonu:

"satır" ile ne kastediyorsun? sanki dikey piksel sütunlarını (yani x=sabit) kastettiğini anlıyorum ama emin olamadım. yatay raster satırı (yani y=sabit) kastetmiyorsun değil mi?

Alıntı
Fakat bu defa da daha fazla vertex transform edilmek zorunda
senin vertexlerin 2d mi (yani üstten görünüş) 3d mi? transform işleminden kastın 3x3 (veya 3x2) bir matrix ile 2d bir vertex'in çarpılması mı? yoksa 4x4 (muhtemelen içine projection da yedirilmiş) bir matrix ile 3d bir vertex mi çarpıyorsun? ya da başka bir metod mu?


Çevrimdışı Alpyre

  • RAAT
  • Retromanik
  • *
  • İleti: 9
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #19 : 13 Temmuz 2017, 09:03:46 »
Hemen hızlı iki yanıt geliyor :)

Alıntı
mapping’de kullandığım bir değişkenin (her satırdaki duvar uzaklığı)

hemen bir terminoloji senkronizasyonu:

"satır" ile ne kastediyorsun? sanki dikey piksel sütunlarını (yani x=sabit) kastettiğini anlıyorum ama emin olamadım. yatay raster satırı (yani y=sabit) kastetmiyorsun değil mi?

Haklısın. 'Satır' hiç doğru bir terminoloji olmadı. "Sütun" demeliydim (x=sabit). Duvarlar sırayla düşey çizgiler halinde çiziliyor.

Alıntı
Fakat bu defa da daha fazla vertex transform edilmek zorunda

senin vertexlerin 2d mi (yani üstten görünüş) 3d mi? transform işleminden kastın 3x3 (veya 3x2) bir matrix ile 2d bir vertex'in çarpılması mı? yoksa 4x4 (muhtemelen içine projection da yedirilmiş) bir matrix ile 3d bir vertex mi çarpıyorsun? ya da başka bir metod mu?

Bak işte bu soru çalıştığım yerden geldi.
Dün şu yazını okumuş bulundum (sörf yaparken şans eseri karşıma çıktı): http://www.plazma-dergi.org/dergi/08/chunk/ch09.html
Okumamış olsaydım şimdi şaşkın şaşkın ekrana bakıyor olacaktım muhtemelen. :) Neyse...

Vertex'lerim tamamen 2D. X ve Y koordinatından ibaret.
'Transform' dediğim ise bu vertex'lerin herbirini oyuncuya rölatif hale getirmek (sanki oyuncu sabit duruyor da tüm duvarlar onun etrafında dönüyor gibi).

Pseudo code olarak yazarsam şöyle bir şey yapıyorum:
pX,PY : Oyuncunun mutlak haritadaki konumu
X,Y :  Vertex'lerin mutlak haritadaki koordinatları.
TX,TY : Oyuncuya göre rölatif hale getirilmiş koordinatlar.
Kod: [Seç]
for each vertex in this sector
  vertex.TX = vertex.X - pX
  tempTY    = vertex.Y - pY
  vertex.TY = vertex.TX * Cos(angle) + tempTY * Sin(angle)
  vertex.TX = vertex.TX * Sin(angle) - tempTY * Cos(angle)

Daha sonra da bu TX,TY koordinatlarından vertex'lerin ekran koordinatlarını hesaplıyorum. TY bir aproksimasyon olarak oyuncuya uzaklık (z) kabul ediliyor (bu bisqwit'in kodunun aşağı yukarı aynısı).

Bu hesaplamalar için matris kullanabileceğimi yeni öğrendim (dün :)).
Hatta bisqwit'in videosundaki gizemli "Vector Cross Product" işleminin olduğunu da sanırım anladım. Vertex'leri vektör olarak alıyor, matris olarak yazıyor ve sonra ardışık matris işlemleri yapıyor. Ama giriş yazımda da dediğim gibi, bu çok daha pahalı. Temel trigonometri ile çok daha ucuz hesaplanabiliyor.

Ancak 'transform' işleminde avantaj sağlayabilir gibi duruyor. Bunun üzerine biraz kafa yorayım.

Çevrimdışı nightlord

  • RAAT
  • Tedavideki Retromanik
  • *
  • İleti: 347
    • Night Network
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #20 : 13 Temmuz 2017, 19:55:05 »
OK bu durumda vertex transform sayısını azaltmanın bir yolu olabilir. Özellikle duvarları küçük küçük bölümlediğin için (hani mesela 8m uzunluğundaki duvarı 8 tane 1m duvar yapıyorsun ya)

Diyelim ki 8 m duvar için 9 vertex'in var.
v1, ... , v9

ve sen bunları transform edip 9 transformed vertex buluyorsun
tv1, ... , tv9

Bu yazdığın işlem ile sadece ilk 2 vertexi döndür.
tv1, tv2 yi bul

sonra bu ikisinin farkı senin o yöndeki duvarlar için birim vektörün

u1 = tv2 - tv1

bundan sonra

tv3 = tv2 + u1
tv4 = tv3 + u1
...
tv9 = tv8 + u1

yani 7 tane vertex'i sadece 2 toplama ile bulabilirsin.

Hatta en başta hatırlarsan bunu sormuştum. Mesela bütün duvarlar kuzey güney ve doğu batı şeklinde olsa işine yarar mı diye. Bunun için sormuştum. Çünkü o durumda sadece 2 tane birim vektör hesaplaman yeterli diğer bütün vertexleri toplamalar/çıkarmalar ile transform edebilirsin.





Çevrimdışı Wisdom

  • RAAT
  • Retroman
  • *
  • İleti: 40
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #21 : 15 Temmuz 2017, 12:44:09 »
Merhaba,

Cok guzel gidiyor, elinize saglik, ben daha yeni gordum bu konuyu. Koda bakmadim ama konunun tamamini okudum, bir yerde sin/cos tablolarini 72 degerden 18'e indirdiginizi yazmistiniz galiba (simdi geri donup bakamadim). Eger programin size'i sorun degilse (ki degil saniyorum), bu tablolari mumkun oldugunca acmanizda ve bir fonksiyon uzerinden erismek yerine inline olarak erismenizde fayda var. Hatta yeriniz varsa mumkun oldugunca her turlu hesaplamayi tablolara donusturmenizi oneririm. Cok genel bir oneri oldu biliyorum, belki zaten yaptiniz, belki de "feasible" degil, ama soylemeden gecemedim.

Tekrar elinize saglik, basarilar!

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 1977
  • Advanced User Simulator
    • ae unutmadan
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #22 : 17 Temmuz 2017, 14:32:57 »
Hatta en başta hatırlarsan bunu sormuştum. Mesela bütün duvarlar kuzey güney ve doğu batı şeklinde olsa işine yarar mı diye. Bunun için sormuştum. Çünkü o durumda sadece 2 tane birim vektör hesaplaman yeterli diğer bütün vertexleri toplamalar/çıkarmalar ile transform edebilirsin.

hmm bu durumda wolfenstein topu topu 2 vertex hesabından ibaret miymiş?
e bu güzel bir ip ucu oldu.

Çevrimdışı Alpyre

  • RAAT
  • Retromanik
  • *
  • İleti: 9
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #23 : 17 Temmuz 2017, 17:02:28 »
...bu tablolari mumkun oldugunca acmanizda ve bir fonksiyon uzerinden erismek yerine inline olarak erismenizde fayda var. Hatta yeriniz varsa mumkun oldugunca her turlu hesaplamayi tablolara donusturmenizi oneririm...

Haklısın Wisdom. Öyle yapacağım.
Ancak nightlord'un önerdiğini uygulamanın zarif bir yolunu düşünüyorum kaç gündür. Bu optimizasyon kodumda kesinlikle olsun istiyorum ama haritalarım Wolf3D'deki gibi blok blok olsun da istemiyorum. Pek çok şeyi yeni baştan tasarlayacağım sanırım. :)

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 1977
  • Advanced User Simulator
    • ae unutmadan
Ynt: Merhaba retrojen (ve ilk 3D denemelerim)
« Yanıtla #24 : 18 Temmuz 2017, 23:31:15 »
Wolf3D'deki gibi blok blok olsun da istemiyorum. Pek çok şeyi yeni baştan tasarlayacağım sanırım. :)

bu durumda harita detayını limitleyerek çözebilirsin belki de: 90,60,45,30 derecelik duvarlar kullanıp  bunları kendi aralarında  toplam 8 vertex çarpımı ile taban işlemi halledip, diğer tüm duvarları kendi gruplarında toplama yöntemi ile halledebilirsin. Hatta sadece 90 ve 45 derece kullandığında bile birçok harita başarıyla kotarılabilir.