Materyaller

Gerçek dünyada her nesnenin ışığa farklı bir tepkisi vardır. Örneğin çelik nesneler genellikle kil vazodan daha parlaktır ve ahşap bir kap, çelik bir kap gibi ışığa tepki vermez. Bazı nesneler ışığı çok fazla dağılmadan yansıtır, bu da küçük aynasal vurgulara neden olur ve diğerleri çok fazla saçılarak vurguyu daha büyük bir yarıçapta verir. OpenGL' de birkaç nesne türünü benzetimlemek istiyorsak, her yüzeye özgü materyal\green {materyal} özelliklerini tanımlamamız gerekir.

Önceki bölümde, bir ortam ve yansıtıcı yoğunluk bileşeniyle birlikte nesnenin görsel çıktısını tanımlamak için bir nesne ve açık renk tanımladık. Bir yüzeyi tanımlarken, üç aydınlatma bileşeninin her biri için bir materyal rengi tanımlayabiliriz: ortam, dağınık ve yansıtıcı aydınlatma. Bileşenlerin her biri için bir renk belirleyerek, yüzeyin renk çıktısı üzerinde ince taneli kontrole sahip oluruz. Şimdi bu üç renge bir parlaklık bileşeni ekleyip ihtiyacımız olan tüm materyal özelliklerine sahip olacağız:

#version 330 core
struct Material {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
}; 
  
uniform Material material;

Parça gölgelendiricide, yüzeyin materyal özelliklerini depolamak için bir struct oluşturuyoruz. Bunları ayrıca tek tip değerler olarak da saklayabiliriz, ancak bunları bir struct olarak saklamak, daha düzenli olmasını sağlar. Önce struct' ın düzenini tanımlarız ve sonra yeni oluşturulan struct ile tek tip bir değişken tanımlarız.

Gördüğünüz gibi, Phong aydınlatmasının bileşenlerinin her biri için bir renk vektörü tanımlıyoruz. ambient materyali vektörü, yüzeyin ortam aydınlatması altında hangi rengi yansıttığını tanımlar; bu genellikle yüzeyin rengiyle aynıdır. diffuse materyal vektörü, dağınık aydınlatma altındaki yüzeyin rengini tanımlar. Yaygın renk (tıpkı ortam aydınlatması gibi) istenen yüzeyin rengine ayarlanır. specular materyal vektörü, yüzeydeki yansıyan vurgunun rengini ayarlar (veya hatta muhtemelen yüzeye özgü bir rengi yansıtır). Son olarak shininess , yansıyan açık tonun saçılımını/ yarıçapını etkiler.

Bir nesnenin materyalini tanımlayan bu 4 bileşenle birçok gerçek dünya materyalini benzetimleyebiliriz. devernay.free.fr adresinde bulunan tablo, dış dünyada bulunan gerçek materyalleri benzetimleyen materyal özelliklerinin bir listesini gösterir. Aşağıdaki görsel, bu gerçek dünya materyallerinden birkaçının küpümüz üzerindeki etkisini göstermektedir:

Gördüğünüz gibi, bir yüzeyin materyal özelliklerini doğru bir şekilde belirlemek, nesneye ilişkin sahip olduğumuz algıyı değiştiriyor. Etkiler açıkça fark edilir, ancak daha gerçekçi sonuçlar için küpü daha karmaşık bir şeyle değiştirmemiz gerekecek. Model Yükleme bölümlerinde daha karmaşık şekilleri tartışacağız.

Bir nesne için doğru materyal ayarlarını bulmak, çok fazla deneyim gerektiren zorlu bir başarıdır. Bir nesnenin görsel kalitesini yanlış yerleştirilmiş bir materyal ile tamamen yok etmek o kadar da raslanmadık bir durum değildir.

Hadi şimdi gölgelendiricilerde böyle bir materyal sistemi uygulamayı deneyelim.

Materyallerin Ayarlanması

Parça gölgelendiricide tek tip bir materyal struct'ı oluşturduk, bu nedenle daha sonra aydınlatma hesaplamalarını yeni materyal özelliklerine uyacak şekilde değiştirmek istiyoruz. Tüm materyal değişkenleri bir struct içinde depolandığından, onlara material uniform değişkeni ile erişebiliriz:

