Three.js · Sahne
Sahne (Scene): Three.js evreninin temeli
Three.js ile çalışırken ilk kurduğunuz yapı çoğu zaman
THREE.Scene olur: mesh, ışık, grup ve yardımcı nesneler bu kökte
toplanır. Sahne ekrana piksel basmaz; evrende neyin var olduğunu,
nesnelerin üst–alt ilişkisini ve ortak transform kurallarını tanımlar; yani
projenizin içerik ve düzen katmanıdır.
Holodepth üçlüsünde roller birbirini tamamlar: sahne yapıyı tutar, kamera hangi kesitin ekrana yansıyacağını seçer, renderer bu kesiti GPU ile çizer. Kamera ve renderer'ın ayrıntıları kamera ve renderer sayfalarında; bu metinde üçlünün sahne ayağını okuyorsunuz.
Aşağıdaki tablo üçlüyü tek bakışta özetler. Sonrasında scene graph,
Object3D, eksenler, scene.traverse(), ortam özellikleri
(background, fog, environment) ve sahne +
kamera + renderer'ı birleştiren minimal kurulum örneğine geçilir; kamera
matrisleri veya WebGL hattının içi burada tekrar anlatılmaz.
Sahne, kamera ve renderer (üçlü · 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.
Aşağıdaki mini demo, Three.js AxesHelper varsayılan renklerini gösterir; metindeki kırmızı / yeşil / mavi eşleşmesini sahne içinde doğrulayın (
OrbitControls
ile döndürün).
AxesHelper köken noktasından çıkan üç ok: Three.js dünya uzayında X kırmızı, Y yeşil, Z mavidir; sağ el kuralıyla aynı kod renkleri. Izgara yalnızca derinlik sezgisi içindir; eksenler asıl referanstır. Sahne editöründeki renkli oklarla bire bir aynı sözdizimi değildir; amaç «hangi eksen hangi renk»i görmek ve kamerayı serbestçe çevirmektir.
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: sahne ağacında tüm Mesh'leri bul
let meshCount = 0;
scene.traverse((object) => {
if (object.isMesh) meshCount += 1;
});
console.log('Mesh sayısı:', meshCount);
Sahne = global atmosfer katmanı
Scene yalnızca nesne listesi değildir: background,
fog ve environment gibi ortam kararları
kökte toplanır. Ayrıntılı kod ve HDR notu için
görünüm ayarları
alt başlığına bakın; ışık türleri ve PBR dolgu mantığı ışık konularında kalır.
Temel metotlar ve modern teknikler
Sahne yönetiminde sık kullanılan metotlar ve optimizasyon ipuçları aşağıda özetlenir.
Hepsi sahne ve sahne grafiği düzeyinde kalır: nesne ekleme/çıkarma,
ortam görünümü, debug override ve traverse ile toplu bayrak.
Kamera matrisleri, WebGL renderer hattı, gölge haritası kalitesi veya ışık türleri
ilgili sayfalarda işlenir; burada yalnızca hangi API’nin nerede devreye
girdiği gösterilir.
Nesne yönetimi (add, remove,
clear)
Sahneye nesne eklemek, kaldırmak veya tüm kök altını tek seferde boşaltmak için üç
temel metot yeterlidir. clear() sonrası paylaşılan geometri/materyal
referanslarını gerekiyorsa ayrıca dispose() etmeyi unutmayın.
const cube = new THREE.Mesh(geometry, material);
scene.add(cube); // Nesne ekle
scene.remove(cube); // Nesne kaldır
scene.clear(); // Tüm sahneyi temizle (dispose ayrıca gerekebilir)
Görünüm ayarları (background,
fog, environment)
Bunlar Scene özellikleridir: tek renk veya doku arka planı, sis ve
(PBR projelerinde) HDR tabanlı ortam yansıması. Işık nesneleri sahneye
add edilir; scene.environment materyallere yansıyan
ortam terimini besler; ışık türleri ve dolgu mantığı ışık
konularında ayrı işlenir.
scene.background = new THREE.Color(0x111122); // Koyu mavi arka plan
scene.fog = new THREE.FogExp2(0x111122, 0.02); // Hafif sis
// scene.environment = hdrTexture; // HDR / PMREM — materyal ve IBL konularında ayrıntı
Hata ayıklama (overrideMaterial)
Tüm sahneyi geçici olarak tek malzeme ile çizer; geometri hacmini veya draw yoğunluğunu
materyal karmaşası olmadan görmek için kullanılır. İş bitince mutlaka
null yapın.
scene.overrideMaterial = new THREE.MeshStandardMaterial({
color: 0xff0000,
transparent: true,
opacity: 0.5,
});
// … inceleme …
scene.overrideMaterial = null;
Optimizasyon teknikleri
- Frustum culling (doğuştan) Kameranın görüş hacmi dışındaki nesneler varsayılan olarak çizilmez; sahne tarafında ekstra kod gerekmez — kamera sayfasında frustum mantığı anlatılır.
- LOD (Level of Detail) Uzaklığa göre daha düşük poligonlu mesh’e geçiş; ayrıntı Geometry Optimization konusunda.
-
Instancing
Binlerce kopya için
InstancedMesh— tek draw call ailesi; Instancing sayfasına bakın. -
Katmanlar (
object.layers) Nesneleri katmanlara ayırıp hangi kameranın neyi göreceğini seçersiniz; UI / ana sahne ayrımı için sık kullanılır (kamera katman API’si kamera bağlamında tamamlanır).
uiObject.layers.set(1);
camera.layers.disable(1);
uiCamera.layers.enable(1);
uiCamera.layers.disable(0);
Gölge bayrakları (sahne + renderer köprüsü)
Gölge hesabı
renderer
(shadowMap) ve gölge atan
ışık tarafında kurulur. Sahne tarafında yapılan iş,
grafiği dolaşıp hangi mesh’in gölge üreteceğini / alacağını (
castShadow, receiveShadow) toplu açmaktır; gölge haritası
kalitesi veya ışık türleri burada işlenmez.
// Renderer: gölge hesaplamayı aç (ayrıntı renderer sayfasında)
renderer.shadowMap.enabled = true;
// Sahne: hangi mesh gölge üretir / alır — ışık ayarı ayrı konu
scene.traverse((object) => {
if (object.isMesh) {
object.castShadow = true;
object.receiveShadow = true;
}
});
Sahne büyüdükçe traverse maliyeti ve draw call sayısı artar; sahne
yönetimi yalnızca görsel düzen değil,
performans mühendisliği konusudur. Renderer’ın kare başına bu sahneyi
nasıl işlediği
renderer giriş
sayfasında kalır.
Üçlü pratikte renderer.render(scene, camera) ile birleşir; aşağıdaki
örnek bu çağrıyı minimal bir kurulumda gösterir.
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.
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.
| 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.