holodepth

Three.js · Işık · Dolgu

AmbientLight: her köşeye sızan dolgu ışığı

Karanlığı yok etmek değil; kontrol etmek. Sahneye ışık ekledin ama her şey hâlâ “ölü” mü görünüyor? En parlak ışıkların bile arkası neden kömür karası gölgelerle dolu? Gerçek dünyada ışık çarptığı yüzeylerden sekerek odanın en karanlık köşesini bile hafifçe aydınlatır. Three.js’te (gerçek zamanlı path tracing / tam dolaylı çözüm kullanmadığın sürece) ışık böyle sekmez: bir ışığın doğrudan vurmadığı yüzeyler, yalnızca diğer ışıklar ve materyal modelinle aydınlanır; aksi halde o bölgeler karanlıkta kalır.

AmbientLight, bu fiziksel eksikliği telafi etmek için her yöne eşit dağılan, kontrollü bir dolgu (fill) ışığı sunar — lamba değil, sahnenin taban parlaklığıdır.

Bağlam: MeshLambertMaterial (ışık–yüzey), Sahne (Scene), Işığın doğası, Materyal giriş.

Bu sayfa yalnızca “parlaklığı artır” seviyesinde değil; gerçek zamanlı render hattında ortam teriminin nereden geldiğini, nerede yanılttığını ve PBR / IBL / ton eşlemesiyle nasıl üst üste bindiğini okutmak için yazıldı.

Sahne, ışık ve materyal (hatırlatıcı)

Bileşen Teknik karşılık Bu sayfayla ilişki
Sahne THREE.Scene Işıklar ve mesh’ler aynı scene grafiğinde toplanır; AmbientLight de scene.add(...) ile eklenir — konumu sonucu değiştirmez.
Ortam dolgusu THREE.AmbientLight Yönsüz, gölgeli üretmez; difüz denklemindeki yönsüz ortam terimini güçlendirir (aşağıda Lambert / PBR bağlamı).
Materyal MeshStandardMaterial vb. Aynı intensity farklı yüzeylerde farklı “parlak” hissi verir; dolguyu materyalle birlikte ayarlamak gerekir.

Bu tablo sahneyi kurulum sırasından değil, çalışma anında neyin toplanacağı açısından hatırlatır: ışık düğümleri scene grafiğinde dolaşırken AmbientLight yön vektörü taşımaz; materyal tarafındaki aydınlanma denklemi, ortam katkısını diğer ışık terimlerinden ayrı satırlarda birleştirir. Dolayısıyla “ambient’i sahnenin soluna koyayım” gibi bir geometrik sezgi işe yaramaz; asıl oyun color × intensity ve ana ışıkla dengedir.

Zihin modeli

Lamba gibi değil — taban aydınlık

  • Kaynak: Yoktur (konum anlamsız; her yönden aynı anda “varmış” gibi).
  • Yön: Yoktur.
  • Gölge: Yoktur — gölge üretmez, mevcut gölgelerin içini açmaya yardım eder.
  • Amaç: Gölgelerin içindeki detayların tamamen kaybolmasını engellemek, sahneyi yıkamadan dengelemek.

Fiziksel model ve enerji korunumu

AmbientLight fiziksel olarak doğru bir ışık modeli değildir: gerçek dünyada “her yöne eşit, yönsüz bir photon yağmuru” diye ayrı bir kaynak yoktur; motor bunu hesap kolaylığı için yönsüz bir ortam terimi olarak ekler. Bu yüzden klasik anlamda energy conservation (enerjinin kaynaktan yüzeye tutarlı dağılımı) da beklenmez — abartıldığında sahne bilinçli olarak “fazla aydınlık” alır; PBR / IBL ile birlikte düşünürken bu fark kritik olur.

Birden fazla AmbientLight eklersen

