Opengl-光照-基本光照-光照貼圖(現在告別單調的方塊弄個箱子)
前言
前面我們跟著LearnOpengl學習的都是通過怎麼定義一些頂點資料弄出一個立方體在三維世界裡模擬光照模擬光源。看著是有點真實的樣子了。。可是你見過哪個真實世界裡都是這些個立方體的,肯定都是真切的物體啊,什麼房子,樹,石頭,木頭等等。要怎麼模擬這些呢?怎麼把這些放進去呢?很簡單啊。基本章節就學習了紋理座標,我們就已經給立方體貼上了紋理讓它成為了一個箱子-結果可以去看我第一章最後的成果圖。
然後,我們還缺什麼呢?就是把箱子上照上光,我們都說了第一節學習東西沒有生氣的原因就是死板不真實就是因為沒有光,現在加上光不就是真實世界的東西了麼?
現實世界中的物體通常並不只包含有一種材質,而是由多種材質所組成。想想一輛汽車:它的外殼非常有光澤,車窗會部分反射周圍的環境,輪胎不會那麼有光澤,所以它沒有鏡面高光,輪轂非常閃亮(如果你洗車了的話)。汽車同樣會有漫反射和環境光顏色,它們在整個物體上也不會是一樣的,汽車有著許多種不同的環境光/漫反射顏色。總之,這樣的物體在不同的部件上都有不同的材質屬性。
漫反射貼圖
我們希望通過某種方式對物體的每個片段單獨設定漫反射顏色。有能夠讓我們根據片段在物體上的位置來獲取顏色值得系統嗎?
說到這句話,有沒有點點熟悉的感覺?我們希望通過物體上的位置找到物體的顏色。這不就是紋理麼?我們紋理學的就是這麼個道理啊,把紋理想象成一張地圖,然後根據位置可以找到紋理上的每一個畫素,這就是顏色啊。所以其實漫反射貼圖沒啥新東西,就是紋理的那個原理。
struct Material {
sampler2D diffuse;
vec3 specular;
float shininess;
};
Material的diffuse 變成了sampler2D 是因為紋理取樣,這個不用多說吧。前面紋理的時候介紹過了。
shader中的核心程式碼
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
有了漫反射貼圖,會不會想,有咩有鏡面光貼圖?是的,兄弟沒想錯,就是這樣子的,有有有。我們可以看的出來漫反射貼圖使用了之後,整個箱子都會在光源的照射下一大部分有高亮,不論是木頭材質還是鐵材質,而真正能晃眼的其實應該是鐵,木頭不應該。怎麼做呢?簡單的想我們可以將物體的鏡面光材質設定為vec3(0.0)來解決這個問題,可是。。。這樣都不反光了啊。怎麼做。。肯定就是要用到鏡面光貼圖了
鏡面光貼圖
struct Material {
sampler2D diffuse ;
sampler2D specular;
float shininess;
};
[...]
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);
看出來了麼?其實核心思想就是,漫反射貼圖結合光照顏色就是為了體現物體本身在光照下反射的大概顏色的。然後鏡面光貼圖的目的就是為了讓不同的才體現出不同的反光程度。