Tarayıcıda açık dünya inşa etmek, bölüm 22: Işıklandırılabilen bulutlar ve beslenmesi gereken ayıklama sistemi
Yazan: Oleg Sidorkin, Cinevva CTO'su ve Kurucu Ortağı
Burada yeni misiniz? Seri rehberini kullanın. Bu rehber, spike'ın ne olduğunu açıklıyor ve tüm bölümlere bağlantı veriyor.
21. Bölüm, beklenen getiriyi sağlamayan bir render tekniği hakkındaydı. Bu bölümde işe yarayan bir teknik ve çalışabilmesi için dikkatli bir düzeltme gerektiren başka bir teknik var. Spike 43 gökyüzüyle ilgili: fizik tabanlı atmosfer ve hacimsel bulutlar, bir sahnenin teknoloji demosu yerine gerçek bir mekân gibi algılanmasını sağlayan temel. Spike 44 ise meshlet tarzı GPU ayıklama üzerine; buradaki ders, örtülme testinin ancak ona sunduğunuz örtücüler kadar iyi olduğuydu.
Gradyandan değil, fizikten gelen bir gökyüzü
Spike 43'ü yeni sekmede aç ↗ · Kaynak kodunu görüntüle
Neredeyse her sinematik hava efekti iki altyapı unsuruna bağlıdır: gökyüzü ve güneş renklerinin elle ayarlanmış bir gradyan yerine fiziğe göre günün saatini izlemesini sağlayan fizik tabanlı bir atmosfer ve gökyüzüne önceden hazırlanmış bir cubemap yerine üç boyutlu yapı kazandıran hacimsel bir bulut katmanı. Spike 43, mevcut WebGPU ve TSL yığını üzerinde tam olarak bu ikiliyi kuruyor, daha fazlasını değil; çünkü bu ikisi hazır olduğunda hava sisteminin geri kalanı (sis, tanrı ışınları, ıslak yüzeyler, kar) daha küçük ve bilinen devam işlerine dönüşüyor.
Atmosfer, WGSL compute shader'larında hesaplanan bir dizi arama tablosundan oluşan Hillaire 2020 modelini kullanıyor. Bir geçirgenlik tablosu, güneş ışığını Rayleigh, Mie ve ozon yoğunluk profili boyunca entegre ediyor ve yalnızca güneş hareket ettiğinde yeniden hesaplanıyor. Gökyüzü görünüm tablosu, bunu koşula bağlamak ek kod yazmaya değmeyecek kadar ucuz olduğu için her karede yeniden hazırlanıyor; bantlaşmayı önlemek amacıyla ufuk çevresinde doğrusal olmayan bir parametrelendirme kullanıyor. Çoklu saçılma şimdilik gerçek tablo yerine analitik bir yaklaşım kullanıyor ve gün batımları doğru göründüğü için bu kestirme yol kendini iyi gizliyor. Bulutlar, yatay bir katman boyunca ilerleyen Schneider Nubis tarzı bir ray-march kullanıyor. Biçimleri, 32³ Worley dokusuyla aşındırılan 128³ Perlin-Worley dokusundan geliyor; ikisi de ağdan veri çekilmeden açılışta compute ile hazırlanıyor. Işıklandırmada Beer yasası sönümlenmesi, çift loblu faz fonksiyonu ve pudra yaklaşımı kullanılıyor. Temel bağlantı, bulutun güneş renginin her adımda aynı geçirgenlik tablosundan örneklenmesi; böylece bulut aydınlatması ikinci bir ayar geçişine ihtiyaç duymadan gün batımını izliyor.
M1'de sistemin tamamı, yarım çözünürlüklü bulutlarla 1,1 ila 2,0 ms'de tamamlanıyor; yaklaşık 14 MB GPU belleği kullanarak 100 FPS'nin üzerinde çalışıyor ve 6 ms'lik bütçenin çok altında kalıyor. İki temel iddia da pratikte doğrulandı. Gün batımı, render sistemine sinematik bir his kazandıran başlıca sahne ve günün her saati için ayrı ayar yapmaya gerek kalmadan doğrudan fizikten ortaya çıkıyor. Ayrıca güzel bir tesadüf var: bulut katmanı 800 m ile 4000 m arasında parametrelendirildiğinde, alçak bir kameradan bakılan ufuktaki uzak bulutlar koyu dağ sırtları gibi görünüyor. Böylece kimsenin arka plan arazisi modellemesine gerek kalmadan dünyaya arka plan arazisi kazandırılıyor.
Saklanmaya değer bir mimari not. Doğal yaklaşım, önce gökyüzünü swap chain'e çizmek, ardından three.js'in autoClear = false ile geometrileri bunun üzerine çizmesine izin vermek. Ancak bu yöntem r184'teki WebGPU renderer ile çalışmıyor; çünkü bu bayrak, WebGL'de olduğu gibi renk yükleme işlemini denetlemiyor ve three.js her karede gökyüzünün üzerine yazıyor. Çözüm, three.js'i ekran dışı bir hedefe render etmek ve nihai kompoziti (mix(skyCloud, scene, scene.alpha), ardından ACES ve sonra sRGB) swap chain'in sahibi olan kendi geçişimizde gerçekleştirmek.
Ancak örtücüleri kadar iyi olan bir ayıklama sistemi
Spike 44'ü yeni sekmede aç ↗ · Kaynak kodunu görüntüle
Spike 44 dört render modunu birbiriyle karşılaştırıyor: düz ileri render, CPU küme ayıklaması, GPU compute ayıklaması ve Hi-Z örtülme ayıklaması kullanan bir görünürlük tamponu. İlginç olan Hi-Z yolu ve burada sessiz bir hata vardı: HUD, örtülmenin açık olduğunu söylüyordu ancak “Hi-Z tarafından elendi” sayacı sonsuza kadar tam olarak %0,0'da kalıyordu. Görüş hacmi ayıklaması çalıştığına göre ayıklama shader'ının önceki aşamaları sağlamdı. Örtülme kısmı ise tam maliyetine rağmen hiçbir şey yapmıyordu.
Hi-Z örtülme testi, bir kümenin sınırlayıcı kutusunu ekrana yansıtır, ekran dikdörtgeni yaklaşık 2×2 texel olacak şekilde bir derinlik piramidi mip seviyesi seçer, bu dikdörtgendeki en derin örtücü derinliğini örnekler ve kümenin en yakın noktası hâlâ bu örtücüden daha uzaktaysa kümeyi eler. Derinlik piramidi, mip 0'ın opak derinlik ön geçişinden başlatılıp yukarı doğru maksimum indirgeme uygulanmasıyla her karede oluşturulur. Opak ön geçiş kasıtlı olarak yalnızca katı örtücüleri, yani zemini ve her ağaç için gövde vekillerini içerir; çünkü alfa testli yapraklar, maksimum indirgemeyi yanıltan boşluklar açar.
Hata mantıksal değil, geometrikti. Gövde vekili 0,5 m × 4 m × 0,5 m boyutlarında bir kutuydu. 30 m uzaklıkta ekranda yaklaşık 17 piksele yansıyordu. Ancak tipik bir 50 m'lik çim kümesi, her texel'in 32 kaynak pikseli kapsadığı mip 5'i seçer. 17 piksellik bir gövde, tek bir mip-5 texel'ini tamamen kaplamaz; dolayısıyla gövdeye temas eden her texel çevredeki zemine de temas eder. Daha ilk 2×2 maksimum indirgeme, daha büyük derinlik değerini, yani gövdenin arkasındaki daha uzak zemini seçer ve gövdenin derinliği ilk indirgemede silinir. Mip 5'e gelindiğinde piramit neredeyse her yerde zemin derinliğini tutar, küme hiçbir zaman zeminden daha uzakta olmaz ve hiçbir şey örtülü sayılmaz.
Çözüm, vekili düştüğü texel'lere hâkim olacak kadar büyütmek ve boyutlarını ağacın odunsu kısmına değil silüetine göre belirlemektir. Yaklaşık 2 m × 6 m × 2 m boyutlarındaki bir vekil hâlâ gerçek taçtan daha küçüktür; dolayısıyla boşluklardan görünen yapraklar gereğinden fazla ayıklanmaz. Buna rağmen önemli mesafelere kadar maksimum indirgemeden sağ çıkacak kadar büyüktür ve örtülme sayacı hemen sıfırın üzerine çıkar. Buradan çıkan sonuç, üretim motoru için genel bir kurala dönüşüyor: Hi-Z örtücüsü olarak güvenilen her şey, ekrandaki silüetine göre boyutlandırılmalıdır. Çünkü açık bitki örtüsü sahnelerinde Hi-Z'nin etkinliğini derinlik testi matematiğinin zarafetinden çok, ilgili mip seviyesindeki örtücü kapsamı belirler. Bir çim yaprağı altındaki zeminle aynı derinlikte bulunduğundan çimin çimi örtmesi zaten mümkün değildir; asıl kazançlar ağaçların uzaktaki bitki örtüsünü ve diğer ağaçları örtmesinden gelir.
Bu bölümde değinilen teknolojiler
Hillaire 2020 atmosfer LUT'ları. Yalnızca güneş hareket ettiğinde yeniden hesaplanan bir geçirgenlik tablosu (güneş ışığının Rayleigh, Mie ve ozon profilinden geçişi) ile doğrusal olmayan ufuk parametrelendirmesine sahip, her karede hesaplanan bir gökyüzü görünüm tablosu; elle ayarlanmış bir gradyan olmadan günün saatini izleyen fizik tabanlı gökyüzü ve güneş renkleri sağlar. Bir artefakt gerçek tablonun hazırlanmasını zorunlu kılana kadar tam tablo yerine analitik bir çoklu saçılma yaklaşımı kullanılır. Gün batımı, günün her saati için ayrı ayar yapılmadan doğrudan fizikten ortaya çıkar.
Schneider Nubis hacimsel bulutları. Açılışta hazırlanmış ve 32³ Worley dokusuyla aşındırılmış 128³ Perlin-Worley dokusunun biçimlendirdiği yatay bir katman boyunca ray-march uygulanır; ışıklandırmada Beer yasası sönümlenmesi, çift loblu faz ve pudra terimi kullanılır. Bulutun güneş rengini her adımda aynı geçirgenlik tablosundan örneklemek, bulut aydınlatmasının gün doğumunu ve gün batımını hiçbir ek maliyet olmadan izlemesini sağlar. Standart üretim dengesi olarak yarım çözünürlüklü ray-march, tipik izleme mesafesinde görünür kalite kaybı olmadan tam çözünürlüğe göre yaklaşık 4 kat daha ucuza çalışır.
r184'te ham WebGPU'yu three.js ile birleştirme. Gökyüzünü swap chain'e çizip three.js geometrisini autoClear = false ile bunun üzerine render etmek başarısız olur; çünkü bu bayrak WebGPU arka ucunda renk yükleme işlemini denetlemez. three.js'i ekran dışı bir RGBA16F hedefine render edin ve nihai mix, ton eşleme ve sRGB işlemlerini swap chain'in sahibi olan bir geçişte gerçekleştirin.
Hi-Z örtülme ayıklaması ve örtücü boyutlandırma. Maksimum indirgemeyle oluşturulan bir derinlik piramidi, GPU ayıklama geçişinin en yakın noktası ekran dikdörtgenindeki en derin örtücünün arkasında kalan kümeleri elemesine olanak tanır. Örtücüler seçilen mip seviyesinde bir texel'e hâkim olamayacak kadar küçükse test sessizce hiçbir şey yapmaz; çünkü ilk maksimum indirgeme, örtücünün derinliğini onun arkasındaki daha uzak arka planla değiştirir. Örtücüler fiziksel çekirdeklerine göre değil, ekrandaki silüetlerine göre boyutlandırılmalıdır. Bkz. GPU güdümlü LOD.
29 bölümden 22.'si. Önceki: 21. Bölüm - Daha hızlı olmayan, daha hızlı bir renderer Sonraki: 23. Bölüm - Elli avatar ve odadaki bir ses Seri rehberi: /blog/2026-02-25-open-world-browser-series-guide