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 veya fotoğraf makinesi, uzaklaşan nesneleri daha küçük gösterir; paralel çizgiler uzakta bir noktada birleşir gibi görünür. Bu perspektif hissi, 3B sahnenin “içinde durma” deneyiminin temelidir; mimari gezinti, oyun ve sinematik kamera için beklenen görünüm budur.

Three.js'te bunu varsayılan olarak üreten sınıf PerspectiveCamera'dır: dünya uzayındaki noktaları perspektif kurallarıyla ekrana indirger. Oyun ve ürün vizualizasyonunun büyük çoğunluğu bu türle çalışır; teknik karşılığı OrthographicCamera'dır (ölçek sabit, CAD / 2.5D hissi); OrthographicCamera sayfasında.

Bu sayfa PerspectiveCamera'a özeldir: iz düşüm mantığı, frustum diyagramı, fov / aspect / near / far, playground ve resize. Genel kamera dili (view / projection, Object3D, frustum culling) için Kamera giriş sayfasına dönün; FOV ve kırpma düzlemlerinin kavramsal özeti oradaki teknik kavramlar bölümündedir.

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

Perspektif izdüşümde, kameradan çıkan görüş doğrultuları tek bir noktada birleşir gibi düşünülür; paralel koridor çizgileri uzakta kaçış noktasına yaklaşır. Aynı boyuttaki iki nesne, uzakta ekranda daha küçük, yakında daha büyük görünür; bu, gerçek göz ve fotoğraf makinesiyle aynı sezgidir. Three.js bunu PerspectiveCamera ile matematiksel olarak uygular; ölçek sabit kalan OrthographicCamera izdüşümünden temel fark budur.

Sonuç olarak sahnede derinlik, hacim ve mesafe hissi oluşur: ön plandaki obje arka plandan ayrılır, koridor “içeri doğru uzar”. Mimari gezinti, birinci şahıs oyun veya sinematik kamera gibi "dünyanın içindeymiş" deneyimlerinde bu tür varsayılan tercihtir; teknik çizim veya HUD düzlemi gibi oranın korunması gereken işlerde genelde ortografik kamera tercih edilir.

