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

Parlak bir yüzeye baktığınızda çevrenin silueti orada görünür; bu, tek bir fotoğraf açısından değil, etrafınızdaki ışık ve nesnelerin her yönden özetlenmesinden gelir. Three.js'te ana sahneyi çizen kamera genelde tek bakış noktasıdır; CubeCamera ise aynı anda ön, arka, üst, alt, sağ, sol altı yönden örnek alarak 360° çevre bilgisini toplar.

Bu sistemin amacı doğrudan canvas'a kare basmak değildir: altı görüntü bir CubeTexture (küp dokusu) olarak WebGLCubeRenderTarget'a yazılır; malzeme tarafında çoğunlukla envMap ile canlı yansıma veya çevre aydınlatması üretilir. Statik HDR / PMREM birçok projede yeterlidir; sahnede hareket eden nesnelerin yansıması güncellenmeliyse küp kamera devreye girer. Oyuncunun gördüğü kadraj için PerspectiveCamera ; ölçülü plan görünümü için OrthographicCamera.

Bu sayfa CubeCamera'ya özeldir: dinamik yansıma mantığı, altı yüzlü anatomi, küp haritası şeması, etkileşimli demo (statik HDR karşılaştırması), near / far, performans ve özyineleme uyarıları. View / projection ve frustum dili için Kamera giriş sayfasına dönün.

Dinamik yansımaların mantığı

Gerçek hayatta parlak bir metal küveye baktığınızda yüzeyde odanın silueti görünür: ışık sadece “tek renk” değil, çevrenizin o noktadan görünen özetidir. Kamera açısını değiştirdiğinizde yansıma da kayar; çünkü yansıyan şey duvardır, penceredir, hareket eden nesnelerdir. Three.js'te aynı hissi vermek için malzemeye bir çevre haritası (envMap) verilir; küp kamera bu haritanın kaynağını sahnenin o anki halinden üretir.

Birçok projede çevre, diskten yüklenen HDR veya stüdyo HDRI ile sabitlenir; PMREM ile önceden işlenip malzemeye bağlanır. Ürün vitrini, sabit gün ışığı veya yavaş değişen arka plan için bu yol hızlı ve stabildir; yansıma “güzel” görünür, sahne içindeki küpler dönmese bile küre yüzeyi değişmez. Sorun, çevrenin canlı olduğu senaryolarda ortaya çıkar: hareketli objeler yansımada görünmüyorsa izleyici bunu hemen fark eder.

İşte burada CubeCamera devreye girer. Ana ekran kamerasından bağımsız olarak, yansıyan nesnenin yakınında (veya merkezinde) duran bu sistem her güncellemede çevreyi altı yönden yeniden render eder ve sonucu küp dokusuna yazar; parlak malzeme aynı envMap yolunu kullanır ama doku artık statik dosyadan değil, sahnenin güncel örneğinden beslenir. “Her kare” mi “hareket olunca” mı güncelleneceği performans tercihidir; mantık aynıdır: yansıma ile sahne senkron kalır.

Altı yönün nasıl birleştiği ve WebGLCubeRenderTarget yapısı bir sonraki bölümde; statik HDR ile canlı küp haritasını yan yana denemek için etkileşimli demoya geçin. Maliyet ve “statik yeter” kararı performans bölümünde toplanır; burada yalnızca neden ihtiyaç doğduğunu netleştiriyoruz.

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 renderer.render(scene, camera) ise tek geçiştir. Canlı küp haritası açıkken toplam maliyet, güncelleme yapılan karelerde kabaca ≈ 6× + 1× düşünülebilir; tek perspektif kameralı kareye göre belirgin şekilde pahalıdır. Aşağıdaki iki pratik eksen maliyeti düşürür: ne sıklıkla update(), hangi çözünürlükte yakalama.

  • Zamanlanmış güncelleme: 60 FPS'te her karede update() çağırmak, teoride saniyede altmış kez “altı pass’lik” ek yük demektir; çoğu yansıma bunu gerektirmez. Olay tabanlı güncelleme (kamera durdu, kapı açıldı, obje sürüklendi) veya her 2–3 karede bir yenileme genelde yeterli akıcılık verir — görüntüde küçük gecikme kalabilir, FPS ve sol üst maliyet satırı rahatlar. Demoda “Her kare / Her 2 kare / Elle” ve Dondur ile farkı ölçebilirsiniz: sahne aynı kalsa bile maliyet metni değişir. Üretimde kalite ayarına “yüksek / orta / düşük yansıma yenileme” eklemek yaygın bir kalıptır.
  • Düşük çözünürlük: WebGLCubeRenderTarget yüz boyutu (ör. 256×256) hem bellek hem bant genişliğini doğrudan etkiler; altı yüz çarpanı unutmayın. roughness yüksek malzemelerde yansıma zaten bulanık olduğu için 256 px sık yeterlidir; yakın plan hero nesnede 512 denebilir, 1024+ nadiren haklıdır. Çözünürlük anatomi bölümündeki hedefle birlikte seçilir — netlik / maliyet dengesini önce düşükten başlayarak test edin.

Ne zaman kullanmayın? Bölüm 1'deki “canlı çevre” ihtiyacı yoksa küp kamera eklemeyin; statik yol daha ucuz ve öngörülebilirdir.

  • Statik veya yavaş değişen sahneler: Arka plan sabit, yalnızca kamera dönüyor veya ışık yavaş değişiyorsa önceden pişirilmiş HDR / PMREM veya diskten CubeTexture yeterlidir. CubeCamera burada sürekli aynı bilgiyi yeniden yazar — gereksiz 6× maliyet. Demodaki Statik HDR modu bu baseline için referanstır.
  • Mobil ve düşük GPU: Her karede altı ek tam sahne pass'i genelde sürdürülemez; özelliği kalite menüsünden kapatın, çözünürlüğü 128–256'da tutun, güncellemeyi seyrekleştirin veya yalnızca “premium” cihazlarda açın. Düşük donanımda statik HDRI + basit envMap çoğu kullanıcı için yeterli görünür.
  • Kaliteli HDR zaten varsa: Ürün görselleştirmede stüdyo HDRI’si kasıtlı olarak seçilmişse yansıma estetiği dosyadan gelir; canlı küp haritası sahne karmaşasını yansıtmak istemiyorsanız eklemeyin. Hareketli nesnelerin yansıması şart değilse — bölüm 1 kriteri — üretim HDR’si ile kalın.

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.