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.
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.
| 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ı | 2× 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 < far − 0.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.