Bir yüzeyin diğeriyle tam olarak çakışmasına ne sebep olur?


10

Bir yüzeyin diğerinin üstüne binmesine neyin sebep olduğunu gerçekten anlayamıyorum. Oluşturduğum bir 3D motorda tekniğim uç durumlarda başarısız oluyor.

Benim yöntemim boyanacak yüzeyleri en uzaktan en yakına doğru sıralamak. Yakınlığı belirlemek için ortalama z değerlerini karşılaştırıyorum. Bununla birlikte, bazen, örtüşen bir yüzey, örtüştüğünden daha yüksek bir ortalama z değerine sahiptir. Böylece, daha uzaktaki yüzey daha yakın olana boyanır - bunun gibi tuhaf bir renderleme ile sonuçlanır:

Yanda kırmızı bir bölüm ile büyük mor kare

Birinin görmesi gereken, sadece küpün mor ön yüzeyi iken, kırmızı yan yüzey mor olanın üzerine boyanmıştır. Mor yüzeyin ortalama z değeri daha yüksektir ve bu nedenle 'daha uzağa'. Bu tekniğin doğru olup olmadığı konusunda biraz şüphem var.

Ayrıca denediğim şey kameradan yüzeye (yani orijinden) olan mesafeyi almak, ama sonra bir noktaya ihtiyacım vardı. Her yüzeyin ortasını seçtim ama aynı zamanda her zaman işe yaramıyor çünkü tüm yüzeyler birbirinden büyük değil.

Bu nedenle, yüzeylerin kökene yakınlık sırasını belirlemenin güvenilir bir yolu nedir?

Yanıtlar:


11

Ressamlar Algoritmasını uygulamaya çalışıyor gibi görünüyorsunuz . Sanırım, çoğu modern 3D donanımı Bart'ın (Z / Depth buffer) bahsettiklerini kullandığından, bir öğrenme egzersizi olarak sıfırdan bir rasterleştirici yazmaya çalışıyorsunuz. Ressamlar algoritmasının her durumda çalışması için, olası senaryoları (Wikipedia sayfasında gösterilen çakışan çokgen sorunu gibi) çözmek için oluşturuldukları için yüzeyleri alt bölümlere ayırmaya hazır olmanız gerekir.

En uzaktan en yakına doğru render ederek, daha sonra diğer çokgenler tarafından tıkanacak pikselleri oluşturmak için zaman harcıyorsunuz ve çokgenler üzerine dokuları ve karmaşık gölgelendiricileri koymaya başladığınızda değerli döngüleri boşa harcıyorsunuz. Modern donanımın, oluşturulacak pikselin ekrandakinden daha uzakta olup olmadığını belirlemek için derinlik arabelleğini kullanarak önden arkaya oluşturulmasını tercih etmesinin nedeni budur (ve bu nedenle atılabilir).

Çoğu modern hızlandırma donanımında bile, yarı saydam çokgenleri sıradan ve arkadan öne doğru sıralamanız ve işlemeniz gerekir, bu da tüm opak çokgenler oluşturulduktan sonra yapılır.


Basit bir oluşturucu oluşturduğumu söylemekte haklısın. Mesele şu ki, herhangi bir 3D kütüphanesi kullanmıyorum. Tüm projeksiyon hesaplamalarını kendim yapıyorum ve sonra 2B çizim kitaplığı kullanarak çizgiler çiziyorum. Bu en hızlı değil ve piksel başına hiçbir şey yapmıyorum. Her yüzeyden sadece 4 noktam var ve dikdörtgen şekli bir renkle dolduruyorum. Tek seferde tam bir yüzey çizdiğim için, öne doğru geri çekmem gerektiğini söyleyerek haklı mıyım?
pimvdb

Çok eğlenceli ve öğrenmenin harika bir yolu gibi geliyor. Bunu herhangi bir derinlik tamponu olmadan yapıyorsanız, önden arkaya dönebilirsiniz. Bence çokgenlerinizin tüm ekran koordinatlarını bulup çakışma olup olmadığını kontrol etmeniz gerekecek. Derinlemesine örtüştükleri yerlerde, oluşturmak için çokgenleri kesmeniz gerekir, böylece sıralamayı doğru bir şekilde çözebilirsiniz. Ayrıca, mutlaka Görünmesi gerekmeyen çokgenleri kaldırmanın bir yolu olarak Arka Yüz Toplama'ya bakmak isteyebilirsiniz
Roger Perkins

Roger Perkins haklı. Çokgenleri parçalamadığınız sürece, bu şekilde doğru z-sıralama elde edemezsiniz (yani her zaman bazı kenar durumlarınız olacaktır). Yine de bu oldukça yavaş olabilir.
bummzack

