holodepth

Three.js · Kamera türleri

PerspectiveCamera (perspektif kamera) — gerçek dünya görüşünü simüle etmek

Gerçek dünyada gözümüzün veya bir fotoğraf makinesinin dünyayı görme biçimi perspektif prensibine dayanır; nesneler uzaklaştıkça küçülür. Three.js'te bu derinlik algısını simüle eden en temel ve en yaygın yapı PerspectiveCamera'dır. Genel kamera zihin modeli için Kamera Giriş sayfasına bakabilirsiniz.

Perspektif izdüşümün mantığı

Perspektif kamera, 3D uzaydaki noktaları ekran düzlemine aktarırken bir kaçış noktası kullanır. Bu, sahnede doğal bir derinlik, hacim ve mesafe hissi yaratır. Mimari görselleştirme veya oyun gibi "dünyanın içindeymiş" hissi vermek istediğiniz projelerde bu kamera türü varsayılan tercihtir.

Perspektif · kırpma hacmi

Viewing frustum — perspective clip volume

Görüş frustum’u (kesik piramit): kamera orijinde; near ve far düzlemleri arasındaki hacim, rasterleştirmede asıl "görünür" bölgendir. Three.js PerspectiveCamera ile uyumlu eksenler: Y yukarı, +X sağa, bakış doğrultusu −Z.

Çizim ölçekleri yalnızca anlatım içindir; gerçek near / far değerlerini sahne ölçeğine göre seçersiniz. Üstteki şemada dönüşü duraklatabilir, hız ve yakınlaştırmayı kaydırıcılarla veya fare tekerleği ile oynayabilirsiniz; FOV ile yakın/uzak düzlemler canlı güncellenir. Yakın / uzak dörtgeninin üzerine gelince vurgu artar; Oyun · Mimari · Sinematik ön ayarları tipik FOV aralıklarını dener; Görünümü sıfırla sayfa değerlerine döner. Şemada dikey FOV yayı ve sağ sütunda FOV (°) ile Kamera etiketi sürekli görünür; fare üzerine gelince veya canvas’a odaklanınca yakın/uzak düzlem ve görüş doğrultusu etiketleri sağ sütunda açılır (İngilizce alt satırlarla).

Terimler

  • Kamera eye — view space orijini
  • Yakın düzlem near — yakın kırpma düzlemi
  • Uzak düzlem far — uzak kırpma düzlemi
  • Görüş doğrultusu line of sight (−Z) — Three.js bakış yönü

Perspective Effect Playground

Bu WebGL önizlemesi kameranın görüşünü gösterir; sahne ve kamera konumu sabittir — oynanan tek şey PerspectiveCamera’nın FOV, near ve far değerleri. Uzun koridor, zeminde paralel ızgara çizgileri ve yinelenen sütunlar: FOV yükseldikçe yan duvarlar ve ızgara hızlı “içeri kapanır” (geniş açı); düşürdükçe sahne daha düzleşmiş (telefoto) görünür. Near’ı büyütünce yakın kırpma belirginleşir; far’ı küçültünce uzak uçlar kesilir — z-fighting riski için near’ı aşırı küçültme. Aşağıdaki senaryo kartları aynı FOV fikrini üstteki şemadaki Oyun · Mimari · Sinematik örnekleriyle bağlar; kart seçince hem açı hem neden birlikte gelir.

Perspective Effect Playground · koridor · WebGL

Kart bir senaryo seçer (FOV + neden); FOV sürgüsünü elle oynatırsan seçim özel moda döner (yeniden kart seçene kadar).

Kamera konumu sabit; yalnızca projeksiyon parametreleri güncellenir. Zemindeki GridHelper çizgileri perspektifte tek bir uzak noktada toplanıyor gibi görünür — FOV ile bu “kapanma” hızını karşılaştır. Ortadaki vurgulu küp ve yan sütunlar aynı ölçekte kalır; near / far ile hangi derinlik bandının rasterleştirildiğini hisset. Üstteki 2D frustum şeması ile aynı kavramları burada 3B uzayda deniyorsun. Koridor + ızgara: paralel çizgiler, derinlik ve distorsiyonu tek bakışta kıyaslamak için uygun bir “laboratuvar” zemini.


