holodepth

Three.js · Işık · Alan kaynağı

RectAreaLight: Profesyonel stüdyo paneli

Nokta değil yüzey — LED panel, softbox, pencere

Gerçek dünyada ışık kaynaklarının çoğu tek bir nokta değildir; belirli bir yüzey alanına sahiptirler. RectAreaLight, sahneye dikdörtgen şeklinde bir ışık yüzeyi ekler.

Bu ışık türü; nesnelerin üzerinde keskin parlama noktaları (specular highlights) yerine, o dikdörtgen panelin pürüzsüz yansımasını oluşturur. Profesyonel ürün çekimi veya modern iç mekân tasarımları için güçlü bir seçenektir.

Bağlam: SpotLight (konik odak), Materyal Giriş.

Zihin modeli: ışıklı yüzey

Fener değil — ışık yayan düzlem

  • Kaynak: İki boyutlu bir düzlemdir (genişlik × yükseklik).
  • Yayılım: Işık yalnızca ön yüzünden ileri doğru yayılır; arka yüz aydınlatma yapmaz.
  • Yönelim: Panelin yüzü objeye bakmalıdır; rotation veya lookAt kritik önemdedir.
  • Amaç: Stüdyo aydınlatması, TV ekranları, tavan panelleri, softbox hissi.

Tek taraflı yüzey

Panelin arka yüzü aydınlatma üretmez; bu, nokta veya spot sezgisiyle karıştığında “neden duvanın arkası aydınlanmıyor?” sorusunun cevabıdır. Işık hacmi, panel düzleminin normaline göre yarı uzayda düşünülür — yüzü çevirdiğinde tüm sahne ilişkisi değişir, sadece parlaklık değil.

Sahne ölçeği ve birim

width ve height doğrudan dünya birimlerindedir; aynı sayılar farklı projelerde “dev LED duvar” veya “masa üstü softbox” gibi tamamen farklı hisler verir. Split demoda sürgüler bu boyutu oynatırken zemindeki yansıma alanının genişleyip daraldığını izlemek, ölçeği zihinde sabitlemenin en hızlı yoludur.

Yönelim: emisyon yüzeyinin normali

Motor, paneli oriented dikdörtgen olarak ele alır; katkı, bu yüzeyin emisyon normaline (ışığın yerel çerçevesinde “ön yüz”e dik yön) göre hesaplanır — yani enerji, paneli sonsuz düzlem gibi düşünüp lookAt / rotation ile o normali dünya uzayına taşırsın. Bu yüzden rect’te “konum + yön” birlikte okunur; yalnızca position ile oynamak yetmez.

Kritik kurulum: LTC ve üniform kütüphane

RectAreaLight, Linearly Transformed Cosines (LTC) tabanlı hesaplamalar kullanır. Sahneye eklemeden önce üniform verilerin yüklenmesi gerekir; bunun için RectAreaLightUniformsLib kullanılır. İsteğe bağlı yerleşim göstergesi için RectAreaLightHelper eklenebilir (addon modülü — yerel önizlemede CORS için importmap veya bundler kullan).

LTC: yaklaşık alan ışığı

RectAreaLight fiziksel olarak tam bir alan kaynağı simülasyonu değildir; Three.js bunu Linearly Transformed Cosines (LTC) ile yaklaşık hesaplar. Sonuç çoğu vitrin senaryosunda ikna edicidir; fakat “motor içinde gerçek bir area light integral’i” beklentisi taşırsan sınırda kalırsın — özellikle çok büyük panel, uç açılar veya agresif roughness kombinasyonlarında fark hissedilir.

Çağrı sırası: önce init, sonra ışık

RectAreaLightUniformsLib.init() genelde renderer ve materyal pipeline’ı hazır olduktan sonra, ilk RectAreaLight sahneye eklenmeden önce bir kez çağrılır. Çoklu rect kullanımında da tek init yeterlidir; her yeni panel için tekrarlamak gerekmez. Eksik bırakıldığında sonuç “sessizce yanlış” olabilir — sahne siyah kalmadan da yansımalar beklenmedik şekilde düzleşir; bu yüzden Holodepth örneklerinde init satırını şablonun en üstüne koymayı alışkanlık edin.

Init atlanırsa ne olur?

