holodepth

Three.js · Işık · Ambiyans

HemisphereLight: Gök kubbesinin doğal ışığı

Işık sadece güneşten değil; gök ve yerden de “okunur”

Dışarı çıktığında ışığın yalnızca güneşten gelmediğini fark ettin mi? Gökyüzünün maviliği yukarıdan çökerken, çimenin yeşili veya toprağın rengi aşağıdan yüzeylere yansır. HemisphereLight, bu iki yönlü etkiyi taklit eden, gölge üretmeyen ama sahneye yumuşak, gradyanlı bir dolgu ışığıdır — nesnenin üstü ile altı arasında doğal bir renk ayrımı kurar.

Bağlam: AmbientLight (tek renk dolgu), MeshStandardMaterial, Materyal Giriş.

Zihin modeli

Dev bir renk küresi

  • Sky color (gök rengi): Yukarıdan gelen, üst yüzeylere baskın olan ton.
  • Ground color (yer rengi): Aşağıdan “yükselen”, alt bölgelere baskın olan ton.
  • Eksen: Varsayılan “yukarı” yönü Vector3(0, 1, 0) — dünya y ekseni ile hizalı düşünülür.
  • Amaç: Üst–alt arasında doğal kontrast; derinlik ve “yerde durma” hissi.

Gök yönü: varsayılan eksen ve “yukarı”

Gerçek dünyada gökyüzü genelde başının üstünde, yer ise ayak altında okunur; beyin de bu dikey ekseni hızlıca “mekânın yukarısı” olarak eşler. Three.js’te HemisphereLight için bu varsayılan, dünya uzayında Vector3(0, 1, 0) yönüdür — yani gök rengi, yüzey normali bu “yukarı” vektörüne yaklaştıkça baskınlaşır; yer rengi ise normal aşağıya döndükçe güçlenir.

Işık düğümünü Object3D hiyerarşisinde döndürerek (veya parent’ının dönüşünü kullanarak) bu ekseni sahneye göre kaydırabilirsin; böylece “gök” bir mimari sahneye göre eğik bir kubbe gibi davranır. Konum (position) parlaklığı değiştirmez — bu ışık türü mesafe veya “nereden geliyor” sorusunu yönsel ana ışık kadar sert taşımaz; asıl mesaj üst–alt renk dengesidir.

Fiziksel tam karşılığı değil; görsel kısaltma

Gerçek zamanlı raster hatlarında tam gökyüzü saçılımı ve zeminden sekme (bounce) ayrı ayrı hesaplanmadığında, HemisphereLight pratik bir tek geçişlik kısaltmadır: “yukarıdan soğuk / aşağıdan sıcak veya koyu” hissini birkaç renkle verir. Bu yüzden IBL veya ışın izleme ile kıyaslandığında fiziksel doğruluk iddiası taşımaz; ama ürün vitrinleri, oyun içi dış mekânlar ve web tabanlı mimari önizlemelerde sıkça yeterli ve ucuz bir taban oluşturur.

Hemisphere ≠ IBL: HemisphereLight, çevre haritası veya image-based lighting ile gelen gerçek yansıma / dolaylı aydınlanma katmanının yerini tutmaz; yalnızca üst–alt renk ayrımıyla ucuz bir dolgu sunar. İkna edici metal yansıması veya iç mekân bounce için sıradaki adım genelde çevre + PBR tarafıdır.

HemisphereLight nasıl davranır?

  • Çift renk: Tek sabit renk yerine, yüzey normaline göre gök / yer rengi harmanlanır.
  • Doğal kontrast: Örneğin karakterin ayak altı yer tonunu, baş üstü gök tonunu taşır.
  • Hafif maliyet: Hesaplaması basittir; çoğu sahne için görsel getirisi yüksektir.
  • Gölge yok: Fiziksel bir lamba değildir; AmbientLight gibi ambiyans dolgusudur.

Shader sezgisi: normal ve iki renk

Lambert benzeri veya PBR materyallerde yönsel terimler yüzey normali N ile ışık yönü arasındaki ilişkiye bakar. HemisphereLight katkısı ise kabaca şu fikre indirgenir: “normal yukarıdaysa gök rengine yaklaş, aşağıdaysa yer rengine yaklaş” — arada yumuşak bir harman vardır. Bu, aynı renk tonunun her yüzeye eşit basıldığı AmbientLight’tan farklı olarak, eğimli yüzeylerde hafif bir form okuması verir; özellikle tavan–taban ayrımı olan iç mekânlarda veya karakter omuz–bacak siluetlerinde fark edilir.

