2.5D dünyamda derinlik testi ve doku saydamlığını birlikte nasıl kullanabilirim?


11

Not: Zaten bir cevap buldum (bu sorudan sonra göndereceğim) - Bunu doğru yapıp yapmadığımı veya daha iyi bir yol olup olmadığını merak ediyordum.

OpenGL ES (JOGL) kullanarak "2.5D" izometrik bir oyun yapıyorum. "2.5D" ile dünyanın 3D olduğunu kastediyorum, ama 2D izometrik karolar kullanılarak oluşturuldu.

Çözmek zorunda olduğum asıl sorun, dokularımın sırayla (arkadan öne) işlenmesi gerektiğiydi, böylece fayanslar doğru efekti oluşturmak için düzgün bir şekilde üst üste biniyordu. Biraz okuduktan sonra, bunun "eski şapka" 2D yaklaşımı olduğunu hemen anladım. Bu, verimli bir şekilde yapmak zorlaştı, çünkü 3D dünyası oyuncu tarafından değiştirilebilir (böylece şeyler 3D uzayda herhangi bir yerde görünebilir) - bu yüzden derinlik tamponundan yararlanmam mantıklı görünüyordu. Bu, şeyleri doğru sırada oluşturma konusunda endişelenmem gerekmediği anlamına geliyordu.

Ancak bir sorunla karşılaştım. Birlikte GL_DEPTH_TESTve GL_BLENDbirlikte kullanırsanız , nesnelerin z sırasına göre "sıralanmadan" arka planla karıştırıldığı bir efekt oluşturur (bu, saydamlığın olması gereken yerde garip bir çakışma elde ettiğiniz anlamına gelir).

şeffaflık örtüşme sorunu

İşte sorunu göstermek için bazı sahte kod (bu arada, ben Android için libgdx kullanıyorum).

create() {
    // ...
    // some other code here
    // ...

    Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
    Gdx.gl.glEnable(GL10.GL_BLEND);
}

render() {
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

    // ...
    // bind texture and create vertices
    // ...
}

Soru şu: Şeffaflık örtüşme problemini nasıl çözebilirim?


2
Sadece 2D motorum için tam olarak aynı şekilde gittiğimi söylemek için bir yorum: ilk önce kendimi zeki ve Z-sort fayansları olmaya çalışıyorum, sonra sahnenin düz olması için hiçbir sebep olmadığını fark ettim, böylece fayanslarıma bir Z koordinatı ve aktive alfa testi. Doğru olup olmadığınızdan emin değilim, ama yalnız değilsiniz :-)
sam hocevar 11:11

Yanıtlar:


7

Tamam, işte benim çözümüm (daha iyi yapılabilirse lütfen yorum yapın) ...

Aslında alfa testi kullanmam gerektiği ortaya çıkıyor (yine de, bunu yanlışlıkla keşfettim, bu yüzden neden işe yaradığından tam olarak emin değilim).

create() {
    // ...
    // some other code here
    // ...

    Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
    Gdx.gl.glEnable(GL10.GL_ALPHA_TEST);
}

render() {
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    Gdx.gl10.glAlphaFunc(GL10.GL_GREATER, 0);

    // ...
    // bind texture and create vertices
    // ...
}

Kullanımına dikkat GL_ALPHA_TESTve glAlphaFunc.


Sorunumu da çözdü. Paylaşım için teşekkürler. Harikasın
Mathlover

2

Alfa testi, oluşturucunun z tamponu da dahil olmak üzere herhangi bir arabelleğe piksel çizimini durdurmak için kullanılır. Alfa harmanlama sadece görsel bir şeydir - değerler zbuffer'a hala yazılır, bu da bu gibi sorunlara neden olabilir - görünmez pikseller daha sonra oluşturulan piksellerin önünde olur, bu da yeni pikselleri çizdiğinizde ztestte başarısız olacakları anlamına gelir. Verdiğiniz görüntüde görebileceğiniz bu, bir başarısızlık başarısız.

Z yazmanın kapatılması da aynı amaçlara ulaşacaktır, ancak int'deki her şeyi ön sıraya geri çektiğinizden emin olmalısınız. Bu, izometrik oyununuzda yapabileceğiniz kadar kolay olmalıdır.


1
Bir 2D iso oyununda sadece sabit bir Y uçağınız olduğunda ve tasarımcı dünyanın tam kontrolünde olduğunda arkadan öne doğru çizim yapmanın kolay olduğunu düşünüyorum. Ancak, şeyler 3B alanda herhangi bir yerde mevcut olabilir ve kullanıcının bir şeyleri değiştirmesine izin verirseniz, daha karmaşık hale gelir. Derinlik tamponunun kullanılması hayatımı çok daha kolaylaştıracağını düşünüyorum.
Nick Bolton
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.