Aşağıdaki etkileşimli şema, bu mantığın görüş hacmi (frustum) karşılığını gösterir: kamera noktası, FOV açısı ve yakın / uzak düzlemler. Sayısal parametreler ve canlı önizleme sonraki başlıklarda.

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): Three.js'te varsayılan olarak dikey bakış açısıdır (derece). Açı büyüdükçe daha geniş bir koni görürsünüz — sahne “yakınlaşmış” gibi hissedilir; bu, kamerayı fiziksel olarak kaydırmadan elde edilen dijital zoom etkisidir. Pratik aralık çoğu projede 45°–75° civarıdır: 5060° nötr, 70°+ geniş açı (kenarlarda belirgin distorsiyon, balık gözü), 35°–45° telefoto / sinematik sıkışıklık. Değeri kodda veya playground sürgüsünde değiştirdikten sonra camera.updateProjectionMatrix() çağrılmazsa ekrana yansımaz.
  • Aspect (en–boy oranı): Görüntü alanının genişlik / yükseklik oranıdır; dairelerin yuvarlak, insan figürlerinin orantılı kalması buna bağlıdır. Canvas penceresi yeniden boyutlandığında camera.aspect güncellenmezse küreler elips, zemin ızgarası dikdörtgen görünür — tam ekran uygulamalarda resize olayında renderer.setSize ile birlikte aspect’i senkron tutmak standarttır. İlk kurulumda geçici olarak 1 verip ilk resize’ta gerçek oranı yazmak yaygın bir kalıptır (aşağıdaki örnek kodda da böyledir).
  • Near (yakın kırpma): Kameranın görmeye başladığı en yakın düzlem; frustum piramidinin ön yüzüdür. Bu düzlemden daha yakındaki geometri çizilmez (kamera içinde kalmış gibi kesilir). Başlangıç için 0.1 sık kullanılır; sahne birimlerinize göre ölçekleyin. near gereğinden küçük (ör. 0.001) seçilirse derinlik tamponu hassasiyeti dağılır — yüzeylerde titreme ve z-fighting artar. Çok büyük near ise kameraya yakın duvar veya zemin aniden kaybolur; playground’da near sürgüsü bunu gösterir.
  • Far (uzak kırpma): Görüşün kesildiği uzak düzlem; frustum’un arka yüzü. Bu mesafeden ötesi çizilmez (gökyüzü kutusu veya sis ile gizlenir). Infinity teoride mümkün olsa da derinlik aralığı GPU’da sınırlı çözünürlükle paylaşılır; near ile far arasındaki fark ne kadar genişse, yakın derinlikteki ayrım o kadar kötüleşir. Sahne boyutuna uygun üst sınır (ör. birimler metre ise 5002000) genelde 1e6 veya sonsuzdan iyidir — hem performans hem görsel tutarlılık için. Koridor demosunda uzak kesiti göstermek için far bilinçli olarak sıkı tutulmuştur; üretim sahnenizde genelde daha geniş seçersiniz.

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? Kısaca: izleyici sahneyin içinde veya gerçek bir kamera kadrajıyla bakıyorsa; ölçülerin ekranda “yakınlaşıp uzaklaşması” isteniyorsa; PerspectiveCamera doğru varsayılandır.

  • Oyunlar ve etkileşimli 3D: Birinci / üçüncü şahıs gezinti, araç simülasyonu, VR önizleme gibi deneyimlerde oyuncu dünyayı perspektifle okur; koridor, kapı ve engellerin uzaklığı bu sayede anlaşılır. Kamera hareketi ve FOV ile gerilim veya geniş açı hissi verilir — teknik ayrıntılar yukarıdaki frustum ve parametre bölümlerinde.
  • 3D sahne, ürün ve mimari: Konfigüratör, mobilya / iç mekân turu, dış cephe gezintisi, “ürünü masada döndürme” vitrinleri. Müşteri veya kullanıcı mekânın derinliğini ve ölçek hissini kavramak istediğinde perspektif doğal gelir; statik hero görsel yerine gezilebilir sahne hedefleniyorsa bu tür seçilir.
  • Gerçekçi derinlik ve perspektif: Ön plan–arka plan ayrımı, kaçış çizgileri ve mesafe algısı önemliyse — sinematik kare, dramatik açı, “büyük salon” hissi — perspektif kamera kullanılır. Aksi halde sahne kartpostal gibi düz ve ölçek okunaklı kalması isteniyorsa aşağıdaki “kullanılmaz” listesine ve ortografik kameraya bakın.

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? Dünya sahnesi için perspektif doğru olsa bile, ekran uzayında sabit ölçek veya paralel çizgilerin bozulmaması şart ise tek bir PerspectiveCamera ile her şeyi çözmeye çalışmayın; ayrı kamera katmanı veya farklı kamera türü gerekir.

  • UI / HUD ve overlay: Can barı, minimap çerçevesi, menü, imleç, etiketler — piksel başına aynı boyutta kalmalıdır. Perspektif kamerasıyla çizilen bir düzlem kameraya yaklaştıkça büyür, uzaklaştıkça küçülür; bu yüzden HUD çoğu projede CSS/HTML katmanında veya ikinci bir OrthographicCamera ile render edilir. Oyun dünyası perspektif kalır; arayüz ekran uzayında ayrılır.
  • Teknik çizim, CAD ve izometrik düzlem: Ölçü çizgileri, kesit görünüşü, kat planı, fabrika yerleşimi veya strateji oyunundaki “harita” düzlemi — paralel kenarlar ve mesafelerin okunaklı kalması gerekir. Perspektifte uzak köşeler küçülür, duvarlar eğimli görünür; bu da ölçüyü yanıltır. Bu senaryolarda ortografik (veya özel izometrik) izdüşüm tercih edilir; ayrıntılar Ortografik Kamera sayfasında.

Özet: yukarıdaki iki grupta amaç distorsiyonsuz, ölçülü veya ekrana kilitli görünümdür. Kamera türleri ve frustum 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.