holodepth

Three.js · glTF pipeline · Materyal

Materyal anatomisi: Texture bağlama (texture binding)

Bir dokuyu yüklemek yolun yarısıdır; asıl iş, bu dokunun bir materyale doğru slotlar üzerinden bağlanmasıdır. PBR akışında her doku, yüzeyin farklı bir fiziksel özelliğini kontrol eden ayrı bir «giriş» gibi davranır — yanlış slotta doğru piksel bile yanlış fizik üretir.

Yanlış slota bağlanmış bir doku, rengi veya parlaklığı fiziksel olarak tutarsız gösterebilir; renk uzayı (color space) ve ikinci UV kanalı (aoMap vb.) gibi ayrıntılar gözden kaçmamalıdır. Önceki pipeline adımında düğüm ağacını gördük; bu sayfada materyal yüzeyindeki doku yuvalarına odaklanıyoruz — dosyanın glTF alanlarını Three.js özelliklerine kim eşliyor sorusu ise bir sonraki konuda.

Önce okuyun: Node hiyerarşisi, Materyal girişi, Doku temelleri, Albedo / base color.

Slot tabanlı bağlama (texture slots)

Three.js materyalleri, belirli doku türleri için ayrılmış slotlara sahiptir. Bir dokuyu yanlış slota vermek, PBR tutarlılığını bozar. GLTFLoader çoğu eşlemeyi dosyadan üretir; elle müdahale ettiğinizde ise aşağıdaki isimleri doğrudan materyal özellikleriyle eşleştirmeniz gerekir.

map (albedo / diffuse)

Ana renk bilgisi; yüzeyin taban rengini besler. color ile birlikte nasıl çarpıldığını bir sonraki bölümde özetliyoruz; renk uzayı ayarı için doku temelleri sayfasına bakın.

normalMap

Yüzeye detay ve yapay girinti için RGB teğet uzayı; renk değil, yön verisi olduğundan color space tarafında genelde nötr işlem gerekir (örnek kodda NoColorSpace).

roughnessMap & metalnessMap

Pürüzlülük ve metalik karakter; çoğu üretim hattında tek kanallı dokular veya birleşik ORM (occlusion + roughness + metalness) paketlemesi kullanılır — böylece ayrı dosya sayısı ve texture unit yükü azalır.

aoMap (ambient occlusion)

Girintilerde ek gölgelenme çarpanı; Three.js tarafında ikinci UV seti (uv2) beklenir — aksi halde etki görünmez veya beklenmedik örneklenir.

İnteraktif: slot micro-demo

Büyük bir sahne modeli şart değil; bağlama fikri için küçük bir küp yeter. Aşağıda prosedürel map, normalMap ve aoMap dokularını açıp kapatın — yanlış slotta renk (albedo) dokusunun doğrudan normalMape verildiğinde yüzeyin nasıl bozulduğunu gözlemleyin.

PBR slot lab · prosedürel doku · Three.js r170

Amaç: Aynı geometride hangi slotun görünür etki verdiğini ayırt etmek; normalMap kapanınca kabartmanın kaybolması, aoMap ile gölgelenme çarpanının artması ve yanlış slotta renk verisinin teğet alanı olarak yorumlanması. Araba modeli gerekmez — bağlama mantığı materyal üzerindedir.

Matematiksel bağlam: çarpma

Bir map bağlandığında özetle şu sezgisel model geçerlidir:

Sonuç ≈ (doku pikseli) × (materyalin color sabiti)

Bu, albedo / base color yolunda renk tonunun hem dokudan hem de materyalin çarpan renginden geldiği anlamına gelir; ikisini aynı anda «tam güç» kullanmak kontrastı şişirir ve tonu tahmin etmeyi zorlaştırır.

Beyaz map, renkli color

Doku pikseli beyaza yakınsa çarpan etkisi azdır; sonuç büyük ölçüde color’ın tonuna yaklaşır (ör. kırmızı tint + beyaz doku ≈ kırmızı yüzey).

Siyah veya koyu map

Koyu texeller çarpanı düşürür; gölge ve leke detayları doğal olarak yüzeyi karartır. Tam siyaha yakın bölgelerde sonuç neredeyse siyah olur.

Pratik kural

Tüm renk bilgisini texture’da toplamak istiyorsanız color’ı genelde 0xffffff (nötr) bırakın; tersine ince bir «filtre» veya marka rengi eklemek istiyorsanız dokuyu daha nötr tutup color ile oynayın.

Diğer slotlar (normalMap, roughnessMap vb.) çoğu PBR materyalinde ayrı matematikle birleşir; buradaki çarpma sezgisi özellikle map + color çifti için geçerlidir.

Texture units ve donanım limitleri

Her bağlı doku, GPU tarafında bir doku birimi (texture unit) tüketir. Fragment shader her karede bu birimler üzerinden ilgili sampler’lardan okuma yapar; bağladığınız her map, normalMap, roughnessMap vb. ayrı bir örnek kanalı işgal eder.

Limit

Cihaza göre tipik olarak yaklaşık 8–16 birim görülür. Kesin üst sınır WebGL bağlamında gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) ile ölçülür; parça gölgeleri, post işlemleri veya ek geçişler aynı bağlamda başka dokular da kullanıyorsa toplam bütçe daha çabuk dolar.

