holodepth

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ızca position’ı oynatıp target’ı sabit bırakırsan yönü tam kontrol etmeyebilirsin. Varsayılan hedef Vector3(0, 0, 0)’dır — gerekirse light.target.position ile 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.

DirectionalLight ve PointLight
Ö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).

Karşılaştırma · Dolgu vs Directional

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.jsmakeShadowedDirectional + 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.

diagram-directional-light.js — Split Demo Sabitleri
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.