Three.js · Geometri
Attributes ve Buffer’lar (veri katmanları)
Geometri = GPU’ya giden sayılar
Three.js’te bir geometri, GPU belleğine aktarılan bir dizi sayıdan ibarettir. Bu sayılar rastgele değil; BufferAttribute adı verilen yapılarda, belirli bir düzende (interleaved veya sequential) saklanır. GPU, bu buffer’lar üzerinden okuma yaparak her bir noktayı ekrandaki piksellere dönüştürür.
Attribute nedir?
Attribute = her vertex için tekrar eden veri bloğu. Yani “modelin verisi” dediğiniz şey, aslında vertex sayısı boyunca tekrar eden sütunlardır: position, normal, uv, color…
GPU bir shader’ı çalıştırdığında her vertex için şu soruları sorar:
- Position: Neredesin?
- Normal: Nereye bakıyorsun?
- UV: Üzerine hangi doku (texture) parçasını giyeceksin?
- Color: (Eğer varsa) Senin rengin ne?
GPU her vertex için attribute’ları tekrar tekrar okur. Yani 1000 vertex
varsa position, normal, uv gibi tüm attribute’lar
1000 kez işlenir.
Three.js tarafında bunların hepsi geometride bir isimle tutulur:
geometry.attributes.position, normal, uv,
color vb.
Typed Arrays ve BufferAttribute
JavaScript’in standart dizileri (Array) esnektir ama grafik tarafında veri
transferi için pahalıdır. Bu yüzden TypedArray (özellikle
Float32Array) kullanılır: bellekte kesintisiz bir blok kaplar; GPU veriyi tek
bir hamlede “yutabilir”.
Item size, bir attribute’un kaç bileşenden oluştuğunu belirtir:
positioniçin 3 (x, y, z)uviçin 2 (u, v)normaliçin 3 (x, y, z)
Teknik tablo: buffer tipleri ve kullanım amaçları
| Buffer türü | İçerik | GPU rolü |
|---|---|---|
StaticDraw |
Çoğu geometri için varsayılan senaryo (küp, küre, statik mesh). | Default düşün: Veri genelde bir kez yüklenir, çok hızlı okunur. |
DynamicDraw |
Vertex sürekli değişiyorsa (animasyon, dalga, deformasyon). | Önemli: Sık güncelleme için; CPU→GPU akışı vardır. |
StreamDraw |
Çok nadir güncellenen veriler. | Nadir: Bazı akış senaryoları için; çoğu projede gerekmez. |
GPU’ya veri gönderme: interleaved vs sequential
Profesyonel projelerde veriyi nasıl dizdiğiniz, GPU’nun önbellek (cache) davranışını etkiler.
- Sequential (ardışık): Önce tüm konumlar, sonra tüm normaller yazılır. CPU tarafında üretmesi ve yönetmesi kolaydır (Three.js default).
-
Interleaved (iç içe): Bir vertex’in konumu, normali, rengi bellekte yan
yana yazılır:
[pos, norm, col, pos, norm, col]. GPU tek bir okumada o vertex hakkındaki her şeyi aldığı için büyük veri setlerinde cache performansı daha iyi olabilir.
Kısa karar rehberi: “önce doğru çalışsın” diyorsanız sequential; veri setiniz devasa ve erişim paterni netse interleaved bazı GPU’larda daha iyi çıkabilir. (Her cihazda garanti değil; ölçmek gerekir.)
Görsel şema: aynı veri, iki farklı dizilim
Aşağıdaki şema, GPU’nun bellekte “nasıl yürüdüğünü” hissettirir. Solda ardışık kanallar, sağda vertex başına paketlenmiş kayıtlar:
Sequential → yönetimi kolay (Three.js default) · Interleaved → cache dostu olabilir (büyük veri).
| Sequential (kanal kanal) | Interleaved (vertex vertex) |
|---|---|
|
|
Uygulama: özel bir attribute eklemek
Sadece konumu değil, her vertex’e rastgele bir “boyut” veya “hız” bilgisi ekleyip shader’da
kullanmak için, yeni bir TypedArray oluşturup geometriye isimle bağlarsınız. GPU bu veriyi
shader içinde attribute float aSize olarak tanır.
Bağlantı şu: bu değer, vertex shader’da bir hesapta “çarpan” olur. Örneğin point cloud
çiziyorsanız:
gl_PointSize = aSize * 10.0;
const geometry = new THREE.BufferGeometry();
const count = 5000;
// Her vertex için 1 değer (itemSize: 1)
const sizes = new Float32Array(count);
for (let i = 0; i < count; i++) {
sizes[i] = Math.random(); // 0 … 1 arası rastgele ölçek
}
// 'aSize' adında özel bir attribute oluşturuyoruz
geometry.setAttribute('aSize', new THREE.BufferAttribute(sizes, 1));
// GPU bu veriyi shader içerisinde 'attribute float aSize' olarak tanıyacak.
attribute float aSize;
void main() {
// ... position transform ...
gl_PointSize = aSize * 10.0;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
Mini araç: attribute belleğini anında hesapla
“Bu geometri kaç KB/MB yer tutar?” sorusu pratikte en çok iş yapan refleks. Aşağıdaki araç,
seçtiğiniz vertex sayısı ve attribute seti için yaklaşık ham veri boyutunu
hesaplar — Three.js’te sık kullanılan Float32Array / Float32
varsayımıyla (her bileşen 4 byte).
Bu bir GPU sürücü raporu değildir: index buffer, geometri
meta verisi, InterleavedBuffer hizalama dolgusu ve doku belleği dahil
değildir; ama “sadece bu dört attribute ile kaç MB büyür?” tahmini için hızlı bir cetvel
işlevi görür.
Attribute bellek sayacı
Float32 · canlı tahmin
Satır satır (Float32)
- position —
- normal —
- uv —
- color —
index buffer ve geometri ötesi bellek bu toplama dahil değildir.
Holodepth notu: bellek bütçesi
Attribute’lar çok hızlı büyür: önce ihtiyacı ölç
Her bir Float32Array elemanı bellekte 4 byte yer kaplar.
1 milyon vertex’li bir modelde sadece position verisi bile yaklaşık
12 MB (\(1{,}000{,}000 \times 3 \times 4\) byte) yer tutar.
Normaller, UV’ler ve diğer attribute’lar eklendikçe bu miktar hızla artar. Mobil cihazlarda çökme yaşamamak için her zaman ihtiyacınız olmayan attribute’ları temizleyin ve gerekiyorsa LOD / basitleştirme stratejileri kullanın.