Skip to content

Tarayıcıda açık dünya inşa etmek, bölüm 10: Dikiş kaosu ve köşe bölümündeki boss savaşı

Cinevva CTO'su ve Kurucu Ortağı Oleg Sidorkin tarafından

Burada yeni misiniz? Seri rehberine göz atın. Rehber, Spike'ın ne olduğunu açıklıyor ve tüm bölümlere bağlantılar içeriyor.

Önceki bölümler yöntemli geldiyse bu bölüm tam anlamıyla bir mücadeleydi.

17'den 22'ye kadar olan Spike'lar, uç durumlar dönemimizdi. Aynı anda iki LOD kullanan marching cubes, yükseklik haritası ile MC sınırları arasındaki dikişler, üç veya dört LOD seviyesinin buluştuğu farklı çözünürlüklü köşe chunk'ları, GPU'da dikiş üretimi ve geri dönüş modu davranışları. Her Spike, karşılaştığımız veya karşılaşmayı beklediğimiz belirli bir hata senaryosunu ele aldı.

Spike 17, iki LOD seviyesi aynı anda etkinken çift LOD'lu marching cubes yaklaşımını test etti. Zorluk, tek bir chunk'ın farklı yüzlerindeki komşularının farklı çözünürlüklerde olabilmesiydi. Spike 16'daki geçiş hücresi mantığı tek seferde bir yüz için çalışıyordu ancak bir chunk birden fazla yüzünde geçiş hücrelerine ihtiyaç duyduğunda vertex buffer yönetimi karmaşıklaşıyordu. Her yüzün geçiş hücrelerinin, diğerlerinin üzerine yazılmadan üretilip buffer'a eklenmesi gerekiyordu.

Spike 19'u yeni sekmede aç ↗ · Kaynak kodunu görüntüle

Tekrar tekrar karşımıza çıkan ilk kötü karakter sarım sırasıydı. Birkaç kez topoloji sorunları yaşadığımızı düşündük ama aslında bunların yönlendirme sorunları olduğunu keşfettik. Sarım, ana mesh'e göre ters olduğu için arka yüz ayıklama geçerli dikiş üçgenlerini yok ediyordu. Kök neden aynıydı, ancak görsel belirti kamera açısına göre değişiyordu. Çözüm, geçiş hücresi üretim kodunda tutarlı bir sarım kuralını zorunlu kılmak ve bunu çift taraflı materyal geçişiyle doğrulamaktı.

İkinci kötü karakter, kısmi doğruluğun verdiği sahte güvendi. Bir dikiş belirli bir kamera açısından kusursuz görünebilir, ancak yüksek ve düşük çözünürlüklü chunk'lar arasındaki LOD rolleri değiştiğinde bozulabilirdi. Geçiş hücresi asimetriktir. Yüksek çözünürlüklü ve düşük çözünürlüklü taraflardan farklı biçimlerde örnek alır. Bir yapılandırmada “hangi taraf yüksek çözünürlüklü” mantığını ters kurarsanız hatayı yalnızca kamera belirli bir konuma geldiğinde görürsünüz.

Ardından en sevdiğimiz toparlanma anlarından biri geldi. Yükseklik haritası karolarındaki dikişin kesilmesi artefaktını araştırıyor ve geçiş mantığını suçluyorduk. Bunun için iki gün harcadık. Asıl suçlu, önceki çizimden kalan eski geometrilerdi. Chunk daha düşük bir LOD'a geçtiğinde önceki frame'deki yüksek çözünürlüklü geometri hâlâ buffer'ın son kısmında duruyordu. Çizim aralığı ise hâlâ eski ve daha yüksek vertex sayısına ayarlıydı. Çizim aralığını compute shader'ın atomik sayacının bildirdiği etkin vertex sayısıyla sınırlandırınca “gizemli dikiş sorunu” ortadan kayboldu.

Bu, render hatalarının çoğu zaman mesh üretim hataları gibi göründüğünü hatırlatan harika bir örnekti. Geometri başından beri doğruydu. Draw call yalnızca geçerli verilerin sonunu aşarak okuma yapıyordu.

Spike 22'ye geldiğimizde, chunk'ların belirli koşullar altında marching cubes'tan yükseklik haritası moduna geçebildiği hibrit geri dönüş yaklaşımını test ediyorduk. Örneğin chunk'ın hacimsel düzenleme içermemesi ve kameradan yeterince uzakta olması bu koşullar arasındaydı. Bu yaklaşım bize ya hep ya hiç politikasından daha uygulanabilir bir yol sundu. Yakın alandaki düzenlenmiş chunk'lar hacimsel özgürlük için MC kullanırken uzak alandaki düzenlenmemiş chunk'lar verimlilik için yükseklik haritalarını kullanıyordu.