Raster hatlarında her etkilenen yüzey, uygun materyal için ışık katkılarını toplar. İki ayrı AmbientLight örneğini scene.add(...) ile tutmak, çoğu zaman tek, daha güçlü bir dolgu hissi verir: her birinin color ve intensity bileşenleri ortam terimine eklenir. Yeni bir “parlaklık katmanı” açmak istiyorsan pratikte yeni düğüm açmak yerine mevcut örneğin değerlerini oynamak; aksi halde hangi düğümün ne kadar etki ettiğini takip etmek zorlaşır.

PBR materyalde “ambient” ne anlama gelir?

MeshStandardMaterial / MeshPhysicalMaterial tarafında roughness, metalness gibi fiziksel kelime dağarcığı kullanılır; AmbientLight ise motorun sunduğu basit bir yönsüz ortam katkısıdır — gerçek dünyadaki dolaylı aydınlanmayı bire bir kopyalamaz. Amacı, yönsel ışığın ulaşamadığı bölgeleri tamamen siyaha gömmek riskini azaltmaktır. Gökyüzü–yer renk ayrımı veya daha ikna edici ambiyans için sırada HemisphereLight ve gerektiğinde çevre / IBL konularına geçilir.

PBR + IBL çakışması: MeshStandardMaterial / MeshPhysicalMaterial ile çevre haritası / IBL açıldığında, zaten yansıma ve difüz için ortam aydınlanması üretilir. Üstüne güçlü bir AmbientLight koymak çoğu zaman çift dolgu (double lighting) yapar — enerji iki kez eklenmiş gibi okunur, albedo yıkanır. IBL kullanan sahnelerde ambient’i düşük tut veya kaldırıp eksikliği exposure / env gücü ile kapatmayı dene.

AmbientLight nasıl davranır?

  • Her yere eşit yayılır → Tüm etkilenen yüzeylere aynı türden ek parlaklık (materyale göre).
  • Konumdan bağımsızdır → Sahneye nereye eklersen ekleyin, sonuç aynıdır; yalnızca renk ve intensity önemlidir.
  • Sahneyi yumuşatır → Tek başına sert yönsel ışık kadar dramatik değildir; ana ışık + ambient birlikte okunur.

Teknik çekirdek: Lambert difüz terimine ek

“Her yere eşit” hissinin teknik karşılığı: çoğu lit materyalde yönsüz ortam katkısı, Lambert difüz çerçevesinde (veya PBR difüz dalında) yönsel ışınlarla ayrı toplanan terime eklenir — yani yüzey normalinden bağımsız, sabit bir taban parlaklık offset’i gibi düşünülebilir. Bu yüzden form okuması ve rim hatları, yönsel ışıktan gelir; ambient yalnızca tabanı kaldırır, yön üretmez.

API yüzeyi: color, intensity, visible

color (veya setRGB / setHSL) tonu, intensity ise bu tonun tüm yönlere eşit ölçek katsayısını belirler. visible = false, düğümü sahneden çıkarmadan ışığı devre dışı bırakmak için kullanılabilir — aynı kurulum üzerinden hızlı A/B veya LOD benzeri bir anahtar düşünülebilir. position / rotation alanları olsa da sonuçta ışın yönü üretilmediği için grafiğe nereye parent edildiğin yalnızca düzen ve kod okunabilirliği içindir.

color ve doğrusal uzay

Demoda çıkış SRGBColorSpace ile yönetilir; buna rağmen aydınlanma hesabı tarafında AmbientLight’ın color / intensity çifti doğrusal (linear) aydınlanma uzayında diğer ışık terimleriyle toplanır. Pratik sonuç: aynı hex tonu, toneMapping ve outputColorSpace seçimine göre ekranda farklı “doğal” hissedebilir; renk ayarını yaparken mümkünse referans görüntüleme hattını sabitle.

Ambient Occlusion (AO) ile ilişki

