holodepth

Three.js · Varlık optimizasyonu · LOD

LOD sistemi: mesafeye göre adaptasyon

Level of Detail (LOD), aynı objenin farklı poligon yoğunluklarına sahip versiyonlarını bellekte hazır tutup kameraya göre seçen bir stratejidir. Amaç, uzakta görünmeyen detay için GPU bütçesi yakmamak ve geçişleri fark edilmez hale getirmektir.

LOD mantığı: mesafeye göre adaptasyon

LOD sistemi, aynı objenin farklı poligon yoğunluklarına sahip versiyonlarını (LOD 0, LOD 1, LOD 2…) bellekte hazır tutar. Kamera objeye yaklaştıkça detay artar; uzaklaştıkça poligonlar ve doku kalitesi basitleşir.

  • Yakın (LOD 0 — High Detail): Kullanıcının burnunun ucundaki modeldir. Yüksek poligon, yüksek çözünürlüklü dokular ve (gerekliyse) daha ağır shader’lar aktiftir. Bu seviyeyi «her zaman» değil, yalnızca yakın plan olacağı kesin objelere ayırın: karakter yüzü, ana ürün, etkileşimli kahraman nesne gibi. Mikro detayları geometriyle şişirmek yerine çoğu zaman bake edilmiş normal map + iyi materyal daha iyi maliyet/kalite verir.
  • Orta (LOD 1 — Medium Detail): Obje biraz uzaklaştığında devreye girer. Poligon sayısı yaklaşık %40–%50 azaltılır; küçük detaylar dokuya (örn. normal map) devredilir. Hedef, «detayı öldürmek» değil, silueti koruyup iç yüzey karmaşıklığını sadeleştirmektir. Bu seviyede UV/normal tutarlılığı önemlidir: LOD geçişinde ışık tepkisi bir anda değişirse göz onu poligon atlaması gibi algılar.
  • Uzak (LOD 2+ — Low Poly): Objeyi sadece ana silüetiyle taşıyan çok düşük poligonlu versiyondur. Bazı durumlarda iki poligonlu bir resim (billboard) bile yeterli olur. Pratik ölçüt: obje ekranda çok küçük bir alan kaplıyorsa, yüksek poligon «daha iyi» görünmek yerine titreme/aliasing üretebilir. Bu yüzden uzak seviyelerde geometriyi agresif azaltmak, hatta tamamen billboard’a düşmek çoğu sahnede daha temiz sonuç verir.

İyi bir sezgi: LOD kararını «metre» ile değil, objenin ekrandaki piksel alanı ve siluet algısı ile verin. Aynı mesafe, farklı FOV ve ekran boyutunda farklı görünür.

Tek obje, 3 seviye LOD — en kritik fark: hard switch (popping) vs smooth (dither) ve silüet koruması Pedagogy demo
Geçiş kalitesi

Seçilen LOD

Mesafe eşiklerine göre LOD0 / LOD1 / LOD2.

Tris (yaklaşık)

Popping skoru (0–100): hard switch + silüet bozulması artınca yükselir.

Skor:

Bu demo eğitim içindir; gerçek projede LOD seçimi THREE.LOD + gerçek mesh’ler ile yapılır. Burada amaç popping ve silüet korumasını gözle görülür hale getirmektir.

Mini doğrulama (Three.js · THREE.LOD)

Üstteki panel kavramı hızlıca öğretir; buradaki küçük sahne aynı fikri gerçek WebGL seçimi ile kısa süreliğine doğrular: üç torus seviyesi, kamera Z slider’ı ve bu karede çizilen üçgen sayısı.

WebGL doğrulama

lod.update(camera) çağrısı animasyon döngüsünde çalışır; mesafe büyüdükçe motor daha düşük segmentli geometriyi seçer.

Bağ: Üstteki popping ve silüet farkı burada gerçek mesh değişimiyle oluşur; bu sahne LOD’un motor tarafındaki karşılığıdır.

Bu blok üretim kalitesi iddiası taşımaz; yalnızca dokümantasyon içi hızlı «motorla aynı dilde konuşma» içindir.

