holodepth

Three.js · Kamera türleri

CubeCamera (küp kamera) — altı yönden çevre yakalama

CubeCamera (küp kamera) — gerçek zamanlı yansıma üretmek

CubeCamera, sahneyi tek bir bakış açısından değil; ön, arka, üst, alt, sağ, sol olmak üzere altı yönde eşzamanlı görüntüleyerek 360° çevre bilgisini toplayan özel bir kamera sistemidir. Amacı doğrudan ekrana kare basmak değil; bu altı görüntüyü bir CubeTexture (küp dokusu) olarak kaydetmek ve genelde envMap üzerinden yansıma / çevre aydınlatması olarak kullanmaktır. Genel kamera modeli için
Kamera Giriş; perspektif sahne kamerası için PerspectiveCamera.

Dinamik yansımaların mantığı

Gerçek hayatta parlak bir metal küveye baktığınızda, yüzeyde odanın yansımasını görürsünüz. Three.js'te statik HDR / çevre haritaları birçok senaryoda yeterlidir; ancak sahnede hareket eden nesnelerin yansımasını gerçek zamanlı göstermek istiyorsanız CubeCamera devreye girer: her güncellemede çevreyi altı yönden yeniden örnekleyip dokuyu güncellersiniz.

Yapısal anatomi: altı yüzlü görüş

Bir CubeCamera, tek bir merkez noktaya bağlı altı adet PerspectiveCamera gibi düşünülebilir. Her biri sabit yaklaşık 90° yatay ve 90° dikey görüş açısı (FOV) ile kendi yönünü render eder — küp haritasının yüzleri birbirine düzgün bitişik gelsin diye altı yön tam bir küpü kaplar (90°×6 = 360° yatayda kavramsal tam tur). Bu altı görüntü birleştirilerek bir render target içine yazılır.

CubeTexture nedir? GPU tarafında küp haritası, aynı boyutlu altı adet 2D doku (genelde +X, −X, +Y, −Y, +Z, −Z yüzleri) olarak düşünülür; birlikte tek bir küp örnekleyici (samplerCube) oluşturur. CubeCamera bu altı yönü ardışık render edip sonucu bu yapıya yazar.

  • near / far: Diğer kameralarda olduğu gibi yansımanın hangi mesafe aralığında üretileceğini belirler.
  • WebGLCubeRenderTarget: Yakalanan küp haritasının tutulduğu bellek hedefidir. Çözünürlük (ör. 256 veya 512) hem netliği hem GPU yükünü doğrudan etkiler.

Altı yüz düzeni (cross): Küp haritası GPU’da altı ayrı 2D doku yüzeyi olarak saklanır; bu şema, o yüzlerin birbirine nasıl bitişik düşündüğünü gösterir (yaygın “açılmış küp” çizimi). Yüzlerin üzerine gelerek yön ipuçlarını görebilirsiniz. Eksen adları Three.js / WebGL ile uyumludur; ön/arka etiketi (+Z / −Z) yaygın yorumdur — gerçek “ekran önü” kamera ve nesne yerleşiminize bağlıdır.

CubeCamera bağlantısı: Her güncellemede bu altı yüz sırayla render edilir ve WebGLCubeRenderTarget içine yazılır (tipik sıra: +X → −X → +Y → −Y → +Z → −Z). Alttaki şemada sırayla vurgu, bu akışı hatırlatır.

Etkileşimli demo: statik HDR vs CubeCamera

Ortada metalik bir küre, etrafta hareket eden küpler: Statik HDR modunda çevre PMREM ile önceden pişirilir — sahne hareket etse bile yansıma "donuk" kalır. CubeCamera modunda küre, her güncellemede çevreyi altı yönden yeniden yakalar; hareketli nesneler yansımada canlı görünür.

Not: "Her kare" ve "Her 2 kare" arasındaki fark çoğu zaman görüntüde değil, FPS ve üstteki maliyet satırında hissedilir; yansıma hâlâ akıcı görünebilir. "Elle"de sahne o an aynıysa tek tıkta fark az olabilir — küpleri izleyip tekrar deneyin veya üstteki kısa onay mesajına bakın.

~1× sahne
— FPS

Bu kontroller ne işe yarar?

  1. Çevre kaynağı: Statik HDR — önceden pişirilmiş çevre; küre yansıması hareketli küpleri "canlı" göstermez. CubeCamera — yansıma gerçek zamanlı üretilir; küpler hareket ettikçe kürede görünürler.
  2. Her kare / Her 2 kare: Küp haritasının ne sıklıkla yeniden çekileceği (GPU maliyeti). Sahne aynı kalabilir; asıl fark FPS ve sol üstteki maliyet metnindedir.
  3. Elle + Haritayı güncelle: Küp haritası yalnızca düğmeye basınca yenilenir. Tıkladığınızda üstte kısa onay görünür; küpler hareket halindeyken fark daha belirgin olur.
  4. Canlı / Dondur: CubeCamera modunda Dondur ile update() durur — küpler döner, küre yansıması son çekilen küp haritasında kalır. Üstteki “küp ✓” ve şemadaki hızlı yüz vurgusu yalnızca gerçek güncellemede çalışır.
  5. Onay kutusu (özyineleme): Varsayılan kapalı: küp çekilirken küre gizlenir — doğru yansıma. Açık: küre de kareye girer; yansımada artefakt / kararma (bilerek gösterilen hata).