Düz ambient, yüzeylerin birbirini ne kadar “gölglediğini” bilmez. Ambient Occlusion ise tam da bu noktada devreye girer: ortam / difüz dolgunun yüzey üzerindeki dağılımını kıvrımlar ve temas bölgelerinde kısar — yani ambient ile AO birlikte çalışır; biri tabanı açar, diğeri o tabanın nerede zayıflayacağını söyler. Daha fazla için Ambient Occlusion dokusuna bak.

Hızlı kıyas: Ambient vs. diğerleri

Aşağıdaki tablo, “Bu form yön taşır mı?” ve “Gölge üretir mi?” sorularına hızlı cevap verir. Böylece dramayı yönsel ışıklarla kurup, dip aydınlığı ambient ile dengelemek — veya nokta / spot ile lokal vurgu eklemek — zihinsel modelde birbirine karışmaz.

Işık türü, yön, gölge ve tipik rol
Işık türü Yön Gölge Rol
AmbientLight Hayır Hayır Dolgu
DirectionalLight Evet Evet (üretir) Ana / güneş benzeri
HemisphereLight Kısmi (gökyüzü–yer) Hayır Doğal ambiyans, renk geçişi
PointLight Evet (kaynak noktadan) İsteğe bağlı Lamba ampulü, mesafeye göre sönüm
SpotLight Evet (koni) İsteğe bağlı Sahne okuma, odaklı vurgu
RectAreaLight Alan / yüzey normali Hayır (tipik) Panel / stüdyo yumuşak alan

MeshBasicMaterial gibi ışığı yok sayan yüzeyler ve RectAreaLight için özel materyal gereksinimleri ayrı sayfalarda ele alınır; ambient’in rolü yine taban dolgu olarak kalır — bu iki dünya birbirinin yerine geçmez, üst üste okunur.

İnteraktif: Before / After — aynı sahne, iki yarı

AmbientLight tek başına “vay” dedirtmez; karşılaştırınca etkisi netleşir. Sol yarı: yalnız DirectionalLight (gölgeler sert, gölgeli yüzeyler karanlıkta). Sağ yarı: aynı geometri + ayarlanabilir AmbientLight — gölge içlerinde detay yeniden okunur. Kamera sabit; tek yapı Ambient dışında öne çıkmıyor.

intensity rakamı mutlak bir “nit” ölçüsü değildir — aynı değer, renderer.toneMapping (ACESFilmicToneMapping vb.) ve toneMappingExposure ile ekranda tamamen farklı parlaklık ve sıkışma hissi verir; hatta aşırı ambient + agresif ton eşlemesi birlikte “yanmış kartpostal”a iter. İki yarıyı kıyaslarken bu ayarları sabit tut; üretimde de “rakam doğru mu?” sorusunu her zaman ton eşlemesi + exposure + env üçlüsüyle birlikte yanıtla.

Ölçüler ve sürgü–intensity zinciri demo sabitleri tablosunda diagram-ambient-light.js ile eşlenir; applyIntensity kesiti anlık okuma metnini üretir. İsteğe bağlı ses: aynı bölümde, demo kutusundan ayrı sütun genişliğinde şerit — dosya adı Ambient-Light-Demo (uzantı sırasıyla denenir).

Karşılaştırma aracı · Ambient vs yok

Sol: sadece DirectionalLight (biraz güçlendirilmiş intensity, position daha üst/ön-çapraz — gölge daha organik); PCFSoftShadowMap + shadow.radius ile hafif yumuşak kontakt. Işığın vurmadığı taraflar ve gölgeler içi siyahımsı. Sağ: aynı yönsel ışık + hafif soğuk tonlu AmbientLight (0x8899ff) — dolgu gölge içini açar, “atmosfer” hissi güçlenir. Slider’ı 0 yap: sağ da sol gibi yalnız directionalı gösterir; yükselt: kıyas büyür. Nesneler MeshStandardMaterial (metalness: 0, roughness: 0.4) — ışık geçişi biraz daha okunur; zemin rengi koyu tutuldu, sağda ambient etkisi sürgüye ×0.9 ile hafifçe sınırlanır (düz yıkanma azalır). Bu ekran “showcase” değil, karşılaştırma aracı.