Sürüm ve materyal kombinasyonuna bağlı olarak hata bazen konsolda belirginleşir, bazen yalnız görüntüde hissedilir. Şüpheye düştüğünde önce init’i doğrula, sonra panel yönünü (lookAt / rotasyon) kontrol et; çoğu “rect çalışmıyor” raporu aslında LTC üniformlarının hiç yüklenmemiş olmasından kaynaklanır.

PhysicallyCorrectLights ve birimler

Eski Three.js sürümlerinde renderer.physicallyCorrectLights = true, RectAreaLight ile birlikte şiddet / alan ilişkisinin daha tutarlı okunmasına yardım eder — düz “slider oyunu”ndan çıkıp PBR birimleriyle hizalanırsın. Güncel sürümlerde bu bayrak kaldırılmış / varsayılanlarla birleşmiş olabilir; projende WebGLRenderer ve ışık birimleri için resmi migration notlarına bak.

import { RectAreaLightUniformsLib } from "three/addons/lights/RectAreaLightUniformsLib.js";
    import { RectAreaLightHelper } from "three/addons/helpers/RectAreaLightHelper.js";

    // Renderer / sahne kurulumundan sonra, RectArea eklemeden önce bir kez:
    RectAreaLightUniformsLib.init();

Split önizleme: Spot vs RectArea

Aynı zemin ve objeler: solda yalnızca SpotLight (gölge + konik speküler), sağda yalnızca RectAreaLight — metal zeminde yansıma biçimini yan yana görmek için. Canlı kod: diagram-rect-area-light.js; panel çerçevesi LineSegments (addon helper yok). Aşağıda yaw/pitch ile panel yönünü oynat: yüzü sahneyi terk edince yansımanın nasıl söndüğünü görürsün.

Sol taraftaki SpotLight referansı, aynı geometride konik speküler + gölge okumasını verir; sağdaki rect ise özellikle metal zeminde dikdörtgen leke ve yumuşak kenar davranışını gösterir. “Chrome küre” kutusu yalnızca materyal parametrelerini değiştirir — ışık türü aynı kalır; böylece LTC yansımasının metal yüzeyde nasıl sıkıştığını hızlıca A/B yaparsın.

İsteğe bağlı ses: aynı bölümde, demo kutusundan ayrı sütun genişliğinde şerit — dosya adı Rect-Area-Light-Demo (uzantı sırasıyla denenir).

Karşılaştırma · Spot (sol) vs RectArea (sağ ayarlar)

Sol: tek odaklı konik ışık — küre ve kutuda parlak nokta, zeminde keskin gölge. Sağ: panel lookAt + yerel yaw/pitch ile yön değişir; yüzü sahneyi kaçırınca yansıma kaybolur. Genişlik/yükseklik speküler alanın boyutunu belirler. Çekirdekte RectAreaLight gölge üretmez.

Demo sabitleri tablosu (split sahne)

initRectSplitDemo · sol ve sağ için iki Scene, tek WebGLRenderer ve setScissor ile yarım genişlikte iki render; ortak buildStage(), solda SpotLight + hedef, sağda RectAreaLight. RectAreaLightUniformsLib.init() renderer kurulduktan hemen sonra, sahne ve rect oluşturulmadan önce çağrılır.

