Three.js · Işık · Yönsel
DirectionalLight: Uzak dünyaların güneşi
Paralel ışınlar — kaynak nerede değil, nereye baktığı her şeyi belirler
Sahnede gerçek bir “güneş” etkisi istediğinde aradığın şey DirectionalLight’tır.
Bu ışığı diğerlerinden ayıran en büyük fark, ışık ışınlarının birbirine paralel
olmasıdır. Kaynak o kadar uzaktadır ki, ışığın tam olarak nerede durduğu değil,
hangi yöne baktığı aydınlatmayı ve gölge yönünü tanımlar.
Bağlam: AmbientLight, HemisphereLight, Materyal Giriş.
Zihin modeli: paralel ışınlar
Dev bir lamba değil — evrenin bir ucundan gelen ışık duvarı
- Kaynak: Sonsuz uzaklıktadır (mesafe parlaklığı değiştirmez).
- Işınlar: Birbirine tamamen paraleldir; tek bir noktadan radyal yayılım yoktur.
- Gölge: Nesneler arası mesafe ne olursa olsun, gölgeler aynı yöne paralel düşer.
- Amaç: Ana aydınlatma ve sahneye yönlü derinlik — formu okutan kontrast.
Paralel ışınlar ve “mesafe” yanılgısı
DirectionalLight’ta parlaklık, ışığın dünya uzayında ne kadar uzakta
durduğuna bağlı değildir; bu, ampul veya nokta ışık sezgisiyle çakışan en sık
zihinsel tuzaktır. Uzaklığı büyütmek güneşi “soluklaştırmaz” — yalnızca geliş
vektörünü ve gölge haritası için kullanılan kameranın başlangıcını
kaydırırsın. Bu yüzden güneşi sahneye göre makul bir küre üzerinde konumlandırıp asıl dramı
intensity, renk ve gölge kutusu ile kurmak daha güvenlidir.
Sonsuz mesafe ≠ sonsuz enerji (gerçek dünya): Güneşten uzaklaştıkça
gerçekte de parlaklık azalır; DirectionalLight modeli ise mesafeyle
şiddeti düşürmez — bu bilinçli bir matematiksel kısaltmadır. İleri seviye
okumada: fiziksel doğruluk istiyorsan mesafe ve atmosferi başka sistemlerle (exposure,
post, sahte sis) taklit edersin; yönsel ışığın çekirdek rolü yine yöndür.
Gölge haritası neden “güneş kamerası” gibi düşünülür?
Yönsel ışıkta gölge üretmek, sahneyi ışığın gözünden tek bir yönde
projeksiyon
etmeye benzer. Three.js bu projeksiyonu ortografik bir shadow.camera ile
sınırlar; kutu dışı kalan geometri gölge haritasına düşmez veya kesilir. Paralel ışınlar
sayesinde tüm gölgeler aynı yönde uzanır — mimari görselleştirme ve açık dünya sahnelerinde
“tek güneş” okuması bu yüzden doğal gelir.
Çözünürlük vs. alan: shadow.mapSize sabitken
shadow.camera kutusu genişledikçe aynı tekstür alanı daha
büyük dünya hacmine yayılır — yani metre başına düşen gölge çözünürlüğü
düşer,
detay seyrelir. Kutu büyütmek “bedava” değildir; genişletince çoğu zaman
mapSize veya cascade stratejisiyle denge ararsın.
DirectionalLight nasıl davranır?
Davranışı yöneten iki temel öğe konum ve hedef ile ilişkilidir:
position: Uzaklık şiddeti değiştirmez (güneşten bir metre uzaklaşmak gibi düşünme). Konum, ışığın geliş açısını ve gölge yönünü belirler. Gölge haritası için kullanılan ortografik kameranın başlangıç noktası da burasıdır.target: DirectionalLight her zaman bir noktaya doğru “bakarak” yönlenir. Yalnızcaposition’ı oynatıptarget’ı sabit bırakırsan yönü tam kontrol etmeyebilirsin. Varsayılan hedefVector3(0, 0, 0)’dır — gerekirselight.target.positionile güncellenir ve sahneye eklenir.
Hedef (target) ve sahne grafiği
Işık her zaman position ile target.position arasındaki doğrultuda
“bakmış” gibi modellenir. light.target varsayılan olarak kökte
(0,0,0) civarındadır; farklı bir odağı istiyorsan hedefi hareket ettirip
mutlaka sahneye eklemelisin — aksi halde bazı kurulumlarda beklediğin
matris güncellemesi gelmeyebilir. Hedefi başka bir Object3D’ye parent etmek
(ör. karakterin göğsüne) güneşi veya spot benzeri yönsel davranışı animasyonla taşımak için
de kullanılır.
Cascade (CSM) notu — tek cümlelik bağlam
Geniş zeminlerde tek bir gölge haritası çözünürlüğü yetmediğinde üretimde sıkça
cascade shadow maps (CSM) devreye girer: mesafeye göre birden fazla
kademeli harita, yine paralel güneş varsayımıyla çalışır. Three.js ekosisteminde bu ihtiyaç
çoğu zaman örnek yardımcılar veya proje içi soyutlamalarla kurulur; burada önemli olan,
yönsel ışığın zihinsel modelinin paralel ışın + kutu sınırlı projeksiyon
olduğunu unutmamaktır — ölçeği büyüttükçe kutuyu veya kademeleri büyütmeden yalnızca
uzaklığı şişirmek sorunu çözmez.
Tipik düzen: yakın–orta–uzak gölge katmanları — her kademe
kendi
projeksiyonunda daha az alanı kaplar, böylece aynı toplam mapSize bütçesiyle
izleyiciye yakın bölgede daha sık texel kalır.
Hızlı kıyas: DirectionalLight vs. PointLight
“Ana ışığı hangi tür seçeyim?” sorusu çoğu zaman mesafe modeli ve
gölge maliyeti üzerinden çözülür. Yönsel ışık, tek bir geliş yönüyle tüm
sahneyi eşit şiddette aydınlatır; nokta ışık ise her yöne yayılır ve mesafeyle zayıflar
(decay ile). Tablo, bu iki formu bir cümlelik karar ağacına indirger.
Web tabanlı vitrinlerde tek güneş + dolgu kombinasyonu sık görülür; lokal sıcaklık (lamba,
fener) gerekiyorsa nokta veya spot devreye girer. Bir sonraki sayfada
PointLight
akışını ayrıntılandıracağız — buradaki tablo, o sayfaya geçmeden önce zihin modelini
hizalar.
| Özellik | DirectionalLight |
PointLight |
|---|---|---|
| Işık yayılımı | Paralel (güneş gibi) | Radyal (ampul gibi) |
| Mesafe etkisi | Yok (her yeri aynı aydınlatır) | Var (uzaklaştıkça azalır) |
| Gölge tipi | Paralel gölgeler | Dağılan (omni) gölgeler |
| Hesaplama yükü | Orta | Yüksek |
Görsel gözlem: sahneyi nasıl değiştirir?
- Hacim: Bir yüzey aydınlık, karşı yüzey karanlık kalır; formlar belirginleşir. Bu kontrast, formu algılamanın temel görsel ipucudur.
- Keskin gölgeler: Sahneye “yer çekimi” ve aidiyet hissi katan sert gölgeler oluşur (gölge haritası açıksa).
- Vurgu: Işığın geliş yönüyle highlight alanlarını seçerek odağı yönlendirebilirsin.
Kontrast ritmi: dolgu + yönsel
Yalnız yönsel ışıkla çalıştığında gölgeler derinleşir; yalnız dolguyla çalıştığında formlar yumuşar. İkisi birlikte, izleyicinin gözünün önce şekli sonra materyal ve rengi okumasına izin veren bir ritim kurar. Bu sayfadaki split demo, aynı dolgu şartlarında yönsel ışığın eklediği paralel gölge dilimini izole eder — “daha fazla ambient” ile telafi etmeye çalışmak yerine, dramayı yönsel tarafta tutup dolguyu düşük tutmak genelde daha temiz bir sonuç verir.
İnteraktif: dolgu vs. yönsel güneş
Aynı geometri ve aynı AmbientLight + HemisphereLight dolgusu:
sol yarıda DirectionalLight yok — yönsel kontrast ve keskin
gölge yok. Sağ yarıda tek bir DirectionalLight (güneş)
eklenir; iki ince sütunun zemindeki gölgeleri aynı yönde kalır — paralel
güneş ışınlarının tipik görünümü. Azimuth sürgüsü güneşin dönüşünü, ikinci sürgü
intensity’yi ayarlar (×0.92 ölçek).
İsteğe bağlı ses: aynı bölümde, demo kutusundan ayrı sütun genişliğinde şerit — dosya adı
Directional-Light-Demo (uzantı sırasıyla denenir).
Sol: yalnızca dolgu — form yumuşar, “güneş” vurgusu yok.
Sağ: DirectionalLight ile ana aydınlatma ve
PCFSoftShadowMap gölgeleri. Mesafe parlaklığı değişmez; yönü azimuth ile
döndürünce tüm gölgeler birlikte kayar.
Split ekranı nasıl okumalısın?
Sol yarı, AmbientLight + HemisphereLight ile dip
aydınlık varken yönsel ana ışığın olmadığı “bulutsuz öğle” gibi düz bir hacim
gösterir. Sağ yarı aynı dolguya tek bir DirectionalLight ekler; iki ince
sütunun gölgelerinin aynı vektörde kaldığını görmek, paralel ışın modelinin
en hızlı kanıtıdır. Azimuth sürgüsü güneşi yatayda döndürür; tüm gölgeler birlikte kayar —
bu, hedef noktası etrafında dönen tek bir güneş hissidir.
Uygulama: profesyonel güneş kurulumu
Aşağıdaki blok, üst bölümdeki interaktif demo
(diagram-directional-light.js — makeShadowedDirectional +
setSunPosition) ile aynı sabitleri verir. Önce tablo ön
harita;
kodda renk 0xfff5e8, şiddet sürgüsü ×0.92, yön
azimuth (küresel güneş).
Kendi sahneye taşırken bu rakamları bire bir kopyalamak şart değil; tablo, HUD’daki
sürgülerin arkasındaki hangi sabitin neye karşılık geldiğini gösterir.
Örneğin gölge kutusunu genişlettiğinde aynı intensity bile daha yumuşak
görünebilir — bu yüzden önce kutuyu CameraHelper ile doğrulayıp sonra parlaklık
oynamak daha az döngü gerektirir.
Ön harita tablosunu nasıl kullanırsın?
İlk bloklar her iki yarıda ortak olan dolgu ve renderer ayarlarını toplar;
böylece split’in tek değişkeni yönsel ışık olur. “Sağ · güneş” satırları
DIR_INTENSITY_SCALE, küresel konum ve gölge kamerasını bir arada verir — kod
örneğindeki sabitlerle satır satır eşleştirilebilir.
| Sahne / rol | Parametre | Değer |
|---|---|---|
| Ortak · dolgu | AmbientLight + HemisphereLight |
0xe8ecf8 · 0.3; gök 0x87ceeb / yer
0x4a3d34 · 0.52 (addMatchingFill)
|
| Renderer | ACESFilmicToneMapping, exposure ≈1.05;
PCFSoftShadowMap
|
|
| Sol | Ana ışık | DirectionalLight yok — yalnız dolgu |
| Sağ · güneş | DirectionalLight |
0xfff5e8, temel intensity 1 → HUD
×0.92 × şiddet sürgüsü (DIR_INTENSITY_SCALE)
|
Konum (setSunPosition) |
SUN_RADIUS 13.5, SUN_PHI Math.PI * 0.445,
azimuth sürgüsü 0°–360° (varsayılan 38°) |
|
| Gölge kutusu | d = 6, mapSize 2048, radius 2,
near 0.25 / far 32, bias /
normalBias
|
// Interaktif demo ile aynı çekirdek (makeShadowedDirectional + setSunPosition)
const sunLight = new THREE.DirectionalLight(0xfff5e8, 1);
sunLight.castShadow = true;
sunLight.shadow.mapSize.set(2048, 2048);
sunLight.shadow.radius = 2;
sunLight.shadow.bias = -0.00012;
sunLight.shadow.normalBias = 0.02;
const d = 6;
sunLight.shadow.camera.left = -d;
sunLight.shadow.camera.right = d;
sunLight.shadow.camera.top = d;
sunLight.shadow.camera.bottom = -d;
sunLight.shadow.camera.near = 0.25;
sunLight.shadow.camera.far = 32;
// Güneş yönü: demoda varsayılan azimuth ≈38° + küresel (SUN_RADIUS, SUN_PHI, theta)
const SUN_RADIUS = 13.5;
const SUN_PHI = Math.PI * 0.445;
const theta = THREE.MathUtils.degToRad(38);
sunLight.position.setFromSpherical(new THREE.Spherical(SUN_RADIUS, SUN_PHI, theta));
sunLight.target.position.set(0, 0, 0);
scene.add(sunLight);
scene.add(sunLight.target);
// Demoda: sunLight.intensity *= 0.92 * (sürgü 0–1)
API tarafında hatırlatma
DirectionalLight kurucusu renk ve başlangıç intensity alır; güneş
yönü için pratikte position + target çifti kullanılır. Demodaki
setSunPosition, aynı yükseklik açısı (SUN_PHI) üzerinde yalnızca
azimuth’u değiştirerek yatay güneş turu üretir — kendi uygulamanda euler
açıları veya kısıtlanmış bir gün döngüsü için aynı küresel fikir genişletilebilir.
Gerçek sahne: üretim standartları
Güneş rengi: Saf beyaz yerine hafif sarımsı (0xffffcc) veya
gün batımı için turuncu tonlar gerçekçiliği güçlendirir.
Shadow camera: Objen ışığın altındayken gölgesi kesiliyorsa
shadow.camera.left / right / top /
bottom değerlerini artırarak gölge kutusunu genişlet.
Aynı mapSize ile kutu genişledikçe zemindeki gölge detayı
seyrekleşir
— bölüm 1’deki “çözünürlük vs. alan” notu burada pratiğe döner.
Performans: mapSize’ı yükseltmek kaliteyi artırır fakat bellek
ve doldurma maliyetini artırır; mobilde 1024 veya hibrit strateji sık denenir. Tek
yönsel ışıkta genelde bir gölge haritası yönetmek nokta ışıklara göre daha öngörülebilir
kalır.
Sanat yönetimi: Güneş rengi ile dolgu (HemisphereLight) arası
uyumu bozmadan yönsel rengi sıcaklaştırmak, metal yüzeylerde specular diliminin hâlâ okunur
kalmasına yardım eder; tersine soğuk güneş + soğuk dolgu bazen klinik bir stüdyo hissi
verir — bilinçli bir tercih olmalıdır.
Yaygın hata: gereksiz uzaklık
Işığı kilometrelerce uzağa taşımak
Hata: Konumu aşırı uzağa almak (ör. position.x = 10000) —
parlaklığı düşürmez.
Sonuç: Gölge hesaplarında hassasiyet kaybı, shadow acne ve depth fighting riski artabilir.
Doğru yaklaşım: Konumu sahneyi kapsayacak makul bir uzaklıkta tut; asıl kontrolü açı ve shadow camera sınırlarıyla yap.
Shadow acne ile Peter panning’i karıştırma: acne, gölge haritasının yüzeye yapışık artefakt (tırtıklı / kirli) üretmesidir; peter panning ise gölge bloğunun yüzeyden koparak havada süzülmesidir — ikisi zıt yönde bias ayarı ister. Ayrıntı için Bias & Shadow Acne sayfasına bak.
Aşırı uzak konum bazen derinlik tamponunda z-fighting veya ince gölge çizgilerinde titreme olarak geri döner; çözüm mesafeyi şişirmek değil, gölge bias / normalBias ve kutu sınırlarını birlikte kalibre etmektir. Işığı sahne merkezine yakınlaştırıp yine de aynı açıyı korumak, birçok projede daha stabil bir gölge hacmi verir.
Holodepth ilkesi
Ana ışık + dolgu
Ana ışık (DirectionalLight) form verirken, yardımcı bir
AmbientLight veya HemisphereLight gölgelerin içindeki
karanlığı yönetir. İkisi birlikte dengeli bir taban oluşturur.
Holodepth çizgisinde yönsel ışık “hikâyeyi anlatan” katmandır: izleyici nereden baktığını, nesnelerin birbirine göre boyutunu ve zemine temasını bu katmandan okur. Dolgu ise bu hikâyeyi siyaha gömmemek için taban aydınlık taşır — ikisinin rolünü karıştırmamak, sahne kurarken en az poli sayısı kadar önemlidir.
Production notu
Gölge kamerasını ayarlarken
new THREE.CameraHelper(light.shadow.camera) kullan.
Körlemesine sayı girmek yerine, ışığın sahnede hangi hacmi “gördüğünü” görselleştirerek hem
kapsamı hem performansı optimize edersin.
normalBias neden var? Derinlik karşılaştırmasında yüzeyi
ışığa göre hafifçe ofsetlemek için kullanılır; özellikle eğimli yüzeylerde
(yüksek slope) surface acne’yi azaltmaya yardım
eder — sabit bias tek başına yetmediğinde eğim duyarlı ince ayar budur.
Aşırı değer peter panning’i tetikleyebilir; kutu + mapSize ile birlikte küçük
adımlarla ilerle.
Devam: tek noktadan her yöne yayılan
PointLight
(ampul ışığı) rehberi ve interaktif karşılaştırma — aşağıdaki özet kutusundan da tek tıkla
geçebilirsin.