holodepth

Three.js · Sahne grafiği

Object3D ve sahne hiyerarşisi

Three.js'te nesneleri yalnızca yan yana koymuyoruz; onları birbirine bağlayarak bağımlı hareket sistemleri kuruyoruz. Object3D, Mesh, Group, Camera, Light gibi tiplerin ortak tabanıdır ve sahne grafiğinin omurgasını oluşturur.

Hiyerarşi ve koordinat uzayları

Yerel (local) ve dünya (world) koordinatları

Hiyerarşiyi kullanmanın ilk adımı, bir nesnenin konumunun neye göre ifade edildiğini bilmektir.

  • Yerel uzay (local space): Nesnenin ebeveyne (parent) göre konumu ve yönelimidir. Üst öğe yoksa ebeveyn genelde doğrudan Scene kabul edilir.
  • Dünya uzayı (world space): Sahne kökenine (genelde (0, 0, 0)) göre birikmiş gerçek konum ve yönelimdir; üst nesnelerin tüm dönüşümü bu değere yansır.

Örnek: Bir araba modelinde tekerlek, arabanın merkezine göre yan tarafta olabilir (yerel). Araba dünyada ilerlediğinde tekerleğin dünya konumu, arabanın dönüşümüyle birlikte güncellenir.

Temel transformlar: position, rotation, scale

Tüm Object3D türevleri üç temel transform özelliği taşır: position, rotation ve scale. Bu değerler yerel uzayda tutulur ve ebeveyn–çocuk hiyerarşisi boyunca birleşerek dünya konumunu ve yönelimini oluşturur.

rotation özelliği Euler açılarıyla tutulur; değerler radyan cinsindendir.

Her Object3D için dönüş ve ölçekleme işlemleri, nesnenin kendi origin (pivot) noktasına göre uygulanır; bu nokta çoğu modelde yerel köken
(0, 0, 0) etrafındadır.

Dünya konumu ve matris güncellemesi

Bir nesnenin dünya koordinatlarındaki konumunu almak için getWorldPosition() kullanılır; sonuç, verdiğiniz vektöre yazılır:

object.getWorldPosition(new THREE.Vector3());

Üretilen vektörü her karede tekrar kullanacaksanız tek bir Vector3 örneğini saklamak daha verimlidir.

Three.js varsayılan olarak her karede transform matrislerini otomatik günceller (matrixAutoUpdate açık). Bu davranış kapatılarak — yalnızca dönüşümü seyrek değişen statik nesnelerde ve bilinçli senaryolarda — gereksiz matris yeniden hesaplaması azaltılabilir; bu ileri düzey bir optimizasyondur ve genelde manuel updateMatrix() ihtiyacı doğurur.

Parent–child ilişkisinin gücü

Bir nesneyi diğerine .add(çocuk) ile eklediğinizde, çocuk ebeveynin transform zincirine girer: konum, dönüş ve ölçek üstten aşağı etkiler.

  • Miras: Ebeveyn dönerse çocuk da onunla birlikte hareket eder; ebeveyn ölçeklenirse çocuk uzayı da ölçeklenir.
  • Bağımsızlık: Çocuğun yerel transformunu değiştirmek, ebeveynin dünyadaki yerini değiştirmez — yalnızca üst nesneye göre ilişkiyi güncellersiniz.

THREE.Group: görünmez konteyner

THREE.Group, geometrisi olmayan bir Object3D türevidir; parçaları mantıksal olarak toplamak için kullanılır.

Neden? Örneğin karakterin tüm mesh'lerini (baş, gövde, kollar) tek Group altında toplayıp characterGroup.position.x = 10 ile tüm figürü birlikte taşımak.

Teknik tablo: hiyerarşi metotları

Metot İşlev Kullanım senaryosu
.add(object) Nesneyi çocuk olarak bağlar. Silahı karakterin el bone'una veya gruba bağlamak.
.remove(object) Nesneyi bu düğümün altından çıkarır. Sahneden ayırmak veya başka ebeveyne taşımadan önce söküm.
.attach(object) Nesnenin dünya transformunu koruyarak ebeveyni değiştirir; çocuk başka bir düğümün altına alınırken ekranda zıplamaz. Yer değiştirirken "zıplamayı" önlemek.
.traverse(callback) Sahne grafiğini derinlik öncelikli (depth-first) gezer. Gruptaki tüm mesh'lerde materyal veya gölge bayrağı ayarlamak.

Uygulama: güneş sistemi mantığı

Dünya'nın güneş etrafında, ay'ın dünya etrafında dönmesi; üst grup dönünce alt grupların birlikte hareket etmesi için klasik bir örnektir. sunMesh, earthMesh, moonGeo / moonMat ve sahne kurulumu varsayılmıştır.

const solarSystem = new THREE.Group();
const earthGroup = new THREE.Group();
scene.add(solarSystem);

solarSystem.add(sunMesh);

solarSystem.add(earthGroup);
earthGroup.position.x = 10;
earthGroup.add(earthMesh);

const moonMesh = new THREE.Mesh(moonGeo, moonMat);
moonMesh.position.x = 2;
earthGroup.add(moonMesh);

function animate() {
  requestAnimationFrame(animate);

  solarSystem.rotation.y += 0.01;
  earthGroup.rotation.y += 0.02;

  renderer.render(scene, camera);
}

animate();

Holodepth notu: matrixWorld ve derinlik

Three.js her karede hiyerarşiye göre dünya matrislerini (matrixWorld) günceller; yerel matrisler için matrixAutoUpdate varsayılan olarak açıktır. Çok derin iç içe yapılar (onlarca seviye) bu hesaplamayı artırır; mümkün olduğunca yassı ve amaca uygun bir sahne grafiği kurmak performans için iyidir.