holodepth

Three.js · Sahne

Sahne (Scene): Three.js evreninin temeli

Three.js'te bir sahnenin görüntülenebilmesi için üç temel yapı birlikte çalışır: sahne (scene), kamera (camera) ve renderer. Bu sayfada bu üçlüden en kritik olan yapı olan sahneyi derinlemesine inceleyeceğiz.

Sahne, kamera ve renderer (hatırlatıcı)

Bileşen Teknik karşılık Ana sorumluluk
Sahne THREE.Scene Nesnelerin hiyerarşik listesini ve ortam özelliklerini (fog, background) tutmak.
Kamera THREE.PerspectiveCamera 3D uzayı matematiksel bir perspektifle 2D düzleme (ekrana) iz düşürmek.
Renderer THREE.WebGLRenderer GPU kullanarak verileri piksellere dönüştürüp canvas'a basmak.

Sahne: evrenin konteyneri ve hafızası

Sahne nedir?

Sahne, yalnızca nesnelerin bulunduğu bir kap değil; tüm 3D evrenin organizasyon ve ilişki merkezidir. THREE.Scene kök düğüm olarak mesh, ışık, grup ve yardımcı araçları aynı evrende toplar; burada kurduğunuz ilişkiler animasyon ve sahne yönetiminin omurgasıdır.

Scene graph: evrenin hiyerarşik ağacı

Sahne sadece bir liste değil, bir ebeveyn–çocuk (parent–child) ilişkisidir. Bir Group oluşturup içine üç Mesh eklerseniz, grubu hareket ettirdiğinizde içindeki nesneler kendi yerel koordinatlarını koruyarak grupla birlikte taşınır.

Kök düğüm ve graf: En üstte sahne vardır; altında Mesh, Group, Light vb. düğümler bulunur. Bir grubu döndürmek içeridekileri de döndürür; bir objeyi taşımak child’ları da taşır — bu yüzden sahne grafiği karmaşık mekanizmalar ve animasyon için hayatidir.

Object3D ve ortak transform sistemi

Three.js'te sahne dahil tüm nesneler Object3D hiyerarşisinden türetilir. Bu, hepsinin aynı temel transform arayüzünü (position, rotation, scale), üst–alt bağını (parent / children) ve sahne grafiğinde tutarlı hareket kurallarını paylaştığı anlamına gelir.

Kartezyen eksenler ve sağ el kuralı

Three.js'te evren (0, 0, 0) merkez noktasından dışarıya doğru uzanan üç hayali yol üzerine kurulur. Bu yolları (eksenleri) karıştırmamanın en pratik yolu Sağ el kuralı'dır — parmağınızı konuma göre konumlandırın:

  • X ekseni (yatay) Sağ el başparmağınız sağa baksın. Pozitif değerler sağa, negatifler sola hareket ettirir. (Kırmızı eksen)
  • Y ekseni (dikey) İşaret parmağınız gökyüzüne baksın. Pozitif değerler yukarı, negatifler aşağı (yerçekimi yönü) hareket ettirir. (Yeşil eksen)
  • Z ekseni (derinlik) Orta parmağınızı kendinize (ekranın dışına) doğru bükün. Pozitif Z size yaklaşır; negatif Z ekranın içine girip uzaklaşır. (Mavi eksen)

İpucu: Nesne ile bakış aynı noktada çakışıyorsa genelde hiçbir şey görünmez; pozisyonları Z ekseninde ayırmak sık kullanılan ilk adımdır.

Traversal (gezinme)

Sahnedeki tüm nesneler üzerinde işlem için scene.traverse() kullanılır; büyük sahnelerde hata ayıklama ve toplu ayarlar için kritiktir.

// Örnek: tüm mesh'lerde gölge oluşturmayı aç
scene.traverse((object) => {
  if (object.isMesh) {
    object.castShadow = true;
  }
});

Sahne = global atmosfer katmanı

Scene yalnızca liste tutmaz: background, fog, environment (HDR / PMREM) gibi görsel ortam kararları burada toplanır. PBR yansımaları ve tutarlı ışık için scene.environment modern projelerde sık geçer.