void main()
{    
    // ambient
    vec3 ambient = lightColor * material.ambient;
  	
    // diffuse 
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = lightColor * (diff * material.diffuse);
    
    // specular
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);  
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    vec3 specular = lightColor * (spec * material.specular);  
        
    vec3 result = ambient + diffuse + specular;
    FragColor = vec4(result, 1.0);
}

Gördüğünüz gibi artık materyal yapısının tüm özelliklerine ihtiyaç duyduğumuz her yerde erişiyoruz ve bu sefer ortaya çıkan rengini materyalin renkleri yardımıyla hesaplıyoruz. Nesnenin materyal özelliklerinin her biri, ilgili aydınlatma bileşenleriyle çarpılır.

Uygulamada nesnenin materyalini uygun uniform'lar ile ayarlayarak belirleyebiliriz. Bununla birlikte, GLSL' deki bir struct, uniform olarak ayarlanırken hiçbir açıdan özel değildir; bir struct yalnızca uniform değişkenlerin bir ad alanı olarak işlev görür. Struct'ı doldurmak istiyorsak, tek tek uniform değişkenleri ayarlamamız gerekecek, ancak struct'ın adını önek olarak alacağız:

lightingShader.setVec3("material.ambient", 1.0f, 0.5f, 0.31f);
lightingShader.setVec3("material.diffuse", 1.0f, 0.5f, 0.31f);
lightingShader.setVec3("material.specular", 0.5f, 0.5f, 0.5f);
lightingShader.setFloat("material.shininess", 32.0f);

ambient ve diffusediffuse bileşenini, nesnenin sahip olmasını istediğimiz renge ve nesnenin specularbileşenini orta parlak bir renge ayarladık; specular bileşenin çok güçlü olmasını istemiyoruz. Ayrıca parlaklığı 32'de tutuyoruz.

Artık nesnenin materyalini uygulamadan kolayca etkileyebiliriz. Programı çalıştırmak size şöyle bir şey verecektir:

Gerçekten de doğru görünmüyor mu?

Işık özellikleri

Nesne çok parlak. Nesnenin çok parlak olmasının nedeni, ortam, dağınık ve yansıtıcı renklerin herhangi bir ışık kaynağından tam güçle yansıtılmasıdır. Işık kaynakları ayrıca sırasıyla ortam, dağınık ve yansıtıcı bileşenleri için farklı yoğunluklara sahiptir. Önceki bölümde bunu, ortam ve yansıtıcı yoğunluklarını bir güç değeri ile değiştirerek çözdük. Benzer bir şey yapmak istiyoruz, ancak bu sefer aydınlatma bileşenlerinin her biri için yoğunluk vektörleri belirleyeceğiz. lightColor 'u vec3 (1.0) olarak görselleştirirsek, kod şöyle görünür:

vec3 ambient  = vec3(1.0) * material.ambient;
vec3 diffuse  = vec3(1.0) * (diff * material.diffuse);
vec3 specular = vec3(1.0) * (spec * material.specular); 

Böylece nesnenin her bir maddi özelliği, ışığın bileşenlerinin her biri için tam yoğunlukla döndürülür. Bu vec3 (1.0) değerleri, her bir ışık kaynağı için ayrı ayrı da etkilenebilir ve bu genellikle istediğimiz şeydir. Şu anda nesnenin ortam bileşeni küpün rengini tamamen etkiliyor. Ortam bileşeninin son renk üzerinde gerçekten çok büyük bir etkisi olmamalıdır, bu nedenle ışığın ortam yoğunluğunu daha düşük bir değere ayarlayarak ortam rengini sınırlayabiliriz:

vec3 ambient = vec3(0.1) * material.ambient; 

Işık kaynağının dağınık ve yansıtıcı yoğunluğuna da aynı şekilde etki edebiliriz. Bu, önceki bölümde yaptığımıza çok benzerdir. Her bir aydınlatma bileşenini ayrı ayrı etkilemek için bazı ışık özellikleri oluşturduğumuzu söyleyebilirsiniz. Işık özellikleri için material struct'ına benzer bir şey yaratmak isteyeceğiz:

