> For the complete documentation index, see [llms.txt](https://cgtranslators.gitbook.io/opengl-ogrenin/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cgtranslators.gitbook.io/opengl-ogrenin/isiklandirma/isiklandirma-eslemeleri.md).

# Işıklandırma Eşlemeleri (Lighting Maps)

[Önceki bölümde](https://learnopengl.com/Lighting/Materials) her nesnenin ışığa farklı tepki veren kendine özgü bir materyale sahip olabildiğini inceledik. Bu, nesnelere birbirinden farklı görünüm kazandırmak için harika bir yöntemdir; ancak bir nesnenin görsel çıktısı konusunda hâlâ fazla esneklik sunmuyor.

Önceki bölümde bir materyali nesnenin tamamına tek tip olarak tanımladık. Gerçek dünyadaki nesneler ise genellikle tek bir materyalden değil, birçok materyalden oluşur. Bir arabayı düşünün: dış gövde parlak bir yüzeye sahiptir, camlar çevreyi kısmen yansıtır, lastikler parlaklıktan uzak olduğundan specular vurguları yoktur; jantlar ise son derece parlaktır (eğer arabanızı yıkadıysanız tabii). Arabanın diffuse ve ambient renkleri de nesnenin tamamı için aynı değildir; farklı bölümlerde farklı ambient/diffuse renkler görürsünüz. Kısacası böyle bir nesne, parçalarına göre farklı materyal özelliklerine sahiptir.

Dolayısıyla önceki bölümdeki materyal sistemi en basit modeller dışında yeterli değildir. Sistemi *diffuse* ve *specular* **eşlemeler (map)** sunarak genişletmemiz gerekiyor. Bu eşlemeler, bir nesnenin diffuse (ve dolaylı olarak ambient — ikisi zaten aynı olmalı) ile specular bileşenini çok daha hassas şekilde kontrol etmemizi sağlar.

***

### Diffuse Map

Amacımız, bir nesnenin diffuse renklerini her fragment için ayrı ayrı belirlemenin bir yolunu bulmaktır. Nesne üzerindeki fragment konumuna göre renk değeri alabileceğimiz bir sistem mi?

Bu kulağa tanıdık geliyor ve bir süredir böyle bir sistemi kullanıyoruz. Bu, [daha önceki bölümde](https://learnopengl.com/Getting-started/Textures) ayrıntılı olarak ele aldığımız *dokulardan* başka bir şey değil: nesneye sarılmış ve her fragment için benzersiz renk değerleri sunan bir görüntü. Işıklı sahnelerde buna genellikle **diffuse map** denir (PBR öncesinde 3D sanatçıların genel adlandırması budur), çünkü doku görüntüsü nesnenin tüm diffuse renklerini temsil eder.

Diffuse map'i göstermek için çelik çerçeveli bir ahşap konteynerin [şu görüntüsünü](https://learnopengl.com/img/textures/container2.png) kullanacağız:

![Konteyner diffuse doku](https://learnopengl.com/img/textures/container2.png)

Shader'larda diffuse map kullanımı, doku bölümünde gösterdiğimizle aynıdır. Bu kez dokuyu `Material` struct'ının içinde `sampler2D` olarak saklıyoruz. Daha önce tanımladığımız `vec3` diffuse renk vektörünü diffuse map ile değiştiriyoruz.

{% hint style="warning" %}
`sampler2D`'nin **opaque type** (opak tür) olduğunu unutmayın. Bu, bu türden değişkenlerin yalnızca uniform olarak tanımlanabileceği, örneklenemeyeceği anlamına gelir. Struct, uniform dışında (örneğin fonksiyon parametresi olarak) örneklenirse GLSL garip hatalar verebilir; bu durum, opaque type içeren tüm struct'lar için geçerlidir.
{% endhint %}

Ambient materyal vektörünü de kaldırıyoruz; artık ambient rengi diffuse rengiyle eşit olduğundan ve ambient'i ışıkla kontrol ettiğimizden ayrıca saklamaya gerek kalmıyor:

```glsl
struct Material {
    sampler2D diffuse;
    vec3      specular;
    float     shininess;
}; 
...
in vec2 TexCoords;
```

{% hint style="info" %}
Eğer biraz inatçıysanız ve ambient renkleri diffuse değerinden farklı ayarlamak istiyorsanız, ambient `vec3`'ü tutabilirsiniz; ancak bu durumda ambient renkler yine de tüm nesne için aynı kalacaktır. Her fragment için farklı ambient değerleri elde etmek isterseniz yalnızca ambient değerler için ayrı bir doku kullanmanız gerekir.
{% endhint %}

Fragment shader'da yine doku koordinatlarına ihtiyaç duyacağımıza dikkat edin; bu nedenle ekstra bir giriş değişkeni tanımladık. Ardından diffuse renk değerini almak için dokudan örnekleme yapıyoruz:

```glsl
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));  
```

Ambient materyal rengini de diffuse materyal rengiyle eşitlemeyi unutmayın:

```glsl
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
```

Diffuse map kullanmak için gereken tek şey bu kadar. Gördüğünüz gibi yeni bir şey değil; ancak görsel kalitede çarpıcı bir artış sağlıyor. Çalışması için vertex verilerini doku koordinatlarıyla güncellemek, bunları vertex attribute olarak fragment shader'a aktarmak, dokuyu yüklemek ve uygun texture unit'e bağlamak gerekiyor.

Güncellenmiş vertex verilerini [buradan](https://learnopengl.com/code_viewer.php?code=lighting/vertex_data_textures) bulabilirsiniz. Vertex verisi artık küpün her vertex'i için vertex konumları, normal vektörler ve doku koordinatlarını içeriyor. Doku koordinatlarını vertex attribute olarak kabul etmek ve fragment shader'a iletmek için vertex shader'ı güncelleyelim:

```glsl
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
...
out vec2 TexCoords;

void main()
{
    ...
    TexCoords = aTexCoords;
}  
```

Her iki VAO'nun vertex attribute pointer'larını yeni vertex verisine uygun şekilde güncellediğinizden ve konteyner görüntüsünü doku olarak yüklediğinizden emin olun. Küpü render etmeden önce `material.diffuse` uniform sampler'ına doğru texture unit'i atayın ve konteyner dokusunu bu texture unit'e bağlayın:

```cpp
lightingShader.setInt("material.diffuse", 0);
...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuseMap);
```

Artık diffuse map kullanarak detayda muazzam bir artış elde ediyoruz ve bu kez konteyner gerçekten parlamaya başlıyor. Konteyneriniz muhtemelen şuna benziyor:

![Diffuse map uygulanmış konteyner](https://learnopengl.com/img/lighting/materials_diffuse_map.png)

Uygulamanın tam kaynak kodunu [buradan](https://learnopengl.com/code_viewer_gh.php?code=src/2.lighting/4.1.lighting_maps_diffuse_map/lighting_maps_diffuse.cpp) bulabilirsiniz.

***

### Specular Map

Specular vurgunun biraz tuhaf göründüğünü fark etmiş olabilirsiniz; zira nesne büyük ölçüde ahşaptan oluşan bir konteyner ve ahşabın böyle specular vurgulara sahip olmaması gerekir. Bunu nesnenin specular materyalini `vec3(0.0)` yaparak düzeltebiliriz; ancak bu, konteynerin çelik çerçevelerinin de specular vurgularından yoksun kalmasına yol açar ve metalin *gerçekten* specular vurgu göstermesi gerekir. Nesnenin hangi bölümlerinin specular vurgu göstereceğini farklı yoğunluklarda kontrol etmek istiyoruz. Tanıdık bir problem gibi mi geliyor? Tesadüf mü? Bence değil.

Specular vurgular için de bir texture map kullanabiliriz. Bu, nesnenin her bölümünün specular yoğunluğunu tanımlayan siyah-beyaz (ya da renkli, tercih meselesi) bir doku oluşturmamız gerektiği anlamına gelir. [Specular map](https://learnopengl.com/img/textures/container2_specular.png) için örnek görüntü:

![Konteyner specular map](https://learnopengl.com/img/textures/container2_specular.png)

Specular vurgunun yoğunluğu, görüntüdeki her pikselin parlaklığından gelir. Specular map'teki her piksel, siyahın `vec3(0.0)` ve grinin örneğin `vec3(0.5)` renk vektörüne karşılık geldiği bir renk vektörü olarak yorumlanabilir. Fragment shader'da karşılık gelen renk değerini örnekler ve bu değeri ışığın specular yoğunluğuyla çarparız. Piksel ne kadar 'beyaz' ise çarpma sonucu o kadar büyür ve dolayısıyla nesnenin specular bileşeni o kadar parlak olur.

Konteyner büyük ölçüde ahşaptan oluştuğundan ve ahşabın specular vurguya sahip olmaması gerektiğinden, diffuse dokunun tüm ahşap kısmı siyaha dönüştürülmüştür: siyah bölgeler hiç specular vurgu almaz. Konteynerin çelik çerçevesi ise farklı specular yoğunluklarına sahiptir — metal yüzey specular vurgulara oldukça duyarlıyken çatlaklar daha az duyarlıdır.

{% hint style="info" %}
Teknik olarak ahşabın da specular vurguları vardır; ancak çok daha düşük bir shininess değeriyle (daha fazla ışık saçılması) ve daha az belirgin olarak. Öğrenme amacıyla ahşabın specular ışığa hiç tepki vermediğini varsayabiliriz.
{% endhint %}

*Photoshop* veya *Gimp* gibi araçlar kullanarak, diffuse dokudan bazı bölümleri kesip siyah-beyaza dönüştürerek ve parlaklık/kontrastı artırarak bu tür bir specular görüntü elde etmek görece kolaydır.

#### Specular Map Örnekleme

Specular map, diğer herhangi bir doku gibidir; dolayısıyla kod, diffuse map koduyla benzerdir. Görüntüyü doğru şekilde yükleyip bir doku nesnesi oluşturduğunuzdan emin olun. Aynı fragment shader'da başka bir texture sampler kullandığımızdan, specular map için farklı bir texture unit kullanmamız gerekiyor ([Dokular](https://learnopengl.com/Getting-started/Textures) bölümüne bakın). Render etmeden önce uygun texture unit'e bağlayalım:

```cpp
lightingShader.setInt("material.specular", 1);
...
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specularMap);  
```

Ardından fragment shader'ın materyal özelliklerini, specular bileşeni için `vec3` yerine `sampler2D` kabul edecek şekilde güncelleyin:

```glsl
struct Material {
    sampler2D diffuse;
    sampler2D specular;
    float     shininess;
};  
```

Son olarak fragment'ın karşılık gelen specular yoğunluğunu almak için specular map'ten örnekleme yapıyoruz:

```glsl
vec3 ambient  = light.ambient  * vec3(texture(material.diffuse,  TexCoords));
vec3 diffuse  = light.diffuse  * diff * vec3(texture(material.diffuse,  TexCoords));  
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
FragColor = vec4(ambient + diffuse + specular, 1.0);   
```

Specular map kullanarak nesnenin hangi bölümlerinin *parlak* özelliğe sahip olduğunu büyük bir hassasiyetle belirleyebilir, hatta karşılık gelen yoğunluğu da kontrol edebiliriz. Specular map, diffuse map'in üstüne ek bir ışıklandırma kontrol katmanı ekler.

{% hint style="info" %}
Çok geniş kitleye hitap etmek yerine, specular map'te her fragment'ın specular yoğunluğunu belirlemenin yanı sıra specular vurgunun rengini de belirlemek için gerçek renkler kullanabilirsiniz. Ancak gerçekte specular vurgunun rengi büyük ölçüde ışık kaynağının kendisi tarafından belirlenir; bu nedenle gerçekçi görsel sonuçlar vermez. (Bu yüzden görüntüler genellikle siyah-beyazdır: yalnızca yoğunlukla ilgileniyoruz.)
{% endhint %}

Uygulamayı çalıştırırsanız, konteynerin materyalinin artık gerçek bir ahşap konteynere çok daha yakın göründüğünü açıkça göreceksiniz:

![Specular map uygulanmış konteyner](https://learnopengl.com/img/lighting/materials_specular_map.png)

Uygulamanın tam kaynak kodunu [buradan](https://learnopengl.com/code_viewer_gh.php?code=src/2.lighting/4.2.lighting_maps_specular_map/lighting_maps_specular.cpp) bulabilirsiniz.

Diffuse ve specular map'leri kullanarak görece basit nesnelere muazzam miktarda detay ekleyebiliriz. Normal/bump map ve/veya yansıma map (reflection map) gibi başka texture map'leriyle de daha fazla detay ekleyebiliriz; ancak bunları ilerleyen bölümlere saklıyoruz. Konteynerinizi arkadaşlarınıza ve ailenize gösterin; bir gün olduğundan da güzel hale gelebileceği gerçeğiyle içiniz rahat etsin!

***

### Alıştırmalar

* Işık kaynağının ambient, diffuse ve specular vektörleriyle oynayın; konteynerin görsel çıktısını nasıl etkilediğini gözlemleyin.
* Fragment shader'da specular map renk değerlerini ters çevirmeyi deneyin; böylece ahşap specular vurgu alırken çelik çerçeveler almaz (çelik çerçevedeki çatlaklar nedeniyle çerçeve hâlâ biraz specular vurgu alacaktır, ancak daha az yoğunlukla): [çözüm](https://learnopengl.com/code_viewer_gh.php?code=src/2.lighting/4.3.lighting_maps_exercise2/lighting_maps_exercise2.cpp).
* Siyah-beyaz yerine gerçek renkler kullanan diffuse dokusundan bir specular map oluşturmayı deneyin ve sonucun pek gerçekçi görünmediğini fark edin. Kendiniz oluşturamıyorsanız [renkli specular map'i](https://learnopengl.com/img/lighting/lighting_maps_specular_color.png) kullanabilirsiniz: [sonuç](https://learnopengl.com/img/lighting/lighting_maps_exercise3.png).
* **Emission map** ekleyin: bu, her fragment için emisyon değerlerini saklayan bir dokudur. Emisyon değerleri, sanki kendi içinde bir ışık kaynağı varmış gibi bir nesnenin *yaydığı* renklerdir; böylece nesne ışık koşullarından bağımsız olarak parlar. Emission map'ler genellikle oyunlardaki parlayan nesnelerde görülür ([robot gözleri](https://learnopengl.com/img/lighting/lighting_maps_eyes_robot.jpg) veya [konteyner üzerindeki ışık şeritleri](https://learnopengl.com/img/lighting/lighting_maps_strips_container.png) gibi). Şu [dokuyu](https://learnopengl.com/img/textures/matrix.jpg) (creativesam tarafından) konteynere emission map olarak ekleyin; sanki harfler ışık yayıyormuş gibi görünsün: [çözüm](https://learnopengl.com/code_viewer_gh.php?code=src/2.lighting/4.4.lighting_maps_exercise4/lighting_maps_exercise4.cpp); [sonuç](https://learnopengl.com/img/lighting/lighting_maps_exercise4.png).

***

*Orijinal kaynak:* [*LearnOpenGL – Lighting/Lighting-maps*](https://learnopengl.com/Lighting/Lighting-maps)\
*Türkçe çeviri: Nezihe Sözen*