initRectSplitDemo · Rect split lab
Sahne / rol Parametre Değer Tür
Sabitler RECT_POS / RECT_AIM (-0.65, 3.95, 3.55) · (0, 0.32, 0) 🔒 Sabit
LTC RectAreaLightUniformsLib.init makeRenderer sonrası, Scene / rect öncesi bir kez 🔒 Sabit
Renderer WebGLRenderer antialias: true · alpha: false · setPixelRatio(min(dpr, 2)) · SRGBColorSpace · arka plan 0x070a12 · PCFSoftShadowMap · ACESFilmicToneMapping · taban toneMappingExposure = 1.12 (sağ yarı render’da geçici 1.18) 🔒 Sabit
Sol sahne sceneL buildStage() · addFill(..., "L") · makeSpotKey() + spot.target sahneye ekli 🔒 Sabit
Sağ sahne sceneR buildStage({ floorEmissiveBoost: 0.11 }) · addFill(..., "R") · RectAreaLight + mint LineSegments çerçevesi 🔒 Sabit
Spot (sol) makeSpotKey 0xfff0e8 · intensity 96 · distance 26 · angle π/8.2 · penumbra 0.26 · decay 2 · konum (2.85, 5.15, 2.35) · hedef (0, 0.22, 0) · gölge mapSize 1024 · near 0.35 / far 40 🔒 Sabit
Rect (sağ) · ctor new RectAreaLight(...) 0xfff2e8 · intensity 38 · width 3.5 · height 2.2 — HUD ile applyControls içinde güncellenir 🔒 + ↔ UI
Geometri buildStage Zemin 14×14 metalimsi (0x1f2a40, yüksek metalness) · küre r 0.52 sol-ön · kutu 0.68³ sağ-arka; sağda zemin emissiveIntensity +0.11 🔒 Sabit
Dolgu addFill Sol: Ambient 0.07 · Hemisphere 0.24 — Sağ: Ambient 0.095 · Hemisphere 0.3 🔒 Sabit
Kamera PerspectiveCamera FOV 38 · near / far 0.1 / 90 · konum (0.05, 2.25, 8.45) · lookAt(0, 0.28, 0) 🔒 Sabit
Çift render setScissor / setViewport Genişlik ikiye bölünür; sol sceneL, sağ sceneR · her yarı için cam.aspect ayrı güncellenir 🔒 Sabit
HTML · sürgüler data-rect-demo-* width 80–900 → value/100 → clamp 0.8–9 · height 60–700 → clamp 0.6–7 · intensity 0–100 → t ile lerp(14, 92, t) · yaw −58…58 · pitch −42…42 🔒 + ↔ UI
Checkbox tel / chrome data-rect-demo-wire-toggle (mint çerçeve) · data-rect-demo-chrome-sphere (küre metal/roughness) ↔ UI
Güncelleme applyControls rect.width / height / intensity · applyRectOrientation(yaw, pitch) · tel geometrisi · readout Türkçe özet ↔ UI

Önemli kod kesiti

Genişlik/yükseklik sürgüleri ham değeri 100’e bölünerek dünya birimine çevrilir ve güvenli aralıkta sıkıştırılır; şiddet sürgüsü 0–1 normalize edilip lerp(14, 92, …) ile rect intensity’ye gider. Okuma satırı sol/sağ farkını ve panel durumunu tek blokta özetler.

function applyControls() {
    const wRaw = wInput ? Number(wInput.value) / 100 : 3.5;
    const hRaw = hInput ? Number(hInput.value) / 100 : 2.2;
    const w = THREE.MathUtils.clamp(wRaw, 0.8, 9);
    const h = THREE.MathUtils.clamp(hRaw, 0.6, 7);

    const t = intInput ? Number(intInput.value) / 100 : 0.65;
    const inten = Math.max(0, Math.min(1, t));
    rect.width = w;
    rect.height = h;
    rect.intensity = THREE.MathUtils.lerp(14, 92, inten);

    const yawDeg = yawInput ? Number(yawInput.value) : 0;
    const pitchDeg = pitchInput ? Number(pitchInput.value) : 0;
    applyRectOrientation(rect, yawDeg, pitchDeg);

    const showWire = !!(wireToggle && wireToggle.checked);
    wireState.line.visible = showWire;
    updateRectWireframe(wireState, w, h);

    applySphereChrome();

    if (readout) {
        readout.textContent =
        `Sol: Spot + gölge. Sağ: RectArea ${rect.width.toFixed(2)}×${rect.height.toFixed(2)} · I ${rect.intensity.toFixed(0)} · yaw ${yawDeg.toFixed(0)}° pitch ${pitchDeg.toFixed(0)}°. ` +
        `${showWire ? "Mint: panel çerçevesi." : "Çerçeve kapalı."} ` +
        `${chromeToggle?.checked ? "Küre: yüksek metal (speküler odak)." : "Küre: varsayılan PBR."}`;
    }
    }

Split ekranı nasıl okumalısın?

Genişlik ve yükseklik sürgüleri panel alanını büyütür; metal zemindeki parlak dikdörtgenin fiziksel boyutu buna bağlıdır. yaw / pitch ise panelin yüzünü sahneye göre döndürür — yüzü tamamen uzaklaştırdığında yansıma kaybolması beklenen davranıştır. Mint çerçeve yalnızca öğretim çizgisidir; üretimde RectAreaLightHelper veya kendi debug katmanınla aynı fikri sürdürebilirsin.

Karşılaştırma: SpotLight ve RectAreaLight

Aşağıdaki tablo “hangi türde odak ve gölge istersin?” sorusuna kısa cevap verir. Spot, yönsel dram ve gölge haritası için uygundur; rect ise yüzey alanından gelen yumuşak yansıma ve stüdyo estetiği için uygundur. İkisini aynı sahnede üst üste kullanmak yaygındır — biri kontakt gölgeyi taşır, diğeri ürün üzerindeki panel yansımasını taşır.