Risk

Tek yüzeyde «her şeyi ayrı doku» modeli (özellikle 10–12+ örnek), mobilde program derlemesinin başarısız olmasına, siyah materyale veya beklenmedik düşüşlere yol açabilir. Sınır aşımı her zaman aynı hatayla raporlanmayabilir; sahneyi düşük uç cihazda test edin.

Çözüm: paketleme ve birleştirme

Roughness, metalness, AO kanallarını tek bir dokuda R/G/B olarak birleştirmek (ORM vb.) yaygındır. Benzer şekilde küçük detayları atlas içinde toplamak da çağrı başına doku sayısını düşürür.

Özet: limit yalnızca «dosya sayısı» değil, aynı çizim geçişinde bağlı eşzamanlı örnek sayısıdır; malzeme tasarımını buna göre sade tutmak web hedefi için kritiktir.

Güncelleme ve needsUpdate

İki farklı «güncelleme» vardır: üniform / örnek güncellemesi (aynı shader programı çalışmaya devam eder) ile programın yeniden oluşturulması (materyal tanımı değiştiği için shader yeniden derlenir).

Yalnızca mevcut bir dokuyu başka bir Texture örneğiyle değiştiriyorsanız (material.map = newTexture) çoğu durumda Three.js örnek atamalarını günceller; bu tip değişimlerde her kare tam yeniden derleme gerekmez.

material.needsUpdate = true ne zaman?

Daha önce kullanılmayan bir slot ilk kez dolduruluyorsa (ör. başta map yoktu, sonra atandı), transparent / alpha test gibi program dallarını değiştiren bayraklar açılıyorsa veya materyal sınıfı / özellik seti kökten değişiyorsa tam yeniden derleme gerekir; bu durumda
material.needsUpdate = true ile yeni program üretimini isteyin.

texture.needsUpdate

Doku piksel verisini (canvas, video, dinamik DataTexture) her kare güncelliyorsanız texture.needsUpdate = true gerekir; bu, materyal programını değil dokunun GPU yüklemesini ilgilendirir.

Kısa kural: aynı materyal «şekli» içinde doku değiştirmek hafif; hangi slotların dolu olduğu veya hangi özelliklerin açık olduğu değişiyorsa ağır — o zaman material.needsUpdate devreye girer.

Bellek yönetimi ve dispose

Kullanılmayan dokular VRAM’de birikebilir. JavaScript’te referansı düşürmek (material.map = null) nesneyi bellekten silmez; GPU tarafındaki WebGLTexture kaynağı texture.dispose() ile serbest bırakılmalıdır.

Önerilen sıra

Materyal veya mesh hâlâ sahneye bağlıyken önce dokuyu materyalden ayırın veya yenisini atayın; ardından eski Texture üzerinde dispose() çağırın. Gerekirse material.needsUpdate = true ile bağlayıcıyı yeni duruma göre yenileyin.

Model yükleme / kaldırma

glTF yükleyicisi ile gelen dokuları tek tek paylaşan başka materyaller olabilir; bir varlığı sahneden çıkarırken yalnızca o modele özgü dokuları serbest bırakın veya ortak önbellek kullanıyorsanız referans sayısını takip edin.

Diğer kaynaklar

Aynı mantık BufferGeometry ve Material için de geçerli: geometry.dispose(), material.dispose() ile eşlik eden önbellekleri temizleyin; uzun oturumlu web uygulamalarında bu üçlü alışkanlık sızıntıyı önler.

JavaScript uygulaması

Aşağıdaki örnek, MeshStandardMaterial üzerinde tipik PBR slotlarını ve veri dokuları için renk uzayı işaretini gösterir. Dosyadan gelen otomatik eşleme ve glTF uzantıları Material mapping konusunda; burada yalnızca elle bağlama iskeleti vardır.

// Örnek PBR bağlama (MeshStandardMaterial)
const material = new THREE.MeshStandardMaterial({
  color: 0xffffff,
  map: colorTexture,
  normalMap: normalTexture,
  aoMap: aoTexture,
  aoMapIntensity: 1.5,
});

// Veri dokuları (renk değil)
normalTexture.colorSpace = THREE.NoColorSpace;
aoTexture.colorSpace = THREE.NoColorSpace;

// AO ikinci UV kanalı gerektirir — genelde uv2
geometry.attributes.uv2 = geometry.attributes.uv;

HoloDepth «Binding» checkpoint’i

Özet

Bağlantı kalitesi, render kalitesidir: slot, renk uzayı ve UV kanalı hizası doğru değilse sonuç çabucak bozulur.

Sıradaki konu: geometri yükünü azaltan mesh compression ve Draco hattına geçiyoruz; giriş için Mesh compression (temel) sayfasından başlayın.

HoloDepth özet stratejisi

  • Cihaz limiti: Mobil uyumlulukta toplam doku birimi için 8–10 bandını hedefleyin.
  • Renk uzayı: Görsel dokuları sRGB tarafında tutun; matematiksel veri dokularını THREE.NoColorSpace ile işaretleyin.
  • Temizlik: Sahneden kalkan her varlık için texture.dispose() alışkanlığı oluşturun.