Spike 22'yi yeni sekmede aç ↗ · Kaynak kodunu görüntüle

Bu bölüm, hız treninin dik düşüşü gibiydi. Aynı anda hem sinir bozucu hem de üretkendi. Tek tek düzeltmelerin çoğu küçüktü; bazen yalnızca bir karşılaştırma operatörünü veya offset'i değiştiren tek bir satırdan ibaretti. Ancak LOD geçişlerinin, buffer yönetiminin ve çizim aralıklarının nasıl etkileşime girdiğine dair kazandırdıkları anlayış hiç de küçük değildi.

  1. bölümde kaosun ardından gelen kararlılık katmanını ele alıyoruz: politika tabanlı chunk modları ve tepkisel hata düzeltmeden açık sistem kurallarına geçiş.

Bu bölümde değinilen teknolojiler

Çift LOD'lu marching cubes. Marching cubes algoritmasının, sınırı birleştiren geçiş hücreleriyle birlikte iki çözünürlük seviyesinde eşzamanlı çalıştırılmasıdır. Buradaki zorluk, tek bir chunk'ın farklı yüzlerindeki komşularının farklı çözünürlüklerde olabilmesi ve bu nedenle her yüz için bağımsız geçiş hücresi üretimi gerekmesidir. Her yüzün geçiş hücreleri, diğerlerinin üzerine yazılmadan vertex buffer'a eklenir. Atomik sayaçlar, tüm yüzlerdeki toplam etkin vertex sayısını izler.

Sarım sırası. Her üçgendeki vertex sırası, hangi tarafın “ön” yüz olduğunu belirler. Arka yüz ayıklamanın çalışması için tutarlı bir sarım gerekir; dışarıdan bakıldığında bu genellikle saat yönünün tersidir. Geçiş hücreleri üçgen üretirken sarımın ana mesh'in kuralıyla eşleşmesi gerekir. Sarımın ters olması, arka yüz ayıklamanın geçerli dikiş üçgenlerini yok etmesine neden olur ve bu da belirli kamera açılarından eksik yüzeyler gibi görünür. Yaygın bir hata ayıklama tekniği, artefaktların sarım sorunundan mı yoksa gerçek topoloji boşluklarından mı kaynaklandığını doğrulamak için materyalde side: THREE.DoubleSide ayarını açıp kapatmaktır.

Yükseklik haritasından MC'ye geri dönüş. Uzaktaki veya düzenlenmemiş chunk'ların yükseklik haritası arazisini (ucuz, düz yüzey), yakındaki veya düzenlenmiş chunk'ların ise marching cubes yaklaşımını (hacimsel, mağaraları destekler) kullandığı hibrit bir chunk modudur. Geri dönüş kararı, kameraya olan mesafeye ve chunk'ın SDF düzenlemeleri içerip içermediğine bağlıdır. Bir yükseklik haritası chunk'ı ile MC chunk'ı arasındaki dikiş, kendine ait bir geçiş geometrisi gerektirir. Bu, Transvoxel'e benzer ancak iki LOD seviyesinden ziyade iki farklı gösterim arasında köprü kurar. Bkz. hibrit yükseklik haritası + hacimsel katmanlar.

Çizim aralığı ve atomik sayaçlar. GPU güdümlü mesh üretiminde compute shader, vertex'leri bir buffer'a yazar ve kaç vertex üretildiğini izlemek için atomik bir sayacı artırır. Draw call, vertex sayısı olarak buffer kapasitesini değil bu sayacı kullanmalıdır. Çizim aralığı etkin sayıyla sınırlandırılmazsa önceki frame'lerden kalan eski vertex'ler —hâlâ buffer'ın son kısmında duran veriler— hayalet geometri üretir: topoloji hataları gibi görünen ancak aslında geçerli verilerin sonunu aşan okumalardan kaynaklanan ince parçalar ve titreyen üçgenler.


12 bölümün 10. bölümü.
Önceki: Bölüm 9 - Transvoxel bir iskeletle başladı
Sonraki: Bölüm 11 - Sabit kodlanmış mod değil, politika modu
Seri rehberi: /blog/2026-02-25-open-world-browser-series-guide