Çevre kaynağı
CubeCamera güncelleme
Yansıma

Kapalı (önerilen): küre o an gizlenir, yansıma temiz. Açık: küre karede kalır; küp haritası kendi yüzeyini de içerir (beklenen bozulma).

Açıkken: küp haritası kendi yüzeyini içerir; yansıma bilinçli şekilde bozulur.
Statik HDR: tek pişirilmiş çevre — hızlı, hareket yansımaz. CubeCamera: her uygun karede altı ek render + ana sahne; sıklık düşürüldükçe FPS genelde toparlanır (görüntü farkı her zaman belirgin olmayabilir). Küp çekiminde küre görünür kalırsa harita özyineleme yapar — üretimde genelde visible = false.

Üstteki etkileşimli sahne (diagram-cube-camera.js, bu sayfadaki data-cube-camera-demo kökü) ile aynı sayıları ön harita tabloda topladık; aşağıdaki kod özeti demodaki küp hedefi, CubeCamera aralığı ve güncelleme karesini hatırlatır. Araç çubuğu / HUD ile değişenler tabloda HUD satırında; kalan satırlar dosyadaki sabitlerdir. Tür sütunu: ekrandaki kontroller ile kaynak koddaki sabitleri ayırır.

Bu demo’da kontrol edilenler

  • Çevre kaynağı → Statik HDR (PMREM) veya canlı CubeCamera
  • CubeCamera güncelleme → her kare / her 2 kare / elle (yalnızca Cube modunda)
  • Yansıma → Canlı (sürekli update) veya Dondur (küp pass atlanır)
  • Haritayı güncelle → elle modda tek karelik küp yenileme
  • Özyineleme demosu → küp çekilirken kürenin sahneye kalması (bilerek bozulma)
diagram-cube-camera.js — Sayfa Demosu Sabitleri (cube-camera.html playground)
Sahne / rol Parametre Değer Tür
Ortak · renderer Ton / renk uzayı ACESFilmicToneMapping, exposure 1 · çıkış SRGBColorSpace (destekleniyorsa) 🔒 Sabit
setPixelRatio min(devicePixelRatio, 2) 🔒 Sabit
Ortak · sahne Scene.background 0x05060c 🔒 Sabit
Ortak · ana kamera + orbit PerspectiveCamera FOV 45, clip 0.1100; başlangıç (0, 2.1, 7.2) 🔒 Sabit
OrbitControls Hedef (0, 0.5, 0), damping açık 🔒 Sabit
Işıklar AmbientLight 0xffffff, yoğunluk 0.25 🔒 Sabit
DirectionalLight 0xffffff · 1.1; konum (4, 10, 6) 🔒 Sabit
Zemin PlaneGeometry / MeshStandardMaterial 24×24, renk 0x1a1e2a, metalness 0.15, roughness 0.85 🔒 Sabit
Yansıtan küre SphereGeometry / materyal Yarıçap 0.55, segment 48; metalness 1, roughness 0.06, envMapIntensity taban 1.15; konum (0, 0.58, 0) 🔒 Sabit
Hareketli küpler BoxGeometry 0.38³; palet 0x5ec8ff0xffe066; metalness 0.2, roughness 0.55; yörünge yarıçapı ≈2.85 🔒 Sabit
Statik HDR PMREMGenerator + RoomEnvironment fromScene(roomEnv, 0.04) → sahne environment + küre envMap (HDR modunda) 🔒 Sabit
Canlı küp haritası WebGLCubeRenderTarget Yüz boyutu 256, generateMipmaps: true, LinearMipmapLinearFilter 🔒 Sabit
CubeCamera near 0.1, far 80, hedef aynı WebGLCubeRenderTarget; konum küre ile senkron 🔒 Sabit
Pedagoji (kod) Küp pass etiketleri / süre CUBE_FACE_LABELS (+X … −Z); şerit için yüz başına 4 animasyon karesi 🔒 Sabit (kod)
Şema animasyonu Küp haritası SVG + pulseFast Yüz vurgusu yalnızca gerçek küp güncellemesinde (Her 2 kare / elle); yavaş döngü 620 ms 🔒 Sabit + HUD (eş)
HUD başlangıç (cube-camera.html) Mod / sıklık Çevre: Statik HDR; sıklık: Her kare 🔄 Dinamik (HUD)
HUD Çevre, sıklık, dondur, elle, özyineleme Kullanıcı seçimi; dondur iken elle güncelleme kapalı 🔄 Dinamik (HUD)