Üstteki Perspective Effect Playground (diagram-perspective-playground.js, data-material-demo="perspective-playground") ile aynı sayıları ön harita tabloda topladık. Sürgüler ve senaryo kartlarıyla değişenler HUD satırında; kalan satırlar dosyadaki sahne sabitleridir. Tür sütunu: ekrandaki kontroller ile kaynak koddaki sabitleri ayırır.

Bu demo’da kontrol edilenler

  • FOV (°) → dikey bakış açısı; sürgü veya senaryo kartı
  • Near → yakın kırpma düzlemi
  • Far → uzak kırpma düzlemi
  • Senaryo kartları → Oyun (80°) · Mimari (50°) · Sinematik (35°); FOV sürgüsünü elle oynatınca Custom çipine döner

Bunlar neyi etkiliyor? FOV, near ve far birlikte perspektif frustumunu — yani kameranın gördüğü kesik piramit hacmini — belirler. Rasterleştiricide ekrana düşen her şey, önce bu hacim içinde "görünür mü?" sorusuna göre hesaplanır; sürgü oynayınca değişen şey doğrudan bu hacimdir.

Kısa mental model: Near büyüdükçe kameraya çok yakın nesneler ve zemin kesilir (önünüz boşalıyormuş gibi). Far küçüldükçe uzaktaki koridor ucu ve sütunlar yok olur (sis + kırpma). İkisini birlikte düşünün: görünür dünya bandı daralıyor.

diagram-perspective-playground.js — Sayfa Demosu Sabitleri (perspective-camera.html playground)
Sahne / rol Parametre Değer Tür
Ortak · renderer Ton / gölge / temiz renk ACESFilmicToneMapping, exposure 1.05 · PCFSoftShadowMap · setClearColor(0x070b14) 🔒 Sabit
Renk uzayı / piksel oranı SRGBColorSpace (destekleniyorsa) · min(devicePixelRatio, 2) 🔒 Sabit
antialias / alpha true / false 🔒 Sabit
Ortak · sahne background + sis 0x070b14 · Fog(0x070b14, 14, 68) 🔒 Sabit
Işıklar + gölge AmbientLight 0x8aa0c0, yoğunluk 0.04 🔒 Sabit
HemisphereLight Gökyüzü 0x8aa8d0 · zemin 0x0a0e16 · yoğunluk 0.16 🔒 Sabit
DirectionalLight (güneş) 0xfff2ea · 1.22; konum (−4.5, 14, 10) · gölge haritası 1024², bias −0.00015, normalBias 0.02; gölge ortho ±26, near 1, far 72 🔒 Sabit
Zemin PlaneGeometry / materyal 16×96, renk 0x141a24, roughness 0.88, metalness 0.04; konum (0, 0, −30), gölge alır 🔒 Sabit
Izgara GridHelper Boy 88, bölüm 44, renkler 0x3d5570 / 0x1a2434; konum (0, 0.018, −30), opacity 0.55 🔒 Sabit
Koridor duvarları BoxGeometry 0.1×3.2×78; x = ±3.45, y = 1.6, z = −30 🔒 Sabit
Sütunlar 22 çift kutu Başlangıç z0 = 2.2, adım zStep = 2.85; taban 0.26², yükseklik 2.75 + (i%4)×0.12, x = ±2.38 🔒 Sabit
Odak küpü MeshStandardMaterial + kutu Renk 0xffd4a8, emissive 0x5c3010 yoğunluk 0.32; boy 0.95×1.65×0.95, merkez yaklaşık (0, 0.825, −14) 🔒 Sabit
Sahne kamerası PerspectiveCamera ctor Başlangıç FOV 55, aspect 1 (ilk kare; sonra viewport), near 0.1, far 75 🔒 Sabit
Poz / bakış position (0, 1.58, 5.4) · lookAt(0, 1.42, −36)OrbitControls yok 🔒 Sabit
Kod · clamp syncCameraFromDom FOV 18…110 · near 0.02…4 · far 12…140; near < far0.05 🔒 Sabit (kod)
Senaryo → FOV FOV_BY_SCENARIO game: 80 · arch: 50 · cinematic: 35 🔒 Sabit (kod)
HUD · aralıklar (perspective-camera.html) Range input FOV 22…105 · near 0.02…2.2 · far 14…125 🔒 Sabit (HTML)
HUD başlangıç FOV / near / far 55 / 0.1 / 75 🔄 Dinamik (HUD)
HUD FOV, near, far, senaryo kartları Kullanıcı seçimi; readout + insight + mod çipi güncellenir 🔄 Dinamik (HUD)

