Three.js · Kamera türleri
StereoCamera (stereoskopik kamera)
İki göz, bir sahne; parallaks ile derinlik
İki gözünüz aynı sahneyi milimetre farklı açılardan görür; beyin bu kaymayı
(parallaks) derinlik olarak yorumlar. VR başlığı, karton gözlük veya anaglif
gözlük; hepsi aynı fikrin farklı sunumlarıdır: izleyiciye sol ve sağ kanal
verip beynin birleştirmesini beklemek. Bu, ekranı dört panele bölen
ArrayCamera veya çevre dokusu üreten CubeCamera ile
karıştırılmamalıdır; amaç tek sahnede stereoskopik çift.
Three.js'te bunu StereoCamera sağlar: içeride iki
PerspectiveCamera (cameraL, cameraR), aralarında tipik
olarak insan göz aralığına yakın 6,4 cm ölçeğinde
eyeSep. Dünya kamerasını hareket ettirdiğinizde çift, bu mesafeye göre güncellenir.
Tek bakışlı oyun veya ürün turu için
PerspectiveCamera; aynı karede dört farklı oyuncu
kadrajı için
ArrayCamera.
Bu sayfa StereoCamera'ya özeldir: stereoskopik mantık, sol/sağ anatomi,
eyeSep ve update(), yan yana / anaglif demo, WebXR ve efekt katmanı
özeti, teknik tablo ve yakınsama (convergence) notları. Genel kamera dili için
Kamera giriş sayfasına
dönün; doğrudan renderer.render(scene, stereo) yerine üst katmanların rolü hemen
alttaki mor kutuda özetlenir.
Uzman Notu: StereoCamera Doğrudan Çizim İçin Tasarlanmamıştır
StereoCamera sınıfı, genellikle grafik motorunun ana renderer döngüsünde
doğrudan çağrılan bir
bileşen değildir. Bunun yerine; AnaglyphEffect, StereoEffect veya
günümüzdeki
modern WebXR gibi yüksek seviyeli sistemler, bu kamerayı arka planda otomatik
olarak yönetir ve
senkronize eder.
Pratikte StereoCamera, çoğu profesyonel projede düşük seviyeli bir
yardımcı
modül olarak konumlanır. Ekranda görüntü bölme, anaglif (kırmızı-mavi gözlük) birleştirme
veya karmaşık bir
XR oturumu başlatma süreçleri, bu kameranın üzerine inşa edilen üst katmanların görevidir.
Aşağıdaki canlı
örnek, bu yardımcı sınıfın mantığını anlamanız için manuel (eğitsel) bir
kullanım
senaryosunu sergilemektedir.
Stereoskopik görüşün mantığı
Neden iki göz? Her göz dünyayı hafifçe farklı açıdan görür; bu görüntü
kayması (binocular disparity) sayesinde beyin bir nesnenin
uzaklığını tahmin edebilir. Dijital tarafta aynı farkı üretmek için
StereoCamera sahneyi sol ve sağ kanal olarak
düşünür; çıktıyı yan yana, üst üste (anaglif) veya VR başlığına göre sunmak ayrı bir
kompozisyon / efekt katmanının işidir.
Kullanım senaryoları; ortak desen: StereoCamera sol/sağ
görüntüyü üretir; nasıl sunulacağı platforma göre değişir (demo ve
uygulama bölümlerinde).
- WebXR / WebVR: VR başlıkları her iki göz için ayrı tampon (buffer) ve
projeksiyon gerektirir.
WebXR oturumları genellikle kendi stereo görüntü akışını yerleşik olarak yönetirken,
StereoCameraaynı paralaks mantığının daha düşük seviyeli bir modellemesidir. Daha kapsamlı bir XR entegrasyonu WebXR başlığı altında incelenmektedir; burada sadece "iki göz, tek sahne" konseptinin temellerini atıyoruz. Unutulmamalıdır kiArrayCameraçok bölgeli tek ekran kurguları içindir, VR'ın çift gözlü yapısı için tasarlanmamıştır. - Karton gözlük (Google Cardboard vb.): Telefon ekranı yan
yana (side-by-side)
iki yarım görüntüye bölünür ve fiziksel mercekler her gözün yalnızca kendi tarafındaki
görüntüyü algılamasını
sağlar. Bu sayfadaki demoda ilgili mod doğrudan viewport bölünerek sağlanmıştır; üretim
aşamasındaki projelerde
ise genellikle bu kalıp veya StereoEffect kullanılır. Gözler
arası mesafe
(
eyeSep) ve odaklanılan nesne mesafesi, birleşerek sahnedeki derinlik ve yakınlık hissini oluşturur (detaylar anatomi bölümündedir). - Anaglif: Tek bir düzlem üzerinde kırmızı-cyan (veya diğer renk kanalları) kullanılarak derinlik illüzyonu yaratılır; renk filtreli gözlükler aracılığıyla sol ve sağ göz görüntüleri ayrıştırılır. Demomuzda bu birleşimin temel işleyişi gösterilmektedir; ancak çoğu projede kalıcı çözüm olarak AnaglyphEffect benzeri bir post-processing üst katmanı tercih edilir (girişin altındaki notta belirtildiği gibi). Standart sinema deneyiminden farklı olarak, izleyicinin görsel sistemi bu renkleri aktif bir şekilde birleştirerek stereo algıyı inşa eder.
- Sinema ve profesyonel projeksiyon: Donanıma ve salon standartlarına
bağlı olarak polarize
gözlükler veya zaman sıralı (aktif shutter) çift projeksiyon sistemleri kullanılır.
Three.js tarafında yine sol
ve sağ karelerin ayrı ayrı üretilmesi gerekirken, son sunum katmanı kullanılan
projektörün yapısına özeldir.
Özel bir render hattı (pipeline) veya gelişmiş bir grafik motoru altyapısı olmadan
yalnızca kamera sınıfını
kullanarak "sinema kalitesine" ulaşmak mümkün değildir; dolayısıyla
StereoCamera, bu devasa üretim hattının sadece küçük ama temel bir parçasıdır.
Yapısal anatomi: sol ve sağ kanallar
StereoCamera, içinde iki adet PerspectiveCamera barındırır:
cameraL ve cameraR. Dünya uzayında kameranızı (veya başlığı)
hareket ettirdiğinizde, bu iki alt kamera göz mesafesine göre otomatik
konumlanır; projeksiyonları güncellemek için tipik akışta
stereoCamera.update(worldCamera) çağrılır (sürümünüze göre tam imza
dokümantasyonda).
- Eye separation (Göz mesafesi):
eyeSep— İki sanal göz arasındaki mesafeyi ifade eder ve varsayılan olarak ortalama insan göz aralığına yakındır (yaklaşık 6,4 cm; sahne biriminiz metre ise bu değer ~0.064olmalıdır). Bu değer artırıldığında sol ve sağ görüntüler arasındaki yatay kayma büyüyerek stereo tabanını genişletir; azaltıldığında ise derinlik algısı zayıflayarak sahne düzleşir. Aşırı yüksek değerler kullanmak, devasa bir varlığın gözünden bakıyormuşsunuz gibi abartılı bir "minyatürleşme" etkisine yol açabilir ve kullanıcıda baş ağrısı riski yaratabilir. Konfor sınırlarına dair incelemeler yakınsama / parallaks bölümünde yer almaktadır. Bu etkiyi Demo HUD üzerinden canlı olarak deneyimleyebilirsiniz; ancak sahne biriminiz metre değilse, bu değeri aşağıdaki ölçeklendirme paragrafına uygun olarak yeniden düzenlemeniz gerekir. cameraLvecameraR: Sahneyi oluşturan iki tamPerspectiveCameraörneğidir. Görüş alanı (FOV),near/farkırpma düzlemleri ve projeksiyon matrisi her zaman ana dünya kamerasına (baş veya kamera teçhizatı/rig) senkronize kalır. Tipik çalışma akışındastereo.update(worldCamera)fonksiyonu kullanılır; bu metot, sol ve sağ kameraların konumlarını manuel olarak hesaplama yükünü ortadan kaldırarak ikili yapıyı otomatik olarak senkronize tutar. Çizim aşamasında (yan yana modda) öncecameraLile sol viewport, ardındancameraRile sağ viewport render edilir. Anaglif veya XR ortamlarında son kullanıcı sunumu farklılık gösterse de, temel üretim hattı değişmez ve her zaman bu iki kanaldan beslenir. Bu konunun pratik kullanımları bölüm 3 ve uygulama özetinde detaylandırılmıştır.
Bu değer gerçek dünya ölçeğine bağlıdır; sahnenin birimi metre değilse,
eyeSep değeri sahne ölçeğine göre ayarlanmalıdır (örneğin 1 birim = 1 cm
ise insan göz aralığı kabaca 6.4 birim olur).
Etkileşimli demo: cameraL, cameraR ve parallaks
Aynı sahne iki kez çizilir: sol yarı
stereo.cameraL, sağ yarı stereo.cameraR
(yan yana mod). Göz mesafesi kaydırıldıkça iki görüntü arasındaki yatay
fark büyür veya küçülür; nesne derinliği (Z) ile nesneyi öne/arkaya
alarak parallaksın nasıl değiştiğini görebilirsiniz. Anaglif modunda iki tampon birleşir
(basit kırmızı–camgöbeği ayrımı; öğretici; Dubois matrisli profesyonel anaglif ayrı
konudur).
stereo.update(worldCamera) öncesi ana kamera dünya matrisi güncel olmalı;
cameraL / cameraR üzerinde lookAt çağırmayın — Three.js
off-axis çifti update() ile yazar. Yakınsamayı ana kamerada
lookAt(nesne) + camera.focus = mesafe(kamera, nesne) ile
hizalarsınız (zero parallax nesne merkezinde). Yan yana modda
viewport / scissor için renderer.getSize() (mantıksal
boyut) kullanılır; domElement.width (tampon pikseli) verilirse
pixelRatio iki kez uygulanır ve sağ göz kayar. stereo.aspect = 0.5
tam tuval en-boy oranında tek gözün oranıdır. Üretimde
genelde StereoEffect, AnaglyphEffect veya
WebXR bu düzeni yönetir.
Uygulama: VR ve anaglif hazırlığı
Üstteki bölüm 3 aynı
mantığı canlı gösterir (viewport bölme veya basit anaglif birleşimi).
Üretimde ise StereoCamera çoğu projede tek başına "ekrana bas" demek
değildir; yan yana iki görüntü, anaglif birleşimi
veya XR oturumu için examples/jsm altındaki
yardımcılar veya özel bir render geçidi kullanılır. Temel kurulum iskeleti şöyle
özetlenebilir:
Tür sütunu: dosyada sabit kalanlar ( Sabit) ile HUD, görüntü modu veya pencere ölçüsüne bağlı güncellemeleri ( Dinamik) ayırır.
| Sahne / rol | Parametre | Değer | Tür |
|---|---|---|---|
| Işık | AmbientLight |
0xffffff, 0.45 |
🔒 Sabit |
DirectionalLight |
0xffffff, 1.05; position.set(3.5, 8, 5)
|
🔒 Sabit | |
| Zemin | GridHelper |
boyut 14, bölüm 28; position.y = −0.55;
çizgi
0x3a4a6a / 0x1a2030
|
🔒 Sabit |
| Parallax nesnesi | Geometri / materyal | BoxGeometry(0.95, 0.95, 0.95),
MeshStandardMaterial renk 0x6a8ae8,
metalness 0.2, roughness 0.42,
emissive 0x1a2848, emissiveIntensity 0.18
|
🔒 Sabit |
| Konum · Z sürgüsü | Başlangıç (0, 0.35, 0); HUD aralığı
−2.2 … 2.8 (adım 0.05)
|
🔄 Dinamik (HUD) | |
| Görsel yardımcı | EdgesGeometry + AxesHelper(1.35) |
Kenar çizgisi 0xc8d8f8 (opacity 0.85); eksenler kutu merkezinde
|
🔒 Sabit |
| Dünya kamerası | PerspectiveCamera |
FOV 50, near 0.05, far
120; aspect her setSize sonrası
getSize() ile
|
🔄 Dinamik (viewport) |
position |
(0, 1.05, 3) |
🔒 Sabit | |
| Yakınsama | lookAt(mesh.position) ·
focus = position.distanceTo(mesh.position) ·
updateProjectionMatrix()
|
🔄 Dinamik (mesh Z) | |
StereoCamera |
eyeSep |
Varsayılan 0.064; HUD sürgüsü 0.012 … 0.12 (adım
0.002)
|
🔄 Dinamik (HUD) |
aspect |
Yan yana: 0.5 (tek göz yarım genişlik); anaglif tampon:
1
|
🔄 Dinamik (mod) | |
| Çıktı | WebGLRenderer |
setPixelRatio(Math.min(devicePixelRatio, 2));
setClearColor(0x05060c); SRGBColorSpace (destek varsa)
|
🔒 Sabit |
| Yan yana çizim | Viewport / scissor | renderer.getSize() mantıksal boyut; sol yarı
cameraL, sağ yarı cameraR; bitişte tam tuval
setViewport(0,0,sw,sh)
|
🔄 Dinamik (viewport) |
| Anaglif (özet) | İki tampon + tam ekran quad | İki WebGLRenderTarget (çizim tamponu boyutu), klasik R|GB
birleşimi;
FullScreenQuad (Pass.js)
|
🔄 Dinamik (viewport) |
// diagram-stereo-camera.js — StereoCamera çekirdeği (yan yana mod)
const worldCamera = new THREE.PerspectiveCamera(50, 1, 0.05, 120);
worldCamera.position.set(0, 1.05, 3);
function aimAtSubject() {
worldCamera.lookAt(mesh.position);
worldCamera.focus = worldCamera.position.distanceTo(mesh.position);
worldCamera.updateProjectionMatrix();
}
const stereo = new THREE.StereoCamera();
stereo.eyeSep = 0.064; // HUD: 0.012 … 0.12
function onResize() {
renderer.setSize(w, h, false);
const size = new THREE.Vector2();
renderer.getSize(size);
worldCamera.aspect = size.x / Math.max(1, size.y);
worldCamera.updateProjectionMatrix();
}
function renderStereoSbs() {
aimAtSubject();
worldCamera.updateMatrixWorld(true);
stereo.aspect = 0.5; // tam tuvalde tek göz = yarım genişlik
stereo.update(worldCamera);
const size = new THREE.Vector2();
renderer.getSize(size);
const halfW = size.x / 2;
const restW = size.x - halfW;
renderer.setScissorTest(true);
renderer.setViewport(0, 0, halfW, size.y);
renderer.setScissor(0, 0, halfW, size.y);
renderer.render(scene, stereo.cameraL);
renderer.setViewport(halfW, 0, restW, size.y);
renderer.setScissor(halfW, 0, restW, size.y);
renderer.render(scene, stereo.cameraR);
renderer.setScissorTest(false);
renderer.setViewport(0, 0, size.x, size.y);
}
// Anaglif: stereo.aspect = 1; sol/sağ tam ekran iki WebGLRenderTarget → FullScreenQuad (R|GB birleşimi)
Gerçek projede pencere boyutu, XR oturumu veya anaglif için kullandığınız modülün API’si farklılık gösterir; önemli olan sol/sağ projeksiyonların aynı sahne anına denk gelmesi ve konfor için parallaks sınırlarını aşmamaktır.
Teknik tablo: StereoCamera parametreleri
| Parametre | Açıklama | Tipik Değer / Not |
|---|---|---|
eyeSep |
İki sanal göz arasındaki fiziksel mesafe (kullanılan sahne birimi ölçeğinde hesaplanır). | 0.064 (Ortalama insan göz aralığı baz alınmıştır) |
aspect |
Her bir göz kamerası için en-boy oranı; bölünmüş ekran (split-screen) kurgularında genellikle toplam ekran genişliğinin yarısı olarak ayarlanır. | 0.5 (Yatay eksende ikiye bölünmüş görünümler için standarttır) |
cameraL |
Sol gözü temsil eden PerspectiveCamera nesnesi. |
update() metodu aracılığıyla ana kameraya göre otomatik senkronize
edilir. |
cameraR |
Sağ gözü temsil eden PerspectiveCamera nesnesi. |
update() metodu aracılığıyla ana kameraya göre otomatik senkronize
edilir. |
Derinlik yanılsaması: yakınsama ve parallaks
Stereoskopik içerikte rahatlık önceliklidir. İki görüntü arasındaki yatay kayma (parallaks) çok büyürse gözler zorlanır, baş ağrısı ve mide bulantısı riski artar.
Sol ve sağ görüntüdeki yatay kayma, nesnenin ekran düzlemine göre nerede “oturduğunu”
sınıflar; demo’da nesne Z’si ve eyeSep bu kaymayı hissettirir:
- Pozitif parallaks: Sol ve sağ görüntülerdeki nesne kenarları birbirine
zıt yönlerde kaymış gibi
konumlanır; bu durum, insan beyninin nesneyi fiziksel ekran düzleminin
arkasında, sanal
sahnenin derinliklerinde algılamasını sağlar. VR başlıkları ve karton tabanlı
sistemlerde (Google Cardboard vb.)
ana sahne geometrisi genellikle bu alanda tutulur, çünkü uzun süreli deneyimlerde gözü
en az yoran ve algı
toleransı en yüksek olan bölge burasıdır. Ancak, çok uzak nesneler ve yüksek
eyeSepdeğerlerinin birleşimiyle oluşan uç pozitif parallaks seviyeleri odaklanma zorluğu yaratabilir; bu nedenle derinlik hissini her zaman ölçülü ve dengeli kurgulamak gerekir. - Negatif parallaks: Kayma yönü doğrudan izleyiciyi işaret eder ve nesnenin fiziksel ekrandan dışarı taşıp üzerinize geliyormuş gibi algılanmasına (pop-out etkisi) neden olur. Bu yöntem; mermi yörüngeleri, aniden beliren yaratıklar veya öne çıkan dramatik UI efektleri gibi kısa süreli vurgular yaratmak için oldukça güçlüdür. Fakat sürekli veya aşırı düzeyde negatif parallaks kullanımı göz kaslarını ciddi şekilde zorlayarak baş ağrısı ve göz yorgunluğu riskini artırır. Üretim aşamasında bu etkiyi bilinçli bir şekilde sınırlamalı ve ana etkileşim alanlarını (gameplay loop) ağırlıklı olarak sıfır veya hafif pozitif bölgede güvenceye almalısınız.
- Sıfır parallaks: Sol ve sağ kameralardan gelen görüntülerde nesne kenarları kusursuz bir şekilde aynı hizada çakışır. Herhangi bir derinlik ipucu (kayma) barındırmadığından, izleyici nesneyi doğrudan fiziksel ekran düzlemine yapışık olarak yorumlar. Bu katman genellikle okunabilirliğin kritik olduğu metinler, nişangahlar (retikül), menüler ve sabit kalması gereken HUD/UI bileşenleri için idealdir. Sahne geometrisinin büyük bir kısmını sıfır parallaks düzleminde bırakmak stereo 3D etkisini zayıflatacaktır; ancak konfor açısından burası, izleyicinin gözlerini doğal odak mesafesinde tutarak dinlenebildiği "referans düzlemi" olarak işlev görür.
Yakınsama (convergence) doğrudan
StereoCamera üzerinde ayrı bir "cevher" olarak ayarlanmaz; iki gözün
projeksiyon ve ofset hesapları birlikte, izleyicide hangi derinlik düzleminin rahat
okunduğunu dolaylı olarak belirler. Konfor için sahne tasarımı, nesne
yerleşimi ve üst katman (XR / efekt) ayarları birlikte düşünülür.
Holodepth notu: VR dünyasına giriş
StereoCamera, Holodepth haritasında ileri düzey veya
WebXR odaklı bir başlıkta derinleştirilebilir. Başlık taktığında
Three.js ve ekosistem çoğu zaman stereoskopik çifti sizin için bağlamaya yakın bir
akış sunar; buna karşılık kendi anaglif pipeline’ınızı veya basit bir
karton gözlük modunu yazmak istiyorsanız, bu kameranın ürettiği sol/sağ
projeksiyon matematiğini bilmek sizi bir adım öne taşır.