Uygulama: canlı yansıma oluşturma

Tipik kurulum özeti aşağıdadır; sayısal sabitler üstteki tablo ve diagram-cube-camera.js ile aynı hizada tutulmuştur; üretimde far / çözünürlük sahne ölçeğine göre değişir. Yansıtan nesneyi küp çekimi sırasında gizlemek (visible = false) iç içe yansımayı ve gereksiz maliyeti azaltır.

// diagram-cube-camera.js — okuma sırası (üstteki demo sabitleri tablosu ile)

// 1. Küp render hedefi (çözünürlük + filtre; bu sayfada 256² / yüz)
const cubeRT = new THREE.WebGLCubeRenderTarget(256, {
  generateMipmaps: true,
  minFilter: THREE.LinearMipmapLinearFilter,
});

// 2. CubeCamera (near, far, renderTarget) — demoda clip sahne ölçeğine göre 0.1 … 80
const cubeCamera = new THREE.CubeCamera(0.1, 80, cubeRT);
cubeCamera.position.copy(sphere.position);
scene.add(cubeCamera);

// 3. Yansıyan küre materyali (HDR veya canlı küp: envMap kaynağı değişir)
const sphereMat = new THREE.MeshStandardMaterial({
  color: 0xffffff,
  metalness: 1,
  roughness: 0.06,
  envMapIntensity: 1.15,
  envMap: cubeRT.texture,
});

// 4. Güncelleme karesi — özyineleme önleme: cubeCamera.update öncesi küreyi gizle
function onAnimationFrame() {
  sphere.visible = false;
  cubeCamera.update(renderer, scene);
  sphere.visible = true;
  renderer.render(scene, camera);
}

Teknik tablo: CubeCamera parametreleri

Parametre Açıklama Performans notu
FOV (iç perspektif kameralar) Three.js içinde altı yön kamerası yaklaşık 90° yatay/dikey görüşle hizalanır; böylece yüzler arasında boşluk kalmaz. Kullanıcı tarafında seçilmez — sabit davranış.
Çözünürlük (resolution) Her küp yüzünün piksel boyutu (ör. 128, 256, 512). Altı yüz olduğu için değer büyüdükçe maliyet kabaca 6 kat artar.
.update() Sahneyi o anki haliyle yeniden yakalar ve küp dokusunu yazar. Her karede çağırmak maliyeti çok artırır; çoğu projede seçici veya seyrek güncelleme tercih edilir.
renderTarget Görüntü verisinin tutulduğu hedef; genelde .texture ile envMap'e bağlanır. Çözünürlük ve filtre seçimi hem kaliteyi hem bant genişliğini belirler.

Performans ve optimizasyon

Uyarı: Her cubeCamera.update() çağrısı, sahneyi içeride altı kez tam render eder. Ana ekranınız için yaptığınız bir
renderer.render(scene, camera) ise tek geçiştir. Bu yüzden canlı küp haritası açıkken toplam maliyet kabaca ≈ 6× + 1× (güncelleme yapılan karelerde) düşünülebilir — yani tek bir perspektif kameralı kareye göre çok daha pahalıdır.

  • Zamanlanmış güncelleme: 60 FPS'te sürekli güncellemek yerine yalnızca sahnede anlamlı değişiklik olduğunda veya her 2–3 karede bir update() kullanmak denge sağlar (üstteki demo ile FPS farkını gözlemleyebilirsiniz).
  • Düşük çözünürlük: Birçok yansıma zaten bulanık / rough görüneceği için 256 px gibi düşük yüz çözünürlükleri sık yeterlidir.

Ne zaman kullanmayın?

  • Statik veya yavaş değişen sahneler: Önceden pişirilmiş HDR / PMREM veya sabit CubeTexture yeterliyse CubeCamera gereksiz maliyettir.
  • Mobil ve düşük GPU: Her karede altı ek render genelde sürdürülemez; güncelleme sıklığını düşürün veya özelliği kapatın.
  • Kaliteli HDR zaten varsa: Üretim ortamı / stüdyo HDRI’si yansıma için yeterliyse canlı küp haritası eklemeyin.

Holodepth notu: özyinelemeli (recursive) yansıma

İki ayna birbirini yansıtıyorsa teoride sonsuz bir özyineleme oluşabilir. CubeCamera bu derinliği otomatik olarak "sınırsız" çözmez; bu yüzden yansıyan nesneyi güncelleme anında gizlemek (visible = false) hem hatalı / istenmeyen iç içe yansımayı azaltır hem performansı korur.