Özet farklar
Özellik SpotLight RectAreaLight
Işık formu Konik Dikdörtgen düzlem
Yansıma (specular) Parlak nokta Parlak dikdörtgen (yumuşak alan)
Gölge desteği Var (castShadow) Yok (çekirdekte varsayılan shadow map üretimi yok)
Materyal uyumu Standart PBR dışı pek çok materyal MeshStandardMaterial ve MeshPhysicalMaterial ile tam uyum

Uygulama: modern stüdyo aydınlatması

RectAreaLight için intensity diğer ışıklara göre farklı algılanabilir; genelde daha yüksek değerler (ör. 5.0 ve üzeri) kullanılır. Önce bölüm 2’deki RectAreaLightUniformsLib.init() çağrısını unutma; bölüm 3’teki split sahne (diagram-rect-area-light.js) aynı sırayı izler. Tam sabit haritası ve applyControls için bölüm 3 altındaki demo sabitleri tablosuna bak; buradaki tablo kısa ön haritadır.

Split örneğindeki sıra özellikle önemlidir: önce sahne ve PBR materyaller, ardından RectAreaLightUniformsLib.init(), sonra rect oluşturma ve yönlendirme. Kendi kodunda bu sırayı bozmak, init’in “bir kare gecikmeli” çalışması gibi zor ayıklanan hatalara yol açabilir.

Split demo: ön harita tablosu

Aşağıdaki satırlar üstteki interaktif split ile aynı çekirdeği özetler; ayrıntılı satırlar lab tablosunda.

diagram-rect-area-light.js — Split Demo Sabitleri
Sahne / rol Parametre Değer
Ortak RECT_POS / RECT_AIM (-0.65, 3.95, 3.55) · (0, 0.32, 0) — panel lookAt tabanı
LTC / renderer RectAreaLightUniformsLib.init() zorunlu · ACESFilmicToneMapping, taban exposure 1.12 (sağ pass 1.18)
Sol · SpotLight Işık 0xfff0e8, intensity 96, gölge mapSize 1024
Dolgu Ambient 0.07 + Hemisphere 0.24
Sağ · RectAreaLight Başlangıç ctor 0xfff2e8, intensity 38, 3.5×2.2 — HUD ile güncellenir
Şiddet sürgüsü intensity = lerp(14, 92, t), t = sürgü 0–1

Alan ve intensity: aynı rakam, farklı his

RectAreaLight’ta şiddet, sezgisel olarak panel alanıyla birlikte okunur: aynı intensity değeri, geniş bir duvarda enerjiyi daha geniş bir emisyon yüzeyine yaydığı için daha yumuşak / daha az “noktasal” hissedilir; küçük bir softbox’ta ise aynı rakam daha sıkı ve parlak görünür. Pratikte “önce alanı gerçekçi kur, sonra intensity’yi ton eşlemesiyle birlikte ince ayarla” sırası daha az sürprizlidir.

API tarafında hatırlatma

RectAreaLight(color, intensity, width, height) dört parametreyle kurulur; yön için lookAt veya rotation kullanılır — konum ile normal aynı anda tutarlı olmalıdır. intensity ölçeği diğer ışık türlerinden farklı hissedilebilir; bu yüzden ton eşlemesi ve kamera exposure ile birlikte ayarlamak genelde daha doğal sonuç verir.

IBL / çevre ile birlikte

Üretimde RectAreaLight çoğu zaman environment map / IBL ile aynı hatta bulunur: IBL genel difüz–speküler ortamı taşır; rect ise vitrin veya ürün üzerinde yönlü stüdyo paneli imzasını ekler. Bağlam için Environment & HDRI sayfasına bak.

// Genel API örneği (split demodaki sabitler: bölüm 3 lab + bölüm 5 ön harita)
    // 1. Işığı oluştur (renk, şiddet, genişlik, yükseklik)
    const areaLight = new THREE.RectAreaLight(0xffffff, 5.0, 4, 2);

    // 2. Konumlandır ve bakış yönünü belirle
    areaLight.position.set(0, 5, 0);
    areaLight.lookAt(0, 0, 0); // Paneli merkeze çevirir

    scene.add(areaLight);

    // 3. Görselleştirici (helper, isteğe bağlı)
    const helper = new RectAreaLightHelper(areaLight);
    scene.add(helper);