Amaç: gereksiz GPU yükünü kaldırmak

Neden her şeyi her zaman en yüksek kalitede çizmiyoruz? Çünkü «uzakta görünmeyen detay», çoğu zaman yalnızca maliyettir.

Piksel başına düşen poligon

Eğer bir obje ekranda yalnızca 10×10 piksel yer kaplıyorsa, onu 100.000 poligon ile çizmek matematiksel bir israftır. GPU piksellerden daha küçük üçgenleri işlemeye çalışırken aliasing (titreme) ve gereksiz performans kaybı doğar.

VRAM ve bant genişliği

Uzaktaki objelerde daha küçük dokular (low texture) seçmek, ekran kartı belleğinde ve bant genişliğinde ciddi yer açar. Bu boşluk, sahnenin «yakın» kısımları için gerçek kaliteye dönüşür.

Kritik unsur: fark edilmeyen geçişler (popping)

LOD sisteminin en büyük zorluğu, model değişim anının kullanıcı tarafından fark edilmesidir. Buna 3D dünyasında «popping» denir. Bunu azaltmak için:

  • Hysteresis (eşik payı): Modelin sürekli iki seviye arasında gidip gelmesini (titreme) engellemek için geçiş mesafelerine küçük bir pay ekleyin. Örn. 10m’de LOD1’e geçiyorsanız, geri dönüşü 9m yerine 8m yapın; böylece kamera küçük salınım yaptığında seviye sürekli «zıplamaz».
  • Cross-fading / dithering: Bir model yok olurken diğeri şeffaf bir şekilde belirsin; poligonların «atlaması» göze batmaz. Bu yaklaşım özellikle geçiş anını “yumuşatır” ama doğru uygulanmazsa şeffaflık sıralaması ve parıltı artefaktları üretebilir; bu yüzden dither tabanlı cross-fade çoğu motorda daha güvenli bir seçenektir.
  • Silüet koruması: Poligon azaltılırken objenin dış hatları korunmalıdır. İç detaylar gidebilir; silüet sabitse geçiş çok daha zor fark edilir. Basit test: modeli siyah “flat” bir malzemeyle (gölgesiz) sadece silüet olarak izleyin; LOD değişiminde hat «oynuyorsa» popping kaçınılmaz olur.

Kural: LOD değişimini fark ettiren şey çoğu zaman üçgen sayısı değil, silüet ve ışık tepkisidir. Bu yüzden seviyeler arasında normal yönleri, sert kenarlar ve materyal parametreleri mümkün olduğunca tutarlı kalmalıdır.

HoloDepth uygulama rehberi: LOD stratejisi

Aşağıdaki tablo «tek doğru» değildir; ama sahne ölçeği ve cihaz hedefinize göre hızlı bir başlangıç çerçevesi sunar.

Seviye Mesafe (örnek) Poligon oranı Doku durumu
LOD 0 0m – 10m %100 (Full) 2K / 4K KTX2
LOD 1 10m – 50m %40 – %50 1K / 512px
LOD 2 50m – 150m %10 – %15 256px veya no normal map
LOD 3 150m+ 2–4 tris (billboard) 128px (flat image)

Teknik not: Three.js’te THREE.LOD

Three.js içinde hazır bir THREE.LOD sınıfı vardır. Farklı modelleri ve hangi mesafede görüneceklerini addLevel ile eklersiniz.

const lod = new THREE.LOD();

// Mesh’ler örnek: yakın / orta / uzak (mesafe: kamera-lod pozisyonu arası)
lod.addLevel(lod0Mesh, 0);
lod.addLevel(lod1Mesh, 10);
lod.addLevel(lod2Mesh, 50);

scene.add(lod);

function animate() {
  requestAnimationFrame(animate);
  lod.update(camera); // kritik: kamera hareketinde LOD seçimi güncellensin
  renderer.render(scene, camera);
}
animate();

İpucu: lod.update(camera) çağrısını render döngüsünde yapmayı unutmayın; aksi halde kamera hareket etse bile seviye değişmez.