Kurulum parametreleri: dört silahşör

Bir PerspectiveCamera örneği oluştururken verdiğiniz dört değer, kameranın görüş hacmini (frustum) matematiksel olarak tanımlar (şema). Aynı parametreleri 3B uzayda denemek için Perspective Effect Playground’a bakın.

Üstteki koridor demosunda bu dört değişkenin etkisini teoriye dokmadan görürsünüz: FOV arttıkça yan duvarlar ve ızgara hızla içeri kapanır (geniş açı hissi); near büyüdükçe kameraya çok yakın yüzeyler kesilir; far küçüldükçe koridorun sonu ve uzak sütunlar görünmez hale gelir. Aspect bu demoda viewport en/boy oranına kilitlenir — pencereyi genişletince sahne basık veya uzun kalmaz.

  • FOV (field of view): Dikey bakış açısı (derece). Pratik aralık: genelde 45°–75°. Çok yüksek değerler kenarlarda güçlü distorsiyon hissi verir; çok düşük değerler sahneyi "düzleşmiş" gösterebilir.
  • Aspect (en–boy oranı): genişlik / yükseklik (canvas veya görüntü alanı). Ekran boyutuyla senkron kalmazsa objeler basık veya uzun görünür.
  • Near (yakın kırpma): Kameranın görmeye başladığı en yakın düzlem; sık değer 0.1.
  • Far (uzak kırpma): Görüşün kesildiği uzak düzlem. Performans ve derinlik hassasiyeti için "sonsuz" yerine sahne ölçeğine uygun bir üst sınır (ör. 1000) seçmek genelde daha iyidir.

Aşağıdaki kurucu satırı, bölüm 1’deki Perspective Effect Playground başlangıcıyla (diagram-perspective-playground.js ve üstteki tablo) hizalıdır. Genel örneklerde far sıkça daha büyük seçilir; koridor demosunda uzak uç kesilmesini görmek için 75 civarı bilinçli sıkı tutulmuştur.

// diagram-perspective-playground.js — başlangıç (aspect ilk resize’ta viewport’tan yazılır)
const camera = new THREE.PerspectiveCamera(
  55, // FOV (°) — HTML sürgü başlangıcı; kod içi clamp 18…110
  1, // aspect — ilk ctor; resize() ile w / h güncellenir
  0.1, // near — başlangıç; clamp 0.02…4
  75 // far — başlangıç; clamp 12…140
);
// syncCameraFromDom: .fov / .near / .far yazıldıktan sonra mutlaka:
// camera.updateProjectionMatrix(); — yoksa yeni clip / açı ekrana yansımaz

Ne zaman kullanılır, ne zaman değil?

Ne zaman kullanılır?

  • Oyunlar ve etkileşimli 3D deneyimler
  • 3D sahneler, ürün görselleştirme, mimari / iç mekân önizlemeleri
  • Gerçekçi derinlik ve perspektif hissi gerektiren her türlü görselleştirme

Hızlı karşılaştırma: PerspectiveCamera uzaklaştıkça küçülen, yaklaştıkça büyüyen çizgilerle gerçek dünyaya benzer bir görünüm verir. OrthographicCamera ise paralel izdüşümle ölçü ve oranların daha "düz" ve okunaklı kalmasını sağlar; derinlik hâlâ vardır ama perspektif distorsiyonu yoktur.

Ne zaman kullanılmaz?

  • UI / HUD katmanları, ekran uzayı sabit ölçek isteyen overlay'ler
  • Teknik çizim, CAD tarzı ölçülü görünüm, izometrik "oyun haritası" düzlemi

Bu ikinci grupta genelde OrthographicCamera tercih edilir; perspektif distorsiyonu olmadan paralel izdüşüm elde edersiniz. Kamera türleri bağlamı için Kamera Giriş sayfasına dönebilirsiniz.

Dinamik yönetim: updateProjectionMatrix

