Three.js · PBR
MeshStandardMaterial: Gerçekçiliğin Kodlanmış Hali
Işığın yüzeyle yaptığı pazarlık
Bazı 3D modeller neden “plastik” gibi görünürken, diğerleri gerçek hayattan farksızdır? Aradaki
fark, ışığın yüzeye yalnızca çarpması değil, o yüzeyle nasıl bir pazarlığa
girdiğidir. Three.js dünyasında bu pazarlığın adı PBR (Physically Based
Rendering), yani fiziksel temelli render modelidir. MeshStandardMaterial, bu
felsefenin kalbidir.
Klasik Phong’ta ayrı bir “parlak leke” rengi vardır; Standard’da ise aynı hikâye
metalness · roughness · çevre ışığı üzerinden, enerji tutarlılığına yakın
bir dilde anlatılır — bu yüzden glTF ve modern içerik boru hatlarıyla uyumludur.
Önkoşul: MeshPhongMaterial (stilize specular) ve MeshLambertMaterial (mat difüz); ışıksız referans MeshBasicMaterial. Cam, clearcoat ve genişletilmiş yüzey katmanları için MeshPhysicalMaterial. Kavramsal çerçeve: Materyal giriş. Üretim disiplini: HoloDepth kuralları. Sayfa sonunda özet ve komşu ders bağlantıları.
Zihin modeli: PBR nedir?
Özet
PBR kullanırken ışığı “taklit etmeye” çalışmazsınız; ışığın yüzeydeki fiziksel davranışını modellersiniz. Işık bir yüzeye çarptığında ya yansır ya emilir; PBR bu dengeyi matematiksel bir disiplinle — enerji korunumu çerçevesinde — yönetir.
Pratikte bu, sanatçıya şunu söyler: “Işığı tek tek hileyle boyamak” yerine yüzeyi
iletkenlik (metal) ve mikro pürüzlülük (roughness) ile
tanımlarsın; yansımaların neyi göstereceği büyük ölçüde sahnedeki ortam ve ışık
düzeninden gelir. Aynı metalness / roughness çifti,
farklı HDR ortamlarında tamamen farklı karakter okunabilir — bu bir hata değil, PBR’nin
tasarım sözleşmesidir.
MeshStandardMaterial tek başına “fotoğraf modu” değildir; doğru ton eşlemesi,
exposure ve (çoğu projede) çevre haritası ile birlikte düşünülmelidir.
Aşağıdaki bölümlerde önce parametre sezgisi, sonra çevre bağımlılığı ve en sonda etkileşimli
örnek üzerinden bu zinciri somutlaştırıyoruz.
Hızlı görünüm rehberi: kombinasyonlar
PBR dünyasında çoğu malzeme görünümü metalness ve roughness ikilisinin dansına bağlıdır. Sık kullanılan “tarifler”:
Metalness · roughness
Cilalı metal
metalness: 1.0
roughness: 0.1
Aynaya yakın, keskin yansımalar.
Fırçalanmış çelik
metalness: 1.0
roughness: 0.5
Mat ama metalik; pütürlü yüzey hissi.
Parlak plastik
metalness: 0.0
roughness: 0.1
Yansıtıcı ama metal olmayan; lake yüzey.
Kuru toprak / taş
metalness: 0.0
roughness: 0.9
Işığı dağıtan, pürüzlü ve mat görünüm.
Kartlardaki değerler başlangıç noktalarıdır; gerçek üretimde çoğu zaman
metalnessMap, roughnessMap veya glTF içinde kanal birleştirme
(ör. ORM dokusu) ile yüzey içi varyasyon taşınırsın. Bu sayfada harita ayrıntılarına
girmeden bile şu ayrımı korumak yeterlidir: metalness “parlaklık
sürgüsü” değil, dielectric ↔ conductor ayrımıdır; parlaklığın keskinliği
ve yansıma bulanıklığı ise roughness ve çevre aydınlatmasıyla birlikte
okunur.
Albedo (color / map) seçerken metal yüzeylerde renk bilgisinin
çoğunun yansımada “yaşadığını” unutma: tam metalde difüz taban sık sık çevre
tonlarına kayar; bu yüzden referans görselini tek bir spot altında değil,
hedef ortamın ışığında değerlendirmek gerekir.
En büyük yanılgı: metalness parlaklık değildir
Yeni başlayanlar tuzağı
Nesneyi “parlatmak” için metalness değerini artırmak — yaygın ama yanlış bir
refleks.
Gerçek: metalness yalnızca yüzeyin iletkenlik /
metal karakterini belirler.
- Parlaklık (brightness): Işık kaynağının gücü ve albedo ile ilişkilidir.
- Bulanıklık (blur):
roughnessile kontrol edilir. - Yansıma: Sahnede çevre haritası (env map) yoksa, metaliklik çoğu zaman kendini yalnızca koyu, cansız bir alan olarak gösterir.
Doğru refleks şudur: önce çevreyi ve kamera exposure’unu oturt, sonra roughness ile yansımanın keskinliğini ayarla; metalness’i yalnızca malzeme gerçekten iletken/metal davranışı istediğinde yükselt. Dielectric bir yüzeyi “parlak” hissettirmek için çoğu zaman düşük roughness + güçlü ortam yeterlidir — metalness’i tırmalamadan.
Bu yanılgı, Phong alışkanlığından gelir: orada parlaklık ayrı bir specular
rengiyle modellenirdi. Standard’da ise parlaklığın büyük kısmı BRDF + ortam
konvolüsyonu üzerinden gelir; bu yüzden “aynı slider hissi” yoktur ve ilk gün
kafa karıştırıcıdır — ama tutarlılık ödülü, farklı sahneler arasında taşınabilir malzeme
dilidir.
Gerçekçiliğin sırrı: ortam (environment map)
PBR ve çevre
PBR materyalin en önemli içgörüsü şudur: Yansıtacak bir dünya yoksa, metal tam
anlamıyla
çalışmaz. Metalik yüzeyler doğası gereği çevreyi yansıtır.
scene.environment veya materyalin envMap özelliği boşsa, ayarları
ne kadar ince ayarlasanız da yüzey sık sık koyu ve cansız kalır.
MeshStandardMaterial, etrafındaki dünyadan beslenen bir aynadır.
Three.js tarafında çevre genelde PMREMGenerator ile ön işlenmiş bir kübik
doku olarak gelir; bu, speküler lobların farklı genişliklerde doğru bulanıklaşmasına
yardım eder. scene.environment sahneye yayılır; istenirse tek nesneye özel
envMap da verilebilir — ikinci yol, varyasyon için güçlü olsa da bellek ve
tutarlılık maliyetini artırır.
Aşağıdaki etkileşimli örnekte prosedürel bir ortam kullanıldığı için harici HDR dosyası yoktur; yine de “IBL kapatılınca metalin neden solgunlaştığı” dersi aynen geçerlidir. Sayısal ayrıntılar figür altındaki özetle birlikte demo sabitleri tablosunda toplanır; burada odak iş akışıdır: önce ortamı doğrula, sonra metalness / roughness ile formu şekillendir.
İnteraktif: “PBR facet gem”
Bu sahnede sol taraftaki facet’li gövde tam PBR parametreleriyle
güncellenir; sağdaki küçük küre ise dielectric bir referans baseline
olarak sabit kalır — böylece metalness / roughness oynatırken “tamamen metal mi, yoksa
parlak dielectric mi?” ayrımını gözle karşılaştırabilirsiniz. Üstteki onay kutusu
scene.environment’ı açıp kapatır; bu tek hareket, bir önceki bölümdeki
“çevresiz metal” uyarısını sahada anında gösterir.
Readout satırı anlık değerleri kısaltır; ışık yerleşimi, IBL
yoğunluğu ve spot açısı gibi ince ayarlar figür altındaki açıklamada — metinleri üst üste
binmeden okumak için önce sürgüleri deneyip sonra alt yazıyı tarayın. Tüm sayısal ölçüler
demo sabitleri
tablosunda diagram-standard-material.js ile eşlenir.
Sol: dodecahedron — sürgülerle PBR; sağ: küçük referans
küre (metalness 0, roughness 0.5), metal olmayan dielectric baseline.
scene.environmentIntensity ~2 ile IBL daha hissedilir; PMREM içinde parlak
nokta + küçük emissive küre ve daha düşük blur (sigma) ile çevrede keskin
bir “hotspot”; sahnede dar cone SpotLight + accent nokta ışık spec’i
netleştirir. Ana gövde rengi soğuk nötr gri taban. IBL kapatınca yine aynı öğreti.
Harici HDR/doku URL yok.
Demo sabitleri tablosu (PBR facet gem)
initStandardDemo · prosedürel ortam PMREMGenerator.fromScene ile
üretilir; ana sahnede ızgara, dodecahedron + referans küre, çoklu ışık ve IBL aç/kapa ile
doldurma güçlendirme (fillLow / fillBoost). Gölge haritası yok.
| Sahne / rol | Parametre | Değer | Tür |
|---|---|---|---|
| Renderer | WebGLRenderer |
antialias: true · alpha: false ·
powerPreference: high-performance ·
setPixelRatio(min(dpr, 2)) · SRGBColorSpace · arka
plan
0x070910 · ACESFilmicToneMapping · exposure
1.06 · gölge yok
|
🔒 Sabit |
| PMREM ortam üretimi | fromScene |
σ (blur) 0.022 · iç sahne: BoxGeometry(48,48,48) arka
yüz 0x1a1528 roughness 0.92 · ışıklar:
0xffdcc8 3.6 · 0x9ec4ff 3.2
·
beyaz 4.4 · nokta 52 @ (8.5,6.2,7) ·
emissive küre emissiveIntensity 6 @ (6.8,5.5,9.2)
|
🔒 Sabit |
| Sahne · IBL açık | scene.environment |
PMREM dokusu · environmentIntensity (destekleniyorsa)
2.05 · arka plan 0x070910
|
🔒 + ↔ UI |
| Sahne · IBL kapalı | scene.environment |
null · environmentIntensity
1 · arka plan 0x121a28 · dolgu ışıkları
fillBoost (ambient 0.48, key 1.55, rim
0.72, accent 1.45, spot 2.95)
|
🔒 + ↔ UI |
| Izgara | GridHelper |
boyut 14 · bölüm 28 · renkler
0x3a4a6a / 0x1a2030 · y = -0.52
|
🔒 Sabit |
| Doldurma (IBL açık) | AmbientLight / DirectionalLight ×2 ·
PointLight · SpotLight
|
ambient 0xffffff 0.2 · key 1.2 konum
(4.5, 6.2, 3.5) · rim 0xb8c8ff 0.5 konum
(-4, 2.5, -3.5) · accent 0xfff2dd 1.15
mesafe 14 decay 1.6 konum
(2.1, 2.35, 2.2) · spot 2.35
mesafe 22 açı
13° penumbra 0.38 decay 1.15 konum
(3.05, 3.45, 2.65) hedef (-0.48, 0.82, 0)
|
🔒 + ↔ UI |
| Ana gövde | MeshStandardMaterial / DodecahedronGeometry |
renk 0xb2bac4 · başlangıç metalness 0.65 roughness
0.28 · envMapIntensity 1.22 · geometri
(1.1, 0) · konum (-0.5, 0.82, 0) · dönüş
(0.22, 0.55, 0.12)
|
🔒 + ↔ UI |
| Referans küre | MeshStandardMaterial / SphereGeometry |
renk 0xa8c4e8 · metalness 0 · roughness
0.5 · envMapIntensity 1.05 · yarıçap 0.32
· segment 36 · konum (1.48, 0.56, 0.18)
|
🔒 Sabit |
| Kamera | PerspectiveCamera |
FOV 40 · yakın/uzak 0.08 / 80 · konum
(0.32, 0.9, 3.25) · lookAt(0.06, 0.68, 0.06)
|
🔒 Sabit |
| OrbitControls | damping / mesafe | enableDamping · 0.06 · hedef
(0.06, 0.68, 0.06) · mesafe 2.05…12
|
🔒 Sabit |
| HTML · Metalness | type="range" |
0…1 · adım 0.01 · varsayılan 0.65 |
🔒 + ↔ UI |
| HTML · Roughness | type="range" |
0…1 · adım 0.01 · varsayılan 0.28 |
🔒 + ↔ UI |
| HTML · IBL | checkbox |
data-standard-demo-env · varsayılan işaretli
(scene.environment açık) |
🔒 + ↔ UI |
Önemli kod kesiti
apply() sürgülerden metalness ve roughness okur; IBL kapalıyken ortamı
kaldırıp dolgu ışıklarını güçlendirir — böylece “karanlık metal” yerine kontrollü bir
sahnede aynı karşılaştırma okunabilir kalır.
function apply() {
const m = metal ? Number(metal.value) : 0.65;
mat.metalness = Math.max(0, Math.min(1, m));
const r = rough ? Number(rough.value) : 0.28;
mat.roughness = Math.max(0, Math.min(1, r));
mat.needsUpdate = true;
const envOn = !!(envCb && envCb.checked);
scene.environment = envOn ? envMap : null;
if ("environmentIntensity" in scene) {
scene.environmentIntensity = envOn ? 2.05 : 1;
}
const boost = !envOn;
ambient.intensity = boost ? fillBoost.amb : fillLow.amb;
key.intensity = boost ? fillBoost.key : fillLow.key;
rim.intensity = boost ? fillBoost.rim : fillLow.rim;
accent.intensity = boost ? fillBoost.accent : fillLow.accent;
spot.intensity = boost ? fillBoost.spot : fillLow.spot;
scene.background = new THREE.Color(boost ? fillBoost.bg : fillLow.bg);
if (readout) {
const envMsg = envOn
? "IBL güçlü (scene.environmentIntensity ~2) — metal vs mat küre kıyasını izle."
: "IBL kapalı — metal ‘boşluğa’ bakar; sağdaki küre zaten metal değil (0/0.5).";
readout.textContent = `${envMsg} Ana: metalness ${mat.metalness.toFixed(
2
)} · roughness ${mat.roughness.toFixed(2)}.`;
}
}
Uygulama: profesyonel kurulum
Tipik bir PBR kurulumu, glTF ile uyumlu düşünüldüğünde aynı parametreler başka motorlarda da
tutarlı kalır.
Üretimde sıradaki adım genelde aoMap, normalMap,
roughnessMap ve metalnessMap (veya birleşik ORM) ile yüzey
detayını eklemektir; aşağıdaki örnek yalnızca çekirdek API’yi gösterir.
Renderer tarafında tone mapping ve doğru renk uzayı seçimi, PBR’nin “doğal” görünmesi için ayrı bir sıradır; demo scriptinde bu yüzden filmik tonlama ve sRGB çıkışı kullanılır — koddaki tek satırlık materyal örneği, bu bağlamın yer tutucusudur.
// 1. Standart PBR kurulumu
const material = new THREE.MeshStandardMaterial({
color: 0xffffff, // Albedo (taban renk)
metalness: 1.0, // Tam metal karakteri
roughness: 0.2 // Hafif mikro pürüzlülük
});
// 2. Neden glTF bu materyali kullanır?
// glTF/GLB formatları motor bağımsızdır (Unreal, Unity, Three.js).
// PBR sayesinde modeliniz her platformda aynı tutarlılıkla görünür.
const textureLoader = new THREE.TextureLoader();
material.normalMap = textureLoader.load('/textures/surface_detail_normal.jpg');
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
Doku yüklerken colorSpace ve flipY bayraklarını hedef formatına
(ör. glTF içe aktarımda beklenen renk uzayı ve doku yönü kuralları için) göre ayarlamayı
unutmayın; yanlış uzay, PBR’de
“her şey yağlı” veya “her şey tozlu” gibi sistematik hatalara dönüşür. Ortam haritası
ürettiğinizde PMREMGenerator çıktısını ve geçici sahne nesnelerini kullanım
sonrası dispose etmek bellek basıncını azaltır.
Holodepth üretim kuralları
A Performans dengesi
PBR materyaller GPU için maliyetlidir; her pikselde karmaşık BRDF hesapları çalışır. Sahnede binlerce PBR nesnesi, özellikle mobilde cihazı zorlar.
B Altın kural: hero vs. arka plan
Hero: Kullanıcının yakından baktığı, etkileşime girdiği modellerde
MeshStandardMaterial kullanın.
Arka plan: Uzak binalar, ikincil objeler veya LOD ile küçültülmüş mesh’lerde MeshLambertMaterial veya MeshBasicMaterial ile GPU’ya nefes aldırın.
Bu ayrım “kalite düşürmek” değil, dikkat bütçesini yönetmektir: izleyici nereye bakıyorsa orada tam BRDF, periphery’de ise daha ucuz shading ile kare başına maliyet sabitlenir. İçerik takımında bunu netleştirmek, sanat ile mühendislik arasındaki en sık çatışmayı erken kapatır.
Son kontrol listesi: hero mesh için ortam + temel ışık düzeni, LOD geçişinde materyal ailesi (Standard → Lambert / Basic), mobilde doku çözünürlüğü ve roughness/metalness haritalarının gereksiz yüksek frekans taşımadığından emin olma. Bir sonraki derste MeshPhysicalMaterial ile cam, transmisyon ve clearcoat gibi Standard’ın üstüne çıkan katmanları ele alıyoruz.