Three.js · Performans · Draw call
Draw call nedir? (İşlemcinin GPU'ya mektubu)
Draw call, CPU'nun ekran kartına «Şu materyalle, şu geometriyi, şu durumda çiz» diye gönderdiği komut paketidir. Her bağımsız çizim yolu, işlemci tarafında hazırlık ve sıra maliyeti doğurur.
Her mesh (ve çoğu durumda her farklı materyal kombinasyonu) için motor bir komut üretir. GPU poligonu çizmekte ustadır; asıl tıkanıklık çoğu zaman komutların hazırlanması ve kuyruğa dizilmesidir. Bu sayfada neden sorun olur, sayıyı artıran gizli faktörler, optimizasyon üçlemesi, renderer.info özeti ve canlı simülatör yer alır; simülatörde draw call sayısını sahne yapısına göre karşılaştırabilirsiniz.
Draw call düşürmek, yalnızca «daha az nesne» demek değildir: aynı görsel zenginliği daha az komutla sunmak — atlas, birleştirme ve örneklem gibi stratejilerin tamamı bu yüzden vardır.
Neden fazla olunca sorun çıkar?
GPU saniyede çok yüksek hacimde üçgen işleyebilir; fakat CPU'nun bu komutları hazırlayıp sürücü ve grafik API üzerinden iletme hızı sınırlıdır. Her pakette durum değişimi (materyal, tampon, shader, birleştirme vb.) ek yük taşır.
CPU darboğazı: Örneğin sahnede 2000 bağımsız nesne varsa, işlemci her karede binlerce komut hazırlamak zorunda kalabilir. GPU boşta beklerken kare süresi uzar; profilde sık sık draw call veya sürücü tarafı zamanı görürsünüz.
FPS düşüşü: İşlemci komut trafiği altında ezildiğinde saniyedeki kare sayısı hızla düşer. On milyon üçgen tek veya birkaç yoldan gönderilebiliyorsa, aynı toplam yükü binlerce küçük yolla bölmek çoğu zaman daha kötü hissettirir — çünkü darboğaz artık piksel başına değil, komut hazırlığı tarafındadır.
Draw call’u artıran gizli faktörler
Bir önceki bölümde darboğazı komut hazırlığı tarafında konumladık. Burada ise grafiğe baktığınızda «nesne sayısı kadar yol vardır» varsayımını bozan şeyler var: aynı düğüm sayısıyla bile, aşağıdaki seçimler toplam çizim yolunu çarpar veya tek görünür nesne altında gizli geçişler açar.
- Materyal ayrımı (farklı material): Geometri aynı kalsa bile, her farklı materyal genelde ayrı shader / pipeline durumu demektir; motor her geçiş için ayrı paket hazırlar. Örneğin 100 küpünüz var ve her biri farklı bir Material kullanıyorsa, tipik olarak 100 ayrı yol doğar — üçgen sayısı düşük olsa bile.
- Çoklu materyal (multi-material): Bu madde «çok mesh» değil, tek mesh içinde yüzey gruplarını ayırmayı anlatır: farklı yüzlere farklı materyaller verdiğinizde motor çoğu zaman her alt grup için ayrı geçiş yapar. Dışarıdan tek parça görünen model, profilde birden fazla yol üretebilir.
- Işık ve gölgeler: Gölge haritası üreten her ışık, derinlik için sahneyi ek turlarda işler; toplam yük, ışık sayısı, hangi nesnelerin gölge alıcısı olduğu ve motor ayarlarına göre katlanarak artar. Bu yüzden ışık/gölge planı, performansı «sonradan» değil erken düşünülen bir karardır; kesin çarpan proje ve sürüme göre değişir.
Bu çarpanlar, bir sonraki bölümdeki atlas / birleştirme / örneklem üçlemesinin neden anlamlı olduğunu açıklar; çözüm ayrıntıları orada toplanır.
HoloDepth’te aynı baskıyı doğrudan hedefleyen içerikler: çok kopya için Instance paylaşımı (canlı lab) · birden çok örgüyü tek çizim yoluna indirgeme için Örgü birleştirme (sayfada buffer birleştirme akışı).
Optimizasyon stratejileri (HoloDepth reçetesi)
Aşağıdaki üçlü, çoğu WebGL / Three.js projesinde draw call trafiğini kontrol altına almak için temel pusuladır; proje türüne göre birini veya üçünü birlikte kullanırsınız.
A. Texture atlas (doku atlası)
On küçük nesnenin on ayrı dokusu ve on ayrı materyali varsa, tipik olarak on ayrı yol doğar. Dokuları tek bir büyük görselde birleştirip UV ile atlas bölgelerine ayırırsanız, aynı görünümü tek materyal altında toplayıp yol sayısını ciddi biçimde düşürebilirsiniz.
B. Static & dynamic batching
Hareket etmeyen veya uyumlu geometrileri tek büyük tampon veya birleşik örgüde toplamak (merge), CPU'nun tek komutla geniş bir alanı göndermesini sağlar. Dinamik taraf için motorun veya eklentilerin sunduğu toplu birleştirme kurallarını okumak gerekir; her birleşim «tek yol» demek değildir ama doğru kullanımda kazanç yüksektir.
C. Instanced rendering
Aynı geometri ve materyalin binlerce kopyası (InstancedMesh vb.), tek çizim yolunda örnek matrisleri veya öznitelik tamponları ile gönderildiğinde komut sayısı dramatik düşer. Ağaçlar, mermiler, sütun gibi tekrarlayan içerikler için ilk tercih seviyesindedir.
Canlı lab · Draw call patlaması · r170
Gerçek dünyada birleşimler her zaman düzenli grid değildir.
Materyal sayısı → Bu labda çizim yolunu tek başına değiştirmez. → Atlas / birleştirme / toplu çizim fırsatını etkiler.
HoloDepth teknik notu: renderer.info
Three.js projelerinde son karenin özetini görmek için konsolda (veya kendi HUD'unuzda) şunu kullanabilirsiniz:
console.log(renderer.info.render.calls);
Aşağıdaki aralıklar öğretici eşik niteliğindedir; cihaz, çözünürlük ve içerik türüne göre «iyi» sayı kayar. Yine de hızlı bir iç kontrol listesi olarak kullanılabilir.
| Draw call (yaklaşık) | Yorum |
|---|---|
| 0 – 100 | Mükemmel — mobil ve düşük güçlü cihazlarda bile genelde rahat. |
| 100 – 500 | İyi — modern masaüstü tarayıcılar için sık görülen hedef bandı. |
| 500 – 1000 | Dikkat — orta segment donanımda kare zamanı dalgalanmaya başlayabilir. |
| 1000+ | Tehlike — acil profil ve optimizasyon (atlas, birleştirme, örneklem) düşünün. |
Ölçüm notu
renderer.info kare sonunda güncellenir; bazı sürümlerde sayaçları
sıfırlamak için renderer.info.reset() kullanılır. Profil ile birlikte
okuyun: düşük FPS her zaman yüksek yol sayısından gelmez, ama
yol sayısı sürekli dört hanelere çıkıyorsa ilk bakılacak yerlerden biridir.