Three.js · Sahne & geometri
Geometrinin anatomisi ve veri yönetimi
3D web geliştirmede geometri, bir nesnenin uzaydaki fiziksel varlığını tanımlayan saf matematiksel veridir. Three.js'te bir objeyi "görmek", aslında GPU'ya binlerce noktanın koordinatlarını ve bu noktaların nasıl birleşeceğini söylemektir. Modern bir projede asıl iş, bu veriyi doğru yapılandırmak ve verimli taşımaktır.
Pratikte ekranda gördüğünüz cisim bir Mesh'tir:
geometri (shape; şekil) ile materyal (appearance; görünüş)
bir araya gelir; şekil verisi tek başına renk, parlaklık veya doku üretmez.
Materyal Giriş
sayfası bu ikinci yarıyı tamamlar.
3D veri katmanları: vertex'ten yüzeye
Dijital bir objenin iskeleti (shape verisi) üç katmandan okunur; materyal ve ışık bunların üstüne biner; sahne grafiği ( Object3D ) nesnenin nerede durduğunu, geometri ne şekilde olduğunu tanımlar:
- Vertices (noktalar): Uzaydaki
(x, y, z)(ve gerektiğinde normal, UV gibi) attribute verisinin atomik satırıdır — her şey buradan başlar.BufferGeometry'da çoğu zamanpositiondizisi olarak GPU'ya gider; binlerce köşe tek bir typed array içinde paketlenir. Noktayı kaydırmak, tüm bağlı kenar ve yüzeyleri dolaylı olarak etkiler. - Edges (kenarlar): İki vertex arasındaki bağ — çoğu zaman “iki index
yan yana” olarak düşünülür. Tam yüzeyli render’da kenarlar ayrı çizilmez; tel kafes
(wireframe) veya
EdgesGeometry/ çizgi materyali ile hata ayıklama ve teknik çizim hissi için görünür kılınır. Kenar, yüzeyden önce kavramsal bir ara basamaktır. - Faces (yüzeyler): En az üç vertex ile kapanan üçgen — GPU rasterization yalnızca üçgenleri ekrana çizer. Dörtgen yüz bile iki üçgene bölünür; karmaşık modeller “üçgen çorbası”dır — aşağıdaki triangulation paragrafı bunu geneller. Hangi üçgenin “ön” yüz sayılacağı vertex sırasına (winding) bağlıdır; hemen alt başlıkta.
Tüm modern GPU'lar, nihai olarak her yüzeyi üçgenlere indirger (triangulation); dörtgen veya daha karmaşık çokgenler bile rasterization aşamasında bu atomik üçgenlere ayrılır.
Winding order (vertex sırası): Bir üçgenin köşelerinin bağlanma yönü, yüzeyin "ön" mü yoksa "arka" mı olduğunu belirler. Ters bir sıralama, yüzeyin kameraya arkasını dönmesine ve materyal ayarlarınıza bağlı olarak görünmez olmasına (back-face culling) yol açar.
Hazır geometriler ve parametrik yaklaşım
Three.js, kodla anında üretilen primitive (ilkel) geometriler sunar; BoxGeometry, SphereGeometry, PlaneGeometry,
CylinderGeometry gibi. Bunlar parametrik formüllerle vertex ve üçgen üretir; Blender’dan gelen glTF ağının yerini öğrenme ve prototipte alır, üretimde çoğu zaman özel
mesh veya düşük segment bilinçli seçim tercih edilir. Ayrıntılı primitive listesi
Primitive geometriler
konusundadır; burada segment fikrini netleştiriyoruz.
- Segment sayısı: Küre, silindir veya düzlemde yüzeyi kaç parçaya
böldüğünüzdür (
widthSegments,heightSegments,radialSegments…). Segment arttıkça üçgen sayısı ve bellek artar; kenarlar daha yuvarlak, silüet daha pürüzsüz görünür. Öğrenirken “yüksek = güzel” alışkanlığı kolaydır; üretimde “yeterince düşük, yeterince iyi” hedeflenir — kameradan uzak zemin düşük segment, yakın hero nesne biraz daha yüksek olabilir. - Performans bütçesi: Gereksiz yüksek segment, vertex attribute ve draw maliyetini şişirir; mobil ve VR’da triangle bütçesi hızla dolar. Düşük poligonlu ( low-poly) geometri + iyi normal / PBR materyal çoğu zaman yüksek poligon + basit materyalden daha ikna edici ve hızlıdır — materyal tarafı şekli “tamamlar”. Primitive’ler de sonuçta BufferGeometry olarak GPU’ya gider; segment seçimi, o tamponun boyutunu doğrudan belirler.
BufferGeometry: GPU ile doğrudan iletişim
Modern Three.js'te performans kalbi BufferGeometry'dedir: vertex
verisi
Float32Array ve benzeri typed array'lerde paketlenir,
WebGL buffer nesnelerine yüklenir. Eski Geometry sınıfı
kaldırıldı; BoxGeometry gibi primitive'ler de arka planda bu yapıyı üretir
(segment
seçimi doğrudan tampon boyutunu etkiler). Amaç, her karede binlerce
Vector3 nesnesi oluşturmak yerine tek seferlik, GPU'ya uygun bellek
düzenidir.
- Hız: Veri bir kez (veya seyrek) CPU’dan GPU’ya gider; çizim sırasında
yalnızca buffer referansları kullanılır — RAM ↔ GPU köprüsü minimize edilir. Sahne
grafiğinde
Meshkonumu her tick değişebilir; geometri buffer’ı çoğu statik mesh’te sabit kalır. Kullanılmayan geometriyigeometry.dispose()ile serbest bırakmayı unutmayın (sayfa sonu dispose notu). Dinamik deformasyon (parçacık, cloth) istisnadır; orada attribute dizileri bilinçli güncellenir. - Öznitelikler (attributes): Her vertex için paralel kanallar:
position(şekil),normal(ışık / gölge yönü),uv(doku sarma) — malzeme ve ışık bunları okur, geometri tek başına renk üretmez.setAttribute('position', …)ile eklenir; paylaşılan köşeler içinsetIndexbellek kazanır. Eksik normaldecomputeVertexNormals()yardımcı olur; ayrıntılı tür tablosu hemen altında.
Mesh = geometri + materyal; renderer.render(scene, camera) bu
buffer’ları pipeline’dan geçirip piksele çevirir. Nesnenin nerede durduğu
Object3D transformudur; yerel / dünya
ayrı katmandır. Rasterization ve WebGL hattının özeti
Renderer · pipeline
sayfasındadır; burada geometri verisinin GPU’ya nasıl paketlendiğine odaklandık.
Teknik tablo: veri türleri ve fonksiyonları
| Özellik | Teknik karşılık | Neden önemli? |
|---|---|---|
| Position | Float32Array |
Nesnenin asıl fiziksel şeklini ve hacmini belirler. |
| Normal | Vector3 (attribute olarak paketlenir) |
Yüzeyin baktığı yönü belirleyerek gölge ve ışık hesaplarını mümkün kılar. |
| UV mapping | Vector2 (attribute olarak paketlenir) |
2D bir resmin (doku), 3D yüzeye hatasız giydirilmesini sağlar. |
| Index | Uint16Array / Uint32Array |
Aynı noktayı kullanan üçgenlerde veriyi tekrar yazmaz; bellek tasarrufu sağlar. |
Uygulama: manuel veri yönetimi
Bir BufferGeometry oluştururken sadece noktaları girmek yetmez; sistemi tam
verimle çalıştırmak için sınırlayıcı hacimleri (bounding volumes)
hesaplamalı
ve ışık için gerekliyse normalleri üretmelisiniz:
// 1. Veri hazırlığı
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([-1, -1, 1, 1, -1, 1, 1, 1, 1]);
// 2. Veriyi GPU'ya bağlama
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
// 3. Otomatik hesaplamalar (hayati adımlar)
geometry.computeVertexNormals(); // Işık hesapları için gerekli
geometry.computeBoundingBox(); // Görünürlük (culling) testleri için gerekli
geometry.computeBoundingSphere(); // Mesafe bazlı optimizasyonlar için gerekli
Holodepth notu: Bellek temizliği (dispose)
Yazılım dünyasında çöp toplayıcılar (garbage collector) JavaScript nesnelerini temizler,
ancak GPU belleği için bu geçerli değildir. Sahneden sildiğiniz bir nesne GPU belleğinde
yaşamaya devam edebilir. Uzun süreli oturumlarda projenizin çökmemesi için, artık
kullanılmayan geometrileri mutlaka geometry.dispose() komutuyla bellekten
tamamen atmalısınız.