Aynı fikir, kabaca tek satırlık bir mix ile de okunur (up birim “yukarı” vektörü, normal yüzey normali; gerçek Three.js shader’ında terimler ve ölçekler motor sürümüne göre ayrıntılanır):

float h = dot(normal, up);
vec3 color = mix(groundColor, skyColor, h * 0.5 + 0.5);

Gök ve yer renklerini seçerken tone mapping ve color space (linear çalışma alanı vs. ekrana giden sRGB görüntü) ile birlikte değerlendir: aynı hex, farklı outputColorSpace / gamma zincirinde farklı doygunluk verebilir.

Diğer ışıklarla toplanma

Sahne grafiğinde birden fazla ışık düğümü varken, etkilenen her fragment için uygun materyal modeli katkıları toplar. HemisphereLight genelde “taban ambiyans” rolünde tutulur; ana kontrastı DirectionalLight veya SpotLight verir, nokta ışıklar lokal sıcaklık ekler. Dolguyu tek başına şişirmek yerine, önce yönsel ışığın yönünü ve gölge dengesini kurup ardından intensity ile hemisferi ince ayarlamak daha kontrollü bir iş akışıdır.

Birden fazla HemisphereLight genelde gereksizdir: her biri ortam terimine eklenir; iki–üç kopya kolayca sahneyi yıkar / pastel yıkama yapar. Tek örnek üzerinden gök–yer çiftini ve intensity’yi oynamak neredeyse her zaman daha temiz bir tabandır.

Hızlı kıyas: Ambient vs. Hemisphere

“Dolgu ışığı ekleyeyim” dediğinde iki yol sık karşına çıkar: her yöne eşit ton basan AmbientLight ve üst–alt ayrımı taşıyan HemisphereLight. Tablo, ikisinin yön duyarlılığı ve renk modeli açısından hızlı bir seçim çerçevesi sunar. Teknik olarak ikisi de gölge üretmez; fark, görsel okunabilirlik ve “dünyanın hangi renklerle çevrildiği” mesajıdır.

Pratik kural: sahne “karton gibi” düzleşiyorsa ve zeminin rengi önemliyse önce HemisphereLight dene; yalnızca gölgelerin içini çok hafif açmak istiyorsan ve renk ayrımı istemiyorsan AmbientLight daha az parametreyle iş görür. İkisini aynı anda yüksek şiddetle üst üste bindirmek kolayca pastel / yıkanmış bir görüntü üretir — toplam dolgu gücünü materyal roughness değerleriyle birlikte düşün.

AmbientLight ve HemisphereLight
Özellik AmbientLight HemisphereLight
Renk sayısı 1 (tek ton) 2 (gök + yer, dinamik harman)
Hacim hissi Daha düz Daha güçlü (üst/alt ayrımı)
Yön duyarlılığı Yok Var (yukarı/aşağı ayrımı)
Tipik kullanım Teknik dolgu Doğal atmosfer, dış/orta mekân

İnteraktif: tek renk dolgu vs. gök + yer

Aynı DirectionalLight ve tek eğik kapsül (hafif zemine gömülü) ile: sol yarıda düşük AmbientLight (düz dolgu), sağ yarıda HemisphereLight (gök + yer). İlk sürgü gök/yer renk ayrımını (kontrast), ikinci sürgü sağdaki dolgu gücünü ayarlar (×0.9 ölçek). İstersen sağda “Ambient kullan” ile aynı geometride düz dolguya geçip farkı net gör.

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

Karşılaştırma · Ambient vs Hemisphere

Sol: AmbientLight — gölge bölgeler tek tonda; hacim düzlaşır. Sağ: HemisphereLight — üst yüzey gök (mavi), alt yüzey yer (kahve) tonuna yaklaşır; eğik kapsül ve hafif gömülü alt ile fark belirgin. Kontrast sürgüsü iki rengi ortaya doğru çekerek etkiyi azaltır. Checkbox ile sağda yine düz Ambient görüp karşılaştırabilirsin. MeshStandardMaterial, PCFSoftShadowMap; zemin rengi yere yakın tutuldu.

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

Sol yarı, aynı yönsel ışık altında düz tek ton dolgu ile gölge içlerinin nasıl “düzleştiğini” gösterir; sağ yarı ise aynı geometride gök ve yer renklerinin üst–alt yüzeylere nasıl dağıldığını gösterir. Kontrast sürgüsü, iki kutbu ortaya doğru çekerek etkiyi zayıflatır — aşırı dramayı kesmek için iyi bir güvenlik valfidir. Checkbox ile sağda yine düz dolguya dönüp A/B yapmak, “ben gerçekten hemisfer mi istiyorum?” sorusuna net cevap verir.