Gerçek bir web projesinde kamera statik değildir. Pencere yeniden boyutlandığında aspect güncellenmelidir; yalnızca özelliği değiştirmek yetmez — camera.updateProjectionMatrix() ile projeksiyon matrisi yeniden hesaplanmalıdır. Aynı çağrı, kodla .fov / .near / .far değiştirdiğinizde de zorunludur — atlanırsa kamera özellikleri güncellenmiş olsa bile görüntü eski projeksiyonda kalır. Çıktı boyutunu güncellemek için Renderer tarafında da setSize çağrısı gerekir. Tam sayfa yerine bir konteyner içinde canvas kullanıyorsanız (ör. bölüm 1 playground), ResizeObserver ile o konteynerin boyutunu izlemek yaygın bir kalıptır.

// diagram-perspective-playground.js — ResizeObserver + viewport (tam pencere değil)
function resize() {
  const w = viewportEl.clientWidth || 640;
  const h = viewportEl.clientHeight || 360;
  renderer.setSize(w, h, false);
  camera.aspect = w / Math.max(h, 1);
  camera.updateProjectionMatrix();
  // FOV, near, far veya aspect değişince zorunlu — yoksa projeksiyon / görüntü güncellenmez
}

const ro = new ResizeObserver(() => {
  resize();
  syncCameraFromDom(); // FOV/near/far sürgüleriyle projeksiyonu tazele
});
ro.observe(viewportEl);

Teknik tablo: perspektif kamera özellikleri

Özellik / metot Açıklama Tipik değer
.fov Görüş açısı (derece). 50–75
.zoom Dijital yakınlaştırma faktörü. 1 (varsayılan)
.focus Stereoskopik etkiler için odak mesafesi. Örneğin 10
.filmGauge Film formatı simülasyonu (mm). Örneğin 35
setViewOffset() Çoklu monitör veya asimetrik görünüm ayarı.

FOV: senaryoya göre pratik aralıklar

Senaryo Tipik FOV (derece, yaklaşık)
FPS / aksiyon oyun hissi 75–90
Mimari, ürün, "sakin" kamera 45–60
Sinematik, tele objektif hissi 35–50

Uygulama: ideal kamera pozisyonlama

Kamera sahnede bir Object3D gibi davranır. Varsayılan olarak (0, 0, 0)'da oluşur; içerik görmek için genelde geri çekilir veya hedefe lookAt ile kilitlenir:

Aşağıdaki kod, bölüm 1’deki Perspective Effect Playground içindeki sabit kamera ile aynı position / lookAt değerlerini gösterir (bu demoda OrbitControls yok).

// Koridor demosu (diagram-perspective-playground.js) — sabit kamera, OrbitControls yok
const camera = new THREE.PerspectiveCamera(55, 1, 0.1, 75);

camera.position.set(0, 1.58, 5.4);
camera.lookAt(0, 1.42, -36);

// resize() sonrası aspect = viewport genişliği / yüksekliği

İnteraktif örneklerde kamerayı fareyle döndürmek için OrbitControls yaygın çözümdür; kamera ve renderer hazır olduktan sonra bağlanır, animasyon döngüsünde controls.update() çağrısı gerekir.

// Bu sayfadaki koridor playground'unda OrbitControls kullanılmıyor — genel örnek:
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const controls = new OrbitControls(camera, renderer.domElement);

function animate() {
  requestAnimationFrame(animate);
  controls.update();
  renderer.render(scene, camera);
}

Holodepth notu: Z-fighting

near değerini aşırı küçük (ör. 0.00001), far değerini aşırı büyük (ör. 999999) tutarsanız derinlik tamponu (Z-buffer) hassasiyetini kaybedebilir; üst üste binen yüzeylerde Z-fighting (titreme) görülebilir. Profesyonel sahnelerde bu aralığı mümkün olduğunca dar ve sahne ölçeğine uygun tutun.

Altın kural: far / near oranı mümkün olduğunca küçük olmalı. Örneğin 1000 / 0.1 = 10 000 çoğu web sahnesi için üst sınır civarında kabul edilebilir bir büyüklük; bunun çok üzerine çıkmadan önce gerçekten ihtiyaç olup olmadığını sorgulayın.