Three.js · Işık · Konik odak
SpotLight: Sahne ışığı ve dramatik odak
Karanlık ile aydınlık arasındaki keskin geçişi sen yönetirsin
SpotLight, tek bir noktadan doğan ancak
PointLight’ın aksine yalnızca
belirli bir konik alan içinde yayılan ışık türüdür. Işığın sınırlarını net
görebildiğin, karanlık ile aydınlık arasındaki o geçişi kontrol edebildiğin en güçlü yer
burasıdır.
Tiyatral bir atmosfer yaratmak, bir objeyi sahneye çıkarmak veya karanlığı bir el feneriyle delmek için en güçlü fırçandır.
Bağlam: DirectionalLight (paralel güneş), PointLight (tam küre), Materyal Giriş.
Zihin modeli: ışık konisi
Ampul değil — karanlığı belirli bir açıyla süpüren koni
- Kaynak: Tek bir koordinat noktasıdır.
- Yayılım: Konik — açıyla sınırlanmış bir hacim.
- Yönelim:
SpotLightyönünüpositioniletarget.positionarasındaki vektöre göre belirler. - Amaç: Sahne spotları, el fenerleri, araba farları ve odak noktası oluşturma.
Apex ve hedef: koninin omurgası
Spot geometrisini düşünürken zihninde tepe noktası (apex) ile
hedef arasında tek bir eksen çiz: koni bu eksen etrafında döner.
position apex’i, target.position ise koninin “baktığı” dünya
noktasını taşır; ikisi aynı hizada değilse koni eğilir ve gölge frustum’u beklediğin hacmi
kapsamayabilir. Bu yüzden hedefi bir Object3D üzerinden animasyonla taşımak,
sahnede “takip eden sahne ışığı” kurmanın en doğrudan yoludur.
Point’ten sonra gelen kesim
PointLight tüm küreyi
besler; SpotLight ise aynı enerjiyi önce konik bir hacme
keser,
sonra mesafe ve decay ile zayıflatır. Bu kesim, hem performans hem de
dramaturji açısından “nerenin aydınlık kalacağını” açıkça seçmeni sağlar — özellikle iç
mekân ve vitrin sahnelerinde vinyet hissi buradan gelir.
Kritik parametreler: açık ve yumuşaklık
SpotLight’ı “gerçekçi” kılan şey, dairesel ışık lekesinin kenarlarını nasıl
yönettiğindir:
angle(açı): Koninin ne kadar geniş olacağını belirler. Değer radyan cinsindedir ve API’de yarı açı (half-angle) olarak tanımlanır — örneğinMath.PI / 6yaklaşık 30° yarı açı demektir; tam açılık konik kesit kabaca 60° olur (2 × angle).penumbra(yarı gölge): Işık lekesinin kenarlarının ne kadar yumuşak geçeceğini belirler.penumbra, tam sert kenar ile yumuşak geçiş arasında bir bölge oluşturur (0–1 aralığında düşün).decay(sönümlenme): Fiziksel tabanlı aydınlatma kullandığında bu değer genellikle 2 olmalıdır — mesafeyle parlaklık düşüşü bu sönümle uyumludur.
Açı birimi: derece değil, radyan
API’de angle her zaman radyan cinsindedir; editör veya HUD’da
derece gösteriyorsan degToRad ile çevirmeyi unutma. Açıyı daraltmak koni
kesitini inceltir — aynı distance ve intensity ile bile sahne
daha “sinematik” ve odaklı okunur; geniş açı ise daha çok genel dolguya yaklaşır.
angle = yarı açı (half-angle)
Three.js’te spotLight.angle koninin yarı açısıdır (eksenden
koni yüzeyine kadar olan açı). Bu yüzden sezgisel “tam konik açı”yı düşünüyorsan gerçek
açılık kabaca 2 × angle olur — half-angle varsayımını
kaçırırsan sahneyi veya editör HUD’unu yanlış ölçeklersin (dar/geniş koni, gölge frustum’u,
sahne planı).
Yoğunluk: enerji koninin içine
SpotLight’ta parlaklık fikri, enerjinin konik hacim / kesit
içinde dağıtılmasıdır: angle küçüldükçe aynı
intensity
daha dar bir alana sıkışır — yani aynı enerji daha küçük taban üzerine
yoğunlaşır ve leke merkezi görece daha parlak okunur. Geniş açıda enerji daha
geniş bir tabana yayılır; bu yüzden “sadece açıyı daraltayım” dediğinde çoğu zaman
intensity’yi de birlikte dengelemek gerekir.
Demodaki decay (2.38) notu
Fiziksel taban için decay = 2 sık tercih edilir; bu sayfadaki interaktif
demoda ise menzil düşüşünü biraz daha hissettirmek için 2.38 kullanılır
(SPOT_DECAY_DEMO). Kendi üretiminde bu değeri kopyalamadan önce sahne ölçeği
ve ton eşlemesiyle birlikte A/B yap: abartılı decay, yakın nesneleri hızla
karartır ve distance sürgüsünün etkisini gölgede bırakabilir.
physicallyCorrectLights ve fiziksel ölçek
Eski Three.js sürümlerinde renderer.physicallyCorrectLights = true ile
intensity daha çok candela benzeri bir ölçeğe yaklaşır;
SpotLight için de decay = 2 fiziksel modda
beklenen taban olur.
Güncel sürümlerde bu bayrak kaldırılmış / davranış varsayılanlarla birleşmiş olabilir —
projende WebGLRenderer ve ışık birimleri için resmi migration notlarına bak.
Görsel gözlem: sahneyi nasıl etkiler?
- Vinyet etkisi: Sahnenin geri kalanını karanlıkta bırakarak izleyicinin gözünü doğrudan ışığın merkezine yönlendirir.
- Hacimsel gölgeler: Işık tek bir noktadan çıktığı için nesneler ışığa yaklaştıkça gölgeleri büyür; dramatik bir perspektif kazanır.
- Yüzey dokusu: Işığı yüzeye dar bir açıyla (oblique lighting) gönderdiğinde pürüzler ve dokular en iyi bu ışıkla okunur.
Penumbra ve düz yüzey
penumbra yarı gölge bölgesi, özellikle düz zemin ve düz arka
yüzeylerde ışık lekesinin kenarını yumuşatarak okunur; eğri ve karmaşık
normallerde fark doğal olarak daha az belirgin kalır. Demodaki arka düzlem, bu farkı
bilinçli
olarak öne çıkarmak için eklenmiştir — üretimde benzer bir “okuma yüzeyi” (duvar, perde)
koymak, sanatçı ile ışığı ayarlarken ortak dil oluşturur.
Penumbra: iç koni → dış koni
penumbra sıfıra yakınsa leke kenarı sertleşir; sıfırdan büyüdükçe Three.js
modelinde iç bölge (inner / core cone) tam güce yakın kalırken,
dış bölge (outer cone) kenara doğru yumuşakça söner — yani dış koni
halkasında fade (geçiş) oluşur. Düz zeminde bu halkayı en net okursun;
eğri yüzeylerde geçiş daha “dağılmış” görünür.
İnteraktif: küresel ampul vs. konik spot
Aynı torus knot + bloklar; sağda ek arka düzlem (biraz
açık ton) ve daha koyu zemin penumbra kenarını okutmak için kontrast
verir. Sol yarıda sıcak PointLight (kaynakta küçük
glow küreleri); sağ yarıda aynı konumdan
SpotLight — target torus merkezinde. Sarı küre
kaynak, emissive magenta hedef (hafif nabız), pembe çizgi
apex→target (yön), sağda her zaman hafif yarı saydam koni hacmi
(additive). Sürgüler yalnızca sağ spot için: angle, penumbra (HUD
değeri demoda eğrilir), distance, intensity (×4.25). İki kutu:
gölgeler (ışık ≠ gölge) ve koni tel kafesi (yalnız tel
çizgileri; hacim mesh’i açık kalır). Tel kafes çekirdek three.module.js ile;
üstteki satır anlık değerleri yazar.
İsteğe bağlı ses: aynı bölümde, demo kutusundan ayrı sütun genişliğinde şerit — dosya adı
Spot-Light-Demo (uzantı sırasıyla denenir).
Sol: aynı noktadan her yöne ışık — zemin ve bloklar daha eşit aydınlanır;
kaynakta küçük glow ile “her yere yayılıyor” ipucu güçlenir. Sağ: koni dışı
hızlı kararır; angle daralınca “sahne ışığı” gibi daralır.
penumbra özellikle zemin ve arka duvardaki ışık lekesinin
kenarında
fark edilir; HUD’un alt yarısı sert bölgeyi, üst yarısı yumuşamayı hızlandırır (demoda
eğri eşleme). Torus gibi ince eğride değişim doğal olarak daha azdır (normal).
distance + biraz yükseltilmiş demo decay menzil düşüşünü
güçlendirir. Gölgeleri kapatınca ışık kalır, gölgeler gider — aynı kavram üretimde de
geçerli. Tel kafes LineSegments; yarı saydam koni ShaderMaterial
(ek addons yok). PCFSoftShadowMap.
Split ekranı nasıl okumalısın?
Sol yarı, aynı kaynak konumundan tam küresel yayılımı hatırlatır; sağ yarı ise aynı geometride koninin dışını hızla karartan kesilmiş hacmi gösterir. Sarı kaynak ve emissive magenta hedef yön eksenini sabitler; pembe çizgi apex→hedef ilişkisini netleştirir; sağdaki hafif koni hacmi “görünür ışık hacmi”ni destekler. Gölgeleri kapatınca yalnız aydınlanma terimi değişir — bu ayrım, üretimde “önce ışık rengi ve hacim, sonra gölge” hata ayıklama sırasını destekler.
Uygulama: tiyatral spot kurulumu
Üstteki split sahne (diagram-spot-light.js) ile aynı sabitleri burada
ön harita tabloda topladık; aşağıdaki kod önce demodaki sağ
SpotLight kurulumunu, ardından genel “tiyatral” örneği hatırlatır. Gölge
haritası çözünürlüğü arttıkça kalite artar; GPU maliyeti de yükselir.
Tablodaki sayılar “tek doğru kurulum” değildir; amaç, HUD’daki her sürgünün arkasında hangi sabitin durduğunu ve sol/sağ sahnelerin dolgu seviyelerinin neden bilinçli olarak farklı seçildiğini göstermektir — sağda daha düşük dolgu, koni kenarının ve penumbranın zeminde okunmasına yer açar.
Ön harita tablosunu nasıl kullanırsın?
Üst bloklar ortak LIGHT_POS / TARGET_POS ve yardımcı geometrileri
listeler; ortada sol PointLight referansı, altta sağ SpotLight ve
renderer satırı gelir. Kod örneğindeki (A) bölümü doğrudan bu sırayla eşleştirilebilir;
(B) bölümü ise genel tiyatral kurulum için kısa bir şablondur.
| Sahne / rol | Parametre | Değer |
|---|---|---|
| Ortak · konum / hedef | Kaynak position |
(3.35, 5.05, 3.95) (LIGHT_POS) |
target.position |
(0, 0.62, 0) (TARGET_POS) |
|
| Ortak zemin (her iki sahne) | buildStage zemin rengi 0x263545 (kontrast; arka
düzlemden
ayrışır) |
|
| Görsel yardımcılar | Sarı küre kaynak; sol PointLight üzerinde emissive + additive halo;
hedefde emissive magenta + halo + hafif nabız; pembe Line
apex→target; sağda sürekli yarı saydam koni (ShaderMaterial,
additive); isteğe bağlı koni teli (LineSegments) |
|
| Arka düzlem (sağ ek geometri) | Penumbra / leke kenarı için düzlem (renk ≈ 0x7588a0); merkez
yaklaşık (0, 1.35, −4.85) |
|
| HUD · gölgeler / tel kafes | Checkbox: tüm mesh cast/receiveShadow + renderer gölge haritası;
tel kafes yalnız çekirdek three (addon yok); split iki yarıda
ortak cam.aspect |
|
Sol · PointLight (karşılaştırma) |
color / decay |
0xffd4a8 (KEY_COLOR), 2 |
intensity / distance |
3.45 ve 88 (sabit, sürgü yok) |
|
| Gölge | mapSize 1024; near 0.2 / far 96 |
|
| Dolgu | Ambient 0.12 + Hemisphere 0.36 (sol sahne; sağdan
daha yüksek dolgu) |
|
Sağ · SpotLight |
color / demo decay |
KEY_COLOR, 2.38 (SPOT_DECAY_DEMO —
menzil düşüşü demoda biraz abartılı) |
intensity |
4.25 × (sürgü 0–1) → ctor başlangıcı ~2.9, sonra
applyControls
|
|
angle |
HUD: 18°–68° → radyan; ctor varsayılan
degToRad(38)
|
|
penumbra / distance |
HUD 0–100 → 0–1, sonra parçalı eğri ile spot.penumbra (alt yarı ≈
0–0.2, üst yarı 0.2→1); ctor başlangıç 0.138 (≈ HUD %35). Mesafe
sürgüsü 8–72 |
|
| Gölge | mapSize 1024, bias, normalBias 0.028,
kamera near 0.35 / far 58 |
|
| Sağ dolgu | Ambient 0.065 + Hemisphere 0.28 (kontrast için sola
göre daha düşük) |
|
| Renderer | Ton / gölge | Exposure ≈1.22; PCFSoftShadowMap |
// --- A) Split demo — diagram-spot-light.js (sağ Spot özeti)
const KEY_COLOR = 0xffd4a8;
const LIGHT_POS = new THREE.Vector3(3.35, 5.05, 3.95);
const TARGET_POS = new THREE.Vector3(0, 0.62, 0);
const SPOT_INTENSITY_SCALE = 4.25;
const SPOT_DECAY_DEMO = 2.38;
const angle = THREE.MathUtils.degToRad(38);
const spot = new THREE.SpotLight(KEY_COLOR, 2.9, 38, angle, 0.138, SPOT_DECAY_DEMO);
spot.position.copy(LIGHT_POS);
spot.target.position.copy(TARGET_POS);
spot.castShadow = true;
spot.shadow.mapSize.set(1024, 1024);
scene.add(spot);
scene.add(spot.target);
// Demoda: intensity = SPOT_INTENSITY_SCALE * (sürgü 0–1); angle / distance HUD’dan;
// penumbra: HUD 0–1 parçalı eşlenir (Ctor’daki 0.35 yalnız başlangıç; canlı değer applyControls’ta).
// --- B) Genel tiyatral örnek (sayfa anlatımı)
const spotLight = new THREE.SpotLight(0xffffff, 2.0, 30, Math.PI / 6, 0.5, 2);
spotLight.position.set(5, 10, 5);
spotLight.target.position.set(0, 0, 0);
spotLight.castShadow = true;
spotLight.shadow.mapSize.set(1024, 1024);
scene.add(spotLight);
scene.add(spotLight.target); // Hedefi sahneye eklemeyi unutma!
API tarafında hatırlatma
new THREE.SpotLight(color, intensity, distance, angle, penumbra, decay) altı
parametreyi tek satırda toplar; target ayrı bir nesne olduğu için
scene.add(spot.target) adımı atlanmamalıdır. Gölge açıkken spot frustum’u
angle ve distance ile birlikte büyür — koni genişledikçe gölge
haritasında piksel başına düşen detay azalabilir; bu durumda önce açıyı daraltıp sonra
mapSize artırmak daha dengeli bir sıradır.
Yaygın hata: hedefi (target) unutmak
Yönü olmayan spot
Hata: SpotLight yönlü bir ışıktır. Yalnızca
position’ı değiştirip target’ı sahneye eklemezsen veya konumunu
güncellemezsen koninin baktığı yer beklediğinle örtüşmeyebilir.
Çözüm: scene.add(spotLight.target) ile hedefi her zaman
sahneye
ekle ve ışığın takip etmesi gereken noktayı orada tut (veya hedefi başka bir
Object3D’ye bağlayıp onu hareket ettir).
Bazı projelerde hedef kökte sabit kalırken spot position ile hareket eder; bazı
projelerde tersi yapılır — ikisi de geçerli, yeter ki matris güncellemesi
ve sahne grafiği tutarlı olsun. Hedefi unuttuğunda koni beklenmedik bir yöne bakabilir veya
frustum tamamen sahne dışına kayar; bu yüzden geliştirme aşamasında
SpotLightHelper veya demodaki tel kafes gibi görsel ipuçları zaman kazandırır.
Hedef hareket ediyorsa matris: target konumunu her kare
elle set ediyorsan veya grafik dışı özel bir akışta güncelliyorsan, ışığın dünya uzayındaki
yönü için spotLight.target.updateMatrixWorld() çağrısının güncel olduğundan
emin
ol — aksi halde spot, bir önceki kareden kalma matrixWorld ile yanlış eksene
bakabilir. Normal Object3D hiyerarşisi ve standart render döngüsünde çoğu
projede bu ekstra adım gerekmez; “hedef takip” kodunda ise sık karşılaşılır.
Holodepth ilkesi
Dikkat yönetimi aracı
SpotLight genel aydınlatma değil, odak aracıdır. Her yeri
aydınlatmak yerine izleyicinin görmesini istediğin kritik bölgeleri vurgula.
Holodepth çizgisinde spot, çoğu zaman DirectionalLight ile kurulan genel güneşin üstüne ince bir dram katmanıdır: vitrin, boss fight alanı veya tiyatro sahnesi gibi. Bir sonraki dosyada dikdörtgen alan ışığı ( RectAreaLight ) ile yumuşak stüdyo paneli düşüncesine geçilir — orada da yön ve alan kontrolü vardır fakat konik kesim yerine yüzey alanı baskındır.
Production notu: gölge frustum ve hata ayıklama
Gölge haritası üretimi açısından kabaca maliyet sıralaması (tipik kurulum, tek harita yönü başına):
| Işık | Gölge maliyeti (yaklaşık) |
|---|---|
DirectionalLight |
1 (tek yönlü harita) |
SpotLight |
1 (tek perspektif frustum) |
PointLight |
6 (küp harita — altı yüz) |
DirectionalLight’tan farklı olarak SpotLight gölgesi tipik olarak
perspektif bir kamera frustum’u ile üretilir. Gölgeler kesik veya eksik
görünüyorsa spotLight.shadow.camera alanını (ör. yakın/uzak düzlemler,
fov) ve harita çözünürlüğünü gözden geçir; çoğu kurulumda konu açısı
(angle) ile uyum tutulur.
Görsel hata ayıklama için SpotLightHelper kullan
(three/addons/helpers/SpotLightHelper.js): koniyi ve sınırları canlı görmek
saatler kazandırır.
Özet kutusundan sıradaki dosyaya geçerek alan ışığı kavramına devam edebilirsin; spot ile rect arasındaki seçim çoğu zaman konik odak mı, dikdörtgen yumuşak panel mi sorusuna indirgenir.