Gerçek sahne ve görsel gözlem

Orman / dış mekân: Gök rengini açık mavi, yer rengini koyu yeşile çek; ağaç altında bile zeminin yeşil yansıması üst tonla birleşir. Stüdyo / ürün: Gök beyaza yakın, yer hafif gri — ürün daha “premium” ve hacimli okunur.

Kural: Zeminin olduğu bir dünyada genelde AmbientLight yerine HemisphereLight ile başlamak daha doğal bir taban verir (ana ışık yine DirectionalLight veya spot ile gelir).

İç mekân / mimari: Tavan açıkça “üst” olduğunda gök rengini tavana yakın nötr veya hafif soğuk tutup, yer rengine parke veya halı tonunu vermek mekânı hızlıca tanımlar. Bu, gerçek GI yokken odanın hacim okumasını güçlendirir.

Karakter ve prop: Yüzey normali kollar, omuzlar ve bacaklarda farklı açılar aldığı için hemisfer, tek renk ambient’a göre daha az “oyuncak plastik” hissini azaltır. Tersine, stilize cel shading veya düz toon görünüm istiyorsan bilinçli olarak zayıf hemisfer + güçlü yönsel rim ışığı kombinasyonu da tercih edilebilir.

Performans ve mobil: Ekstra doku veya çevre haritası taşımadan ambiyans kazanmak isteyen hafif sahnelerde HemisphereLight sıkça yeterlidir; ağır çözümlere (IBL, çoklu ışın haritası) geçmeden önce bu tabanın doygunluğunu ve toneMapping ile uyumunu kontrol et.

Görsel gözlem

Nesneyi döndürdükçe üst yüzeyler gök tonuna, alt yüzeyler yer tonuna yaklaşır; arada keskin çizgi yoktur — eğime göre yumuşak geçiş. Yer rengi, nesnenin altına hafif “temas” rengi vererek zemine bağlar.

Uygulama

Aşağıdaki blok, üstteki split demosu ile aynı sabitleri ve mantığı verir ( diagram-hemisphere-light.js). Önce tablo ön harita; kod satırlarıyla bire bir eşleştirilebilir. Sol yarı AmbientLight (0.26) + düşük yönsel ışık; sağ yarı HemisphereLight (gök/yer + kontrast sürgüsü) ve isteğe bağlı sağ Ambient toggle. Yönsel şiddet demoda ×0.7 (DIRECTIONAL_INTENSITY).

Kendi projen için kopyalarken tablodaki sayıları “kutsal” saymak zorunda değilsin; burada amaç, HUD sürgüleri ile kod sabitleri arasında köprü kurmaktır. Örneğin yönsel ışığı güçlendirdiğinde hemisferi biraz kısarak kontrastı koruyabilir veya gök/yer hex değerlerini marka paletine çekerek aynı matematikle farklı dünya hissi üretebilirsin.

Ön harita tablosunu nasıl kullanırsın?

Tablo satırları, split demodaki sol sahne ve sağ sahne ayrımını izler: ortak geometri ve renderer ayarları üstte, sol ve sağa özgü ışık düğümleri altta gruplanır. Checkbox açıkken sağ tarafta HemisphereLight kapatılıp yerine yaklaşık parlaklık eşlemesi için başka bir AmbientLight devreye girer — bu, “aynı geometride düz dolgu” karşılaştırmasının kod tarafındaki karşılığıdır.

diagram-hemisphere-light.js — Split Demo Sabitleri
Sahne / rol Parametre Değer
Ortak · geometri buildGroup Zemin 9×9 (PLANE_HEX 0x403630), eğik kapsül (MESH_NEUTRAL)
Renderer ACESFilmicToneMapping, exposure ≈1.05; PCFSoftShadowMap
Sol DirectionalLight 0xffffff, 1.35 × 0.7, konum (2, 6, 4), gölge kutusu d = 5.5, mapSize 2048
AmbientLight 0xf2f5ff · 0.26
Sağ DirectionalLight Sol ile aynı — directional.clone()
HemisphereLight · renkler Gök 0x87ceeb, yer 0x5a4635; kontrast sürgüsü 0–100hemi.color / groundColor (_cMid lerp)
HemisphereLight · şiddet Normalde intensity = 0.9 × şiddet sürgüsü (HEMI_INTENSITY_SCALE); checkbox ile Hemisphere kapatılıp sağ Ambient 0xeef2ff · 0.88 × sürgü (AMBIENT_RIGHT_SCALE)
Başlangıç hemi.intensity Kodda ctor 0.55; ilk applyAll ile sürgü değerine göre güncellenir
// Interaktif demo özeti (diagram-hemisphere-light.js — iki ayrı Scene)
// const sceneL = new THREE.Scene(); const sceneR = new THREE.Scene();
const DIRECTIONAL_INTENSITY = 1.35 * 0.7;

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);
sceneL.add(new THREE.AmbientLight(0xf2f5ff, 0.26));