Görsel gözlem: sahneyi nasıl etkiler?

  • Yumuşak geçiş: Işık geniş bir yüzeyden geldiği için aydınlık alanlar ile gölgeler arasındaki geçiş genelde daha doğal okunur.
  • Gerçek dünya karşılığı: Araba kaportası veya cam yüzeyde stüdyo panelinin (softbox) yansımasını net bir şerit olarak görürsün.
  • Hacimsel dolgu: Odayı tek ampul gibi “patlatmadan”, dengeli ve kontrollü doldurur.

Neden çoğu zaman Standard / Physical?

LTC tabanlı hesaplama, modern PBR shader yolunda en iyi sonuç verir. Eski MeshLambertMaterial gibi modeller rect alan yansımasını aynı denklemden okuyamaz; bu yüzden “rect ekledim ama yüzey düz” hissi çoğu zaman yanlış materyal seçimidir. Ürün vitrininde önce materyali doğrula, sonra panel boyutunu oyna.

Difüz ve speküler katkı

LTC yolu yalnızca “aynalı şerit” üretmez: difüz aydınlanmaya da katkı verir. Yine de rect’in sahneye “kendini fark ettirme” biçimi çoğu kurulumda özellikle speküler bileşende belirginleşir — geniş, yumuşak panel yansıması, metal veya düşük roughness yüzeylerde en net okunur; mat yüzeylerde fark daha sakin kalabilir.

Yaygın hata: gölge beklemek

RectArea’dan doğrudan shadow map yok

Hata: RectAreaLight, Three.js çekirdeğinde gölge haritası üretmez; nesnenin altına keskin kontakt gölge beklemek hayal kırıklığı yaratır.

Çözüm: Gölge ihtiyacı varsa yardımcı bir SpotLight veya DirectionalLight ile destekle; veya ışığı / AO’yu doku veya “baking” ile önceden pişir.

Bazı ekipler rect’i “tek başına ana güneş” gibi kullanıp gölge bekler; üretimde daha sağlıklı desen, DirectionalLight veya SpotLight ile kontakt ve forma ait gölgeleri taşıyıp rect’i yansıma ve dolgu estetiğine ayırmaktır. Ortam haritası (IBL) ile birlikte kullanıldığında da rect genelde ince bir “stüdyo katmanı” olarak kalır.

Gölge olmadan “hacim” hissi: IBL / zayıf yönsel ışık dışında, kontakt okumayı sahte gölge (zeminde yumuşak blob / leke imitasyonu), AO (doku veya ekran uzayı), veya bake edilmiş aydınlanma ile destekleyen ekipler çoktur — rect’ten beklenen şey “harita üreten lamba” değil, panel estetiğidir.

Holodepth ilkesi

Estetik imza

RectAreaLight yalnızca genel aydınlatma aracı değil; lüks, steril ve modern bir atmosfer için güçlü bir estetik imzadır. Her sahneye zorla ekleme — ürün ve iç mekân vitrinlerinde en çok parlar.

Holodepth çizgisinde rect, “fiziksel doğruluk tek başına” değil, izleyiciye kalite sözü veren bir ışık türüdür: doğru materyal, doğru ton ve doğru panel yönü bir aradayken sahne anında “ürün fotoğrafı” diline geçer. Bir sonraki büyük blokta gölge kavramına geçeceksen, rect’in gölge taşımadığını zihninde taşı: Gölge girişi rehberi bu boşluğu doldurmanın haritasıdır.

Production notu: materyal kısıtı

Bu ışık türü yalnızca MeshStandardMaterial ve MeshPhysicalMaterial ile tam uyumludur. MeshLambertMaterial, MeshPhongMaterial gibi eski modeller alan yansımasını bu modelle hesaplayamaz. Profesyonel sonuç için PBR materyal kullanmayı unutma.

Performans tarafında her RectAreaLight, PBR yolunda LTC tabanlı ek shader maliyeti taşır; çoğu kurulumda bu, basit bir PointLight’ın yalnızca “tek ışın / nokta” toplamasından daha pahalıdır (özellikle çoklu geniş panel + yüksek çözünürlük). Birden fazla geniş rect mobilde hızla pahalılaşır; LOD veya tek dominant panel + zayıf dolgu / IBL kombinasyonu sık görülür. Özet kutusundan sıradaki konuya geçerek gölge haritası düşüncesine devam edebilirsin.