struct Light {
    vec3 position;
  
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

uniform Light light;  

Bir ışık kaynağının çevresi, dağınık ve aynasal bileşenleri için farklı bir yoğunluğu vardır. Ortam renginin çok baskın olmasını istemediğimizden, ortam ışığı genellikle düşük bir yoğunluğa ayarlanmıştır. Bir ışık kaynağının dağınık bileşeni, genellikle bir ışığın sahip olmasını istediğimiz tam renge ayarlanır; genellikle parlak beyaz bir renktir. Aynasal bileşen genellikle tam yoğunlukta parlayan vec3 (1.0) değerinde tutulur. Ayrıca yapıya ışığın konum vektörünü de eklediğimize dikkat edin.

Tıpkı malzeme üniformasında olduğu gibi, parça gölgelendiricisini güncellememiz gerekiyor:

vec3 ambient  = light.ambient * material.ambient;
vec3 diffuse  = light.diffuse * (diff * material.diffuse);
vec3 specular = light.specular * (spec * material.specular); 

Ardından uygulamadaki ışık yoğunluklarını ayarlamak istiyoruz:

lightingShader.setVec3("light.ambient",  0.2f, 0.2f, 0.2f);
lightingShader.setVec3("light.diffuse",  0.5f, 0.5f, 0.5f); // darken diffuse light a bit
lightingShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f); 

Işığın nesnenin malzemesini nasıl etkilediğini değiştirdiğimize göre, önceki bölümün çıktısına çok benzeyen görsel bir çıktı elde ediyoruz. Ancak bu sefer nesnenin aydınlatması ve malzemesi üzerinde tam kontrole sahip olduk:

Nesnelerin görsel yönlerini değiştirmek şu anda nispeten kolay. İşleri biraz renklendirelim!

Farklı ışık renkleri

Şimdiye kadar, nesnenin gerçek renklerini (yalnızca yoğunluğunu) etkilemeden, beyazdan griden siyaha değişen renkler seçerek, yalnızca bileşenlerinin yoğunluğunu değiştirmek için açık renkleri kullandık. Artık ışığın özelliklerine kolayca erişebildiğimizden, gerçekten ilginç efektler elde etmek için zamanla renklerini değiştirebiliriz. Parça gölgelendiricide her şey zaten ayarlanmış olduğundan, ışığın renklerini değiştirmek kolaydır ve anında bazı ilginç efektler oluşturur:

Gördüğünüz gibi, farklı bir açık renk, nesnenin renk çıktısını büyük ölçüde etkiler. Açık renk, nesnenin hangi renkleri yansıtabileceğini doğrudan etkilediğinden (Renkler bölümünden hatırlayabileceğiniz gibi) görsel çıktı üzerinde önemli bir etkiye sahiptir.

sin ve glfwGetTime işlevleri ile ışığın ortamını değiştirerek ve renkleri yayarak zaman içinde ışığın renklerini kolayca değiştirebiliriz:

glm::vec3 lightColor;
lightColor.x = sin(glfwGetTime() * 2.0f);
lightColor.y = sin(glfwGetTime() * 0.7f);
lightColor.z = sin(glfwGetTime() * 1.3f);
  
glm::vec3 diffuseColor = lightColor   * glm::vec3(0.5f); 
glm::vec3 ambientColor = diffuseColor * glm::vec3(0.2f); 
  
lightingShader.setVec3("light.ambient", ambientColor);
lightingShader.setVec3("light.diffuse", diffuseColor);

Birkaç ışık ve malzeme değeri deneyin ve deneyin ve bunların görsel çıktıyı nasıl etkilediğini görün. Uygulamanın kaynak kodunu burada bulabilirsiniz.

Alıştırmalar

  • Işık rengini değiştirerek ışığın küpü nesnesinin rengini değiştirebilir misiniz?

  • Bu bölümün başında gördüğümüz gibi, bazı gerçek dünya nesnelerini ilgili malzemelerini tanımlayarak simüle edebilir misiniz? Tablonun ortam değerlerinin dağınık değerlerle aynı olmadığını unutmayın; ışık yoğunluklarını hesaba katmadılar. Değerlerini doğru bir şekilde ayarlamak için, aynı çıktıyı elde etmek için tüm ışık yoğunluklarını vec3 (1.0) olarak ayarlamanız gerekir: camgöbeği plastik konteyner çözümü.

Orijinal Kaynak: Materials

Çeviri: Nezihe Sözen

Last updated