Demo sabitleri tablosu (split sahne)

initAmbientSplitDemo · sol ve sağ için iki Scene, tek WebGLRenderer ve setScissor ile yarım genişlikte iki render; ortak buildGroup() ve makeDirectionalLight(), yalnız sağda AmbientLight.

initAmbientSplitDemo · Ambient split lab
Sahne / rol Parametre Değer Tür
Sabitler DIRECTIONAL_INTENSITY / AMBIENT_INTENSITY_SCALE 1.35 · 0.9 (sürgü 0–1 ile çarpılır) 🔒 Sabit
Renderer WebGLRenderer antialias: true · alpha: false · powerPreference: high-performance · setPixelRatio(min(dpr, 2)) · SRGBColorSpace · arka plan setClearColor(0x070a12) · PCFSoftShadowMap · ACESFilmicToneMapping · toneMappingExposure = 1.05 🔒 Sabit
Sol sahne sceneL background 0x070a12 · buildGroup() · makeDirectionalLight() · ambient yok 🔒 Sabit
Sağ sahne sceneR sol ile aynı + AmbientLight(0x8899ff, 0.3) başlangıç intensity (sürgü ile güncellenir) 🔒 + ↔ UI
Yönsel ışık makeDirectionalLight 0xffffff · intensity = DIRECTIONAL_INTENSITY · position (2, 6, 4) · gölge mapSize 2048 · radius 2 · bias -0.00015 · normalBias 0.02 · gölge kamerası d = 5.5, near 0.2 / far 28 🔒 Sabit
Geometri grubu buildGroup Zemin PlaneGeometry(9, 9) 0x1a2230 · küre r = 0.74 (0.15, 0.74, 0.55) 0x4ec9b0 · kutu 0.82³ (-1.05, 0.41, -0.35) rotation.y = 0.38 0xd4a056 · ortak MeshStandardMaterial metalness: 0 · roughness: 0.4 🔒 Sabit
Kamera PerspectiveCamera FOV 40 · yakın/uzak 0.12 / 80 · konum (0, 1.85, 7.2) · lookAt(0, 0.32, 0) 🔒 Sabit
Çift render setScissor / setViewport Genişlik ikiye bölünür; sol sceneL, sağ sceneR · cam.aspect her yarı için ayrı güncellenir 🔒 Sabit
HTML · sürgü input[type="range"] data-ambient-demo-intensity · min 0 · max 100 · step 1 · varsayılan value 30t = value / 100 🔒 + ↔ UI
Ambient güncelleme applyIntensity ambient.intensity = AMBIENT_INTENSITY_SCALE * clamp(t, 0, 1) · readout metni Türkçe özet ↔ UI

Önemli kod kesiti

Sürgü ham değeri 0–100 aralığından normalize edilir; çarpan AMBIENT_INTENSITY_SCALE sağ zemini aşırı yıkamayı azaltır. Okuma satırı kullanıcıya sol/sağ farkını tek cümlede hatırlatır.

function applyIntensity() {
  const t = intensityInput ? Number(intensityInput.value) / 100 : 0.3;
  ambient.intensity =
    AMBIENT_INTENSITY_SCALE * Math.max(0, Math.min(1, t));
  if (readout) {
    readout.textContent = `Sol: yalnız Directional (${DIRECTIONAL_INTENSITY.toFixed(2)}) · Sağ: + soğuk Ambient ${ambient.intensity.toFixed(2)} (0x8899ff) — gölge içi ${ambient.intensity < 0.05 ? "kapalı (≈sol)" : "açılıyor"}.`;
  }
}

Senaryo ve görsel gözlem

Gerçek sahne: Ambient genelde “fısıltı” seviyesindedir — karanlığı öldürmeden açmak için.

  • İç mekân: intensity çoğu zaman yaklaşık 0.3–0.5 aralığında başlar (sahne ve ana ışığa göre).
  • Dış mekân / aydınlık ortam: genelde 0.1–0.2 veya daha düşük; zaten güçlü ana ışık veya gökyüzü hissi vardır.
  • Sahne ölçeği: Birim = 1 m kabul edilen iç mekân ile kilometre ölçekli dış mekânda aynı rakam aynı psikolojik parlaklığı vermez; kamera mesafesi, zemin albedo’su ve ana ışığın intensity değeri ile birlikte değerlendirilir.

Önce ambient değil: ton ve çevre

Dip hâlâ çok karanlıksa bazen ambient’i tırmalamak yerine exposure veya varsa environment / IBL ile üst tona müdahale etmek, materyallerin birbirinden ayrışmasını korur. Ardından gölge dipleri hâlâ okunmuyorsa küçük bir ambient adımı daha kontrollü sonuç verir — ters sıra genelde “yıkanmış” bir ara görüntü üretir.

Modern hat: HDR çevre aydınlanması

Güncel PBR hatlarında “düz gri ambient” yerine çoğu ekip HDRI / environment map ile hem difüz hem speküler ortamı besler. Bu, hem yön hem renk spektrumu kazandırır; ayrıntılı bağlam için Environment & HDRI sayfasına geç.

Ambient yerine veya üstüne ne konur?

  • HemisphereLight: tek renk yerine gökyüzü– yer renk ayrımı; hâlâ gölgesiz ama daha doğal dip.
  • Environment haritası / IBL: yansımalar ve difüz dolgu birlikte; ambient’i sıfıra yaklaştırmayı sık görürsün.
  • Light probe: sahne içi difüz aydınlanmayı örnekleyip materyallere yayan kübemap / SH tabanlı çözümler (üretimde IBL’ye eşlik eder).

Görsel gözlem

Ambient’i artırdıkça gölgeler griye yaklaşır, kontrast düşer; fazla olursa sahne “yıkanır”, form ve derinlik kaybolur. Amaç dip karanlığı biraz kaldırmak, flat bir poster görüntüsüne dönmek değildir.

Ambient’i kaldırınca ne olur?

IBL veya kuvvetli yönsel dramada ambient’i düşürdüğünde veya kaldırdığında sahne çoğu zaman kontrastı artırır — gölgeler daha derin, vinyet ve ışık hacmi daha okunur hale gelir. “Gerçekçilik” öznel olsa da, çift dolguyu kestiğinde malzeme ayrımı ve derinlik sık sık iyileşir; bedeli, gölge diplerini başka bir yolla (hafif env, AO, çok zayıf dolgu) yönetmektir.

Uygulama

Aşağıdaki özet, üstteki Before / After demosu ile aynı çekirdeği anlatır (diagram-ambient-light.js). Tam sabit haritası ve applyIntensity için bölüm 4 altındaki demo sabitleri tablosuna bak. Buradaki tablo kısa ön harita; kod bloğu aynı değerlerle doldurulabilir. Sol yarı yalnız DirectionalLight, sağ yarı aynı yönsel ışık + soğuk AmbientLight (0x8899ff). Şiddet sürgüsü ×0.9 ile çarpılır. Genel projelerde renk tonunu color / setHSL ile ayrıca kurabilirsin.

Kurulum sırası (pratik iş akışı)

Ekipler çoğu zaman önce yönsel ana ışığı ve gölgeleri doğrular, ardından ambient’i adım adım ekler. “Önce her yeri yıkadım, sonra yönseli kurtarmaya çalıştım” döngüsü hem zaman kaybıdır hem de göz, yanlış referansa alışır.