const SKY_HEX = 0x87ceeb;
const GROUND_HEX = 0x5a4635;
const _cSky = new THREE.Color(SKY_HEX);
const _cGround = new THREE.Color(GROUND_HEX);
const _cMid = new THREE.Color().lerpColors(_cSky, _cGround, 0.5);

const hemi = new THREE.HemisphereLight(SKY_HEX, GROUND_HEX, 0.55);
const k = 0.9; // kontrast sürgüsü (0 = düz, 1 = tam gök/yer)
hemi.color.copy(_cSky.clone().lerp(_cMid, 1 - k));
hemi.groundColor.copy(_cGround.clone().lerp(_cMid, 1 - k));

sceneR.add(directional.clone());
sceneR.add(hemi);
// Demoda: hemi.intensity = 0.9 * (şiddet sürgüsü); checkbox: hemi 0, sağ Ambient 0.88 * inten

API tarafında hatırlatma

new THREE.HemisphereLight(skyColor, groundColor, intensity) kurucusu üç parametreyi bir arada verir; kontrast sürgüsü gibi oyun alanı için örnekte olduğu gibi color ve groundColor özelliklerini çalışma anında lerp ile güncellemek yaygındır. intensity’yi sıfırlayıp başka bir dolgu ışığına geçmek, demodaki checkbox ile aynı fikrin sahne mantığına taşınmış halidir.

Yaygın hata: zıt renkleri abartmak

Parlak kırmızı gök + parlak yeşil yer

Hata: Gök ve yer rengini aşırı doygun, zıt kutuplara itmek.

Sonuç: Nesneler kirli ve yapay görünür.

Çözüm: Genelde yer rengini daha koyu veya daha düşük doygunlukta tut; gök ile dengeyi yumuşat.

Abartı genelde “renk tekerleğinde iki uç seçildi” şeklinde ortaya çıkar: gök ve yer birbirini tamamlayan tonlar yerine rekabet eden iki spot gibi davranır. Referans fotoğraf veya HDRI’den örnek al: doğada gök–yer ayrımı çoğu zaman doygunluk ve parlaklık farkıyla gelir, saf tamamlayıcı renk zıtlığıyla değil.

Ton eşlemesi (ACESFilmicToneMapping gibi) açıkken özellikle dikkat et: uç renkler highlight bölgelerinde yanıp sönebilir veya cilt / nötr gri yüzeylerde renk kayması yaratabilir. Şüpheye düştüğünde kontrast sürgüsünü veya intensity’yi düşürüp önce yönsel ışığın beyaz dengesini oturt.

Holodepth ilkesi ve production notu

Işık = mekân tanımı

Işık yalnızca “parlatmak” için değildir; nesnenin hangi dünyada durduğunu söyler. HemisphereLight ile “boşlukta değil, bir yer yüzeyinin üzerinde” mesajını verirsin.

Production: HemisphereLight tek başına ana güneş değildir; DirectionalLight (veya benzeri yönsel kaynak) ile birlikte kullanıldığında performans / görsellik dengesi açısından sıkça tercih edilen “altın standart”tır.

Çevre haritası veya IBL ile çalışmaya başladığında bile çoğu ekip, düşük şiddetli bir hemisferi son ince ayar katmanı olarak tutar: küre haritası genel yansımaları verirken, hemisfer zeminden gelen hafif sıcaklığı veya stüdyo tavan yansımasını hızlıca oynatılabilir bir parametre olarak bırakır. Böylece sanatçı, dosyayı yeniden üretmeden sahne hissini kaydırabilir.

Holodepth perspektifinde önemli olan, kullanıcıya “bu ışık gerçek dünyayı kopyalıyor” yalanını söylemeden, hangi görsel sorunu çözdüğünü açıkça bilmektir: HemisphereLight, dip aydınlığa yön duyarlılığı ekleyerek formu ve mekânı okunur kılar — gölge draması ve ana vurgu ise yine yönsel ışıkların işidir.