Temel metotlar ve modern teknikler

  • Nesne: scene.add(object), scene.remove(object), scene.clear()
  • Görünüm: scene.background, scene.fog, scene.environment
  • Debug: scene.overrideMaterial — tüm sahneyi tek materyalle çizer (performans testi).
  • Optimizasyon: frustum culling (built-in), LOD, instancing; object.layers ile seçici render / UI ayrımı.
  • Gölge: renderer.shadowMap.enabled ile birlikte; traversal ile mesh bazlı ayar yaygındır.

Sahne büyüdükçe traversal maliyeti ve draw call sayısı artar; sahne yönetimi yalnızca görsel değil performans mühendisliği konusudur.

Sahne tek başına görünmez; bir kamera ve renderer ile birlikte render edildiğinde ekranda görünür hale gelir.

Tam örnek: sahne + kamera + renderer

Aşağıdaki blok, yukarıdaki bağlamı tek dosyada toplayan minimal bir kurulumdur; sahne kurulduktan sonra kamera ve renderer ile animasyon döngüsüne bağlanır.

Editor örneğinin yapısı (diyagram)
Scene Mesh (Box) DirectionalLight
PerspectiveCamera scene + camera WebGLRenderer canvas

Bu sürümde PerspectiveCamera çoğu zaman scene.add(camera) ile grafiğe eklenmez; yine de renderer.render(scene, camera) satırında ikili birlikte kullanılır. İsterseniz kamerayı da sahneye ekleyerek tek kökten traverse ile yönetebilirsiniz.

import * as THREE from 'three';

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0a0c12);

const camera = new THREE.PerspectiveCamera(
  50,
  window.innerWidth / window.innerHeight,
  0.1,
  100
);
camera.position.z = 5;

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);

const mesh = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshStandardMaterial({ color: 0x5ec8ff })
);
scene.add(mesh);

const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(2, 3, 4);
scene.add(light);

function animate() {
  requestAnimationFrame(animate);
  mesh.rotation.y += 0.01;
  renderer.render(scene, camera);
}
animate();

Demo sabitleri tablosu (editor örneği)

Aşağıdaki tablo, üstteki tam editor kodundaki sayısal değerlerin ön haritasıdır. Bu sayfada canlı WebGL demosu yoktur; sabitler doğrudan gösterilen main.js bloğundan okunur. Diyagram ile birlikte kullanın.

scene-entry.html — Tam örnek editör bloğu (#box-code-editor-triad-full)
Sahne / rol Parametre Değer Tür
Scene · ortam scene.background new THREE.Color(0x0a0c12) 🔒 Sabit
PerspectiveCamera fov 50 🔒 Sabit
aspect window.innerWidth / window.innerHeight ↔ Pencereye bağlı
near / far 0.1 / 100 🔒 Sabit
camera.position z = 5 (x, y varsayılan 0) 🔒 Sabit
WebGLRenderer Oluşturucu seçenekleri { antialias: true } 🔒 Sabit
setPixelRatio Math.min(window.devicePixelRatio, 2) ↔ Cihaza bağlı (üst sınır 2)
Mesh · geometri BoxGeometry 1 × 1 × 1 🔒 Sabit
Mesh · materyal MeshStandardMaterial.color 0x5ec8ff 🔒 Sabit
DirectionalLight renk · yoğunluk · position 0xffffff · 1 · (2, 3, 4) 🔒 Sabit
Animasyon döngüsü mesh.rotation.y artışı += 0.01 / kare 🔒 Sabit
Modül import three (örnek varsayım; bundler / CDN projenize göre) ℹ Bağlam

Püf noktası: siyah ekran

Her şeyi doğru yaptığınızı düşünüyorsanız ama ekran siyah kalıyorsa: ya bakış noktası mesh'in içinde kalmıştır (Z pozisyonunu artırarak ayırın) ya da MeshStandardMaterial kullanıyorsanız sahneye yeterli ışık eklememiş olabilirsiniz — PBR malzeme ışık gerektirir.