diagram-ambient-light.js — Split Demo Sabitleri
Sahne / rol Parametre Değer
Ortak · geometri buildGroup Zemin 9×9, küre, kutu — MeshStandardMaterial roughness 0.4
Renderer ACESFilmicToneMapping, exposure ≈1.05; PCFSoftShadowMap
Sol · yalnız yönsel DirectionalLight 0xffffff, intensity 1.35 (DIRECTIONAL_INTENSITY), konum (2, 6, 4)
Gölge kutusu mapSize 2048, radius 2, d = 5.5, near 0.2 / far 28
Sağ · Ambient ekli DirectionalLight Sol ile aynı — directional.clone()
AmbientLight + HUD Renk 0x8899ff; intensity = 0.9 × (sürgü 0–1, AMBIENT_INTENSITY_SCALE)
// Interaktif demo (diagram-ambient-light.js — iki ayrı Scene)
// const sceneL = new THREE.Scene(); const sceneR = new THREE.Scene();
const DIRECTIONAL_INTENSITY = 1.35;
const directional = new THREE.DirectionalLight(0xffffff, DIRECTIONAL_INTENSITY);
directional.position.set(2, 6, 4);
directional.castShadow = true;
directional.shadow.mapSize.set(2048, 2048);
directional.shadow.radius = 2;
directional.shadow.bias = -0.00015;
directional.shadow.normalBias = 0.02;
const d = 5.5;
directional.shadow.camera.left = -d;
directional.shadow.camera.right = d;
directional.shadow.camera.top = d;
directional.shadow.camera.bottom = -d;
directional.shadow.camera.near = 0.2;
directional.shadow.camera.far = 28;

sceneL.add(directional);
sceneR.add(directional.clone());

const ambient = new THREE.AmbientLight(0x8899ff, 0.3);
sceneR.add(ambient);
// Demoda: ambient.intensity = 0.9 * (sürgü 0–1)

AmbientLight sahne başına en ucuz ışık türlerinden biridir: ekstra gölge haritası, frustum veya ışın sayısı üretmez; maliyeti çoğunlukla “birkaç uniform / toplama terimi” düzeyindedir. Bu, onu kötüye kullanma lisansı değildir — görsel kalite yine aşırı dolgu ile çöker; fakat performans gerekçesiyle “bir şey ekleyelim” dendiğinde doğru rafta durur.

Yine de sahne grafiğinden kaldırdığında (scene.remove veya üst grubun temizlenmesi) tutulan referansların (ör. GUI bağları) sıcak yeniden yüklemede birikmesini engellemek iyi pratik sayılır.

Yaygın hata: ışık patlaması

Directional + aşırı Ambient

Hata: Güçlü bir DirectionalLight ile birlikte ambient’i çok yüksek tutmak.

Sonuç: Sahne “yanmış”, düz ve kontrastsız görünür; gölge okuması zayıflar.

Holodepth ilkesi: Amaç karanlığı yok etmek değil, kontrol etmektir.

İkinci sık tuzak: Ürün veya arayüz görsellemesinde yalnızca güçlü ambient ile “stüdyo” yakalamaya çalışmak; özellikle MeshBasicMaterial veya aşırı yumuşatılmış PBR ile birleşince spekular okuması ve hacim ipuçları erir. Temel yönsel okuma korunmalı; ambient yine dip açma rolünde kalmalıdır.

Holodepth production içgörüsü

Düz ambient yetmezse

AmbientLight tek renkten gelen eşit dolgu olduğu için bazen fazla düz kalır. Daha doğal bir üst–alt veya gökyüzü–zemin renk ayrımı istiyorsan HemisphereLight (veya yönlü ışıklarla dengeli bir kurulum) genelde daha ikna edici bir ambiyans verir — gerçek dünyada ışık tek frekansta değildir. Üretim bütçesinde: düşük maliyetli dolgu gerekiyorsa ambient hâlâ geçerli; AAA görüntü hedefi varsa aynı rolü çoğu zaman IBL + AO + kontrollü yönsel ışıklar devralır (alternatif listesi).

Sergi, mobil oyun veya marka vitrininde sanat yönlendirmesi bilinçli olarak “poster”e yakınsa bile, izleyicinin takip ettiği rim veya specular dilimleri kaybolmadan düşünülmelidir; aksi halde ürün tanınabilirliği sessizce düşer.