Çalıştırdım! Yaptığım şey, arka yüzün ayrıştırılması ve ayrıştırılmasının bir kombinasyonuydu: katı bir küpte, bazı yüzler görünmezken diğerleri (maksimum 3). Bu yüzden önce görünmeyen kısımları ve görünür kısımları üzerlerine boyadım. Bu bir cazibe gibi çalışır, bir veya daha fazla tarafı kaldırırsam, üst üste biniyorlar, ancak yine de doğru sırada çiziliyorlar. Teşekkürler!
pimvdb

1
Bu sadece küpler gibi basit dışbükey şekiller için işe yarayacaktır. Şu anda sizin için çalışıyor olmasına sevindim, ancak genel bir çözüm değil.
Richard Fabian

3

Sahip olduğunuz bir görünürlük problemidir . Bir çözüm bir z-tamponu kullanmaktır .


Teşekkürler, ancak z-arabelleğe alma, yanlış yapmıyorsam piksel başına görüntüleme gerektirir. Bunu yapmıyorum - küpün öngörülen noktaları arasında düz çizgiler çiziyorum. Z tamponlama hala mümkün mü?
pimvdb

Düz çizgiler çiziyor olsanız bile, görüntü ekrana (veya bitmap dosyasına) ulaşmadan bir noktada piksel formatında olacaktır.
Bart van Heukelom

Bu doğru, ancak çizim kitaplığım 20 fps ile piksel oluşturma yapmak için çok yavaş. Yine de teşekkürler.
pimvdb

2

Yüzleri ortalama z değerlerine göre sıralamak işe yaramaz, çünkü ortalama z değeri köşelerin gerçek z değeri veya hatta yüzey pikselleri hakkında hiçbir bilgi sağlamaz.

Örnek (uyarı, önde ASCII sanatı):

          /
         /
cam     /
-->    / 
      /
     /--       <--B
    /
    ^--A

İki A ve B yüzü vardır. Kameranın A perspektifinden B'nin önünde. Ancak B'nin ortalama z değeri daha küçüktür. Diğer z değerlerine bakalım:

  • A'nın minimum z değeri 4'tür
  • A'nın maksimum z değeri 11'dir
  • dolayısıyla A'nın ortalama z değeri 7.5'tir.
  • B'nin minimum z değeri 6'dır
  • B'nin maksimum z değeri 8'dir
  • dolayısıyla B'nin ortalama z değeri 7'dir.

Bunları minimal z değerlerine göre sıralamayı deneyebilirsiniz, ancak bunun da işe yaramayacağı durumlar vardır. Yalnızca bir z değeri kullanarak rastgele yüzleri doğru şekilde sıralamanın bir yolu yoktur.

Newell'in algoritmasında http://en.wikipedia.org/wiki/Newell 's_algoritması yaptığınız şey z değerlerinin min / maks aralıklarını sıralamaktır. İki yüzün aralıkları üst üste gelmezse, hangisinin ön tarafta olduğundan emin olabilirsiniz. Eğer yaparlarsa, bazen yüzleri kesinlikle ayırmanız gerekir. Bazen oklüzyon veya başka bir teknik için her köşeyi raytrace etmek yeterli olacaktır.


Bu diyagram, ekran görüntüsünde neler olacağını tahmin ediyorum.
jhocking

1

Yaparak renderlemeyi öğrenmeniz iyi olur. Kudos. Bu durumda, "boyacı algoritması" çözümü yoktur, sıralayarak düzeltmeye çalışmak yerine, PS1'de çokgenleri yan yana olduklarında aynı boyutta tutmaya çalışıyorduk (yaptığınız gibi) söyleyebildiğim kadarıyla) ve arka yüz mermisi (ki yapmıyorsun)

Arka yüz kaldırma , ekran boşluğundaki yüzeyi normal yönüne göre kontrol ediyor (sadece ekran boşluğundan derinlik elemanının işaretini normal dönüştürülmüş olsun (bizim durumumuzda normalin z'si idi) veya üçgen yani çapraz (v1-v0, v2-v0))

Backface culling uygularsanız, yaptığınız rasterleştirme miktarını da azaltırsınız.


Yanıtınız için teşekkürler. Backface culling hakkında okudum ama mesele şu ki bir tarafı çıkarmak istiyorum. Sağlam bir küp ile bu harika olabilir, ancak bir tarafı kaldırırsam o zaman oklüzyon oluyor - bu yüzden onları sıralamaya ihtiyacım var sanırım. Her neyse, bir ışının başlangıç ​​noktasından bir yüzeyin orta noktasından ateşlenmesi fikrini buldum. Bu ışın daha sonra başka bir yüzeyden geçerse, ilk yüzey ikincisiyle çakışır. Bana bu fikrin doğru olup olmadığını söyleyebilir misiniz? Teşekkürler!
pimvdb

Fikriniz örnek vakanız için işe yarar olsa da, işe yaramayacağı birçok durum daha var. Örneğin, aynı sahneniz var, ancak kamera yanlış oluşturma dörtlüsünün merkezi üst üste binmeyecek şekilde eğildiğinde, bence ilkellerinizi daha küçük parçalara ayırmanız gerekecek.
Richard Fabian
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.