光照-04.光照貼圖(Lighting maps)

前面的材質(zhì)系統(tǒng)對(duì)于除了最簡(jiǎn)單的模型以外都是不夠的壤短,所以我們需要擴(kuò)展前面的系統(tǒng),我們要介紹diffuse和specular貼圖雁社。它們?cè)试S你對(duì)一個(gè)物體的diffuse(而對(duì)于簡(jiǎn)潔的ambient成分來(lái)說(shuō)浴井,它們幾乎總是是一樣的)和specular成分能夠有更精確的影響。

漫反射貼圖(Diffuse maps)

使用一張圖片覆蓋住物體霉撵,以便我們?yōu)槊總€(gè)原始像素索引獨(dú)立顏色值磺浙。在光照?qǐng)鼍爸校ㄟ^(guò)紋理來(lái)呈現(xiàn)一個(gè)物體的diffuse顏色徒坡,這個(gè)做法被稱(chēng)做漫反射貼圖(Diffuse map)(因?yàn)?D建模師就是這么稱(chēng)呼這個(gè)做法的)撕氧。注:它基本就是一個(gè)紋理。我們其實(shí)是使用同一個(gè)潛在原則下的不同名稱(chēng)喇完。

為了演示漫反射貼圖伦泥,我們將會(huì)使用下面的圖片,它是一個(gè)有一圈鋼邊的木箱:

在著色器中使用漫反射貼圖和紋理教程介紹的一樣锦溪。這次我們把紋理以sampler2D類(lèi)型儲(chǔ)存在Material結(jié)構(gòu)體中不脯。我們使用diffuse貼圖替代早期定義的vec3類(lèi)型的diffuse顏色。

要記住的是sampler2D也叫做模糊類(lèi)型刻诊,這意味著我們不能以某種類(lèi)型對(duì)它實(shí)例化防楷,只能用uniform定義它們。如果我們用結(jié)構(gòu)體而不是uniform實(shí)例化(就像函數(shù)的參數(shù)那樣)坏逢,GLSL會(huì)拋出奇怪的錯(cuò)誤域帐;這同樣也適用于其他模糊類(lèi)型赘被。

我們也要移除amibient材質(zhì)顏色向量是整,因?yàn)閍mbient顏色絕大多數(shù)情況等于diffuse顏色,所以不需要分別去儲(chǔ)存它:

struct Material     // 儲(chǔ)存物體的材質(zhì)屬性
{
    sampler2D diffuse;
    vec3 specular;
    float shininess;
};
in vec2 TexCoords;

如果你非把a(bǔ)mbient顏色設(shè)置為不同的值不可(不同于diffuse值)民假,你可以繼續(xù)保留ambient的vec3浮入,但是整個(gè)物體的ambient顏色會(huì)繼續(xù)保持不變。為了使每個(gè)原始像素得到不同ambient值羊异,你需要對(duì)ambient值單獨(dú)使用另一個(gè)紋理事秀。(彤断??易迹?)

注意宰衙,在片段著色器中我們將會(huì)再次需要紋理坐標(biāo),所以我們聲明一個(gè)額外輸入變量睹欲。然后我們簡(jiǎn)單地從紋理采樣供炼,來(lái)獲得原始像素的diffuse顏色值:

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

同樣,不要忘記把a(bǔ)mbient材質(zhì)的顏色設(shè)置為diffuse材質(zhì)的顏色:

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

這就是diffuse貼圖的全部?jī)?nèi)容了窘疮。就像你看到的袋哼,這不是什么新的東西,但是它卻極大提升了視覺(jué)品質(zhì)闸衫。為了讓它工作涛贯,我們需要用到紋理坐標(biāo)更新頂點(diǎn)數(shù)據(jù),把它們作為頂點(diǎn)屬性傳遞到片段著色器蔚出,把紋理加載并綁定到合適的紋理單元弟翘。

更新的頂點(diǎn)數(shù)據(jù)可以從這里找到。頂點(diǎn)數(shù)據(jù)現(xiàn)在包括了頂點(diǎn)位置身冬,法線(xiàn)向量和紋理坐標(biāo)衅胀,每個(gè)立方體的頂點(diǎn)都有這些屬性。讓我們更新頂點(diǎn)著色器來(lái)接受紋理坐標(biāo)作為頂點(diǎn)屬性酥筝,然后發(fā)送到片段著色器:

#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoords;
...
out vec2 TexCoords;

void main()
{
...
   TexCoords = texCoords;
}

要保證更新的頂點(diǎn)屬性指針滚躯,不僅是VAO匹配新的頂點(diǎn)數(shù)據(jù),也要把箱子圖片加載為紋理嘿歌。在繪制箱子之前掸掏,我們希望首選紋理單元被賦為material.diffuse這個(gè)uniform采樣器,并綁定箱子的紋理到這個(gè)紋理單元:

glActiveTexture (GL_TEXTURE0);      // 激活紋理單元
glBindTexture (GL_TEXTURE_2D, diffuseMap);  // 綁定紋理diffuseMap到當(dāng)前激活的紋理單元
glUniform1i (glGetUniformLocation (lightingShader.Program, "material.diffuse"), 0); // 定義采樣器material.diffuse對(duì)應(yīng)這個(gè)紋理單元

現(xiàn)在宙帝,使用一個(gè)diffuse貼圖丧凤,我們?cè)诩?xì)節(jié)上再次獲得驚人的提升,這次添加到箱子上的光照開(kāi)始閃光了(名符其實(shí))步脓。你的箱子現(xiàn)在可能看起來(lái)像這樣:

Image 070.png

你可以在這里得到應(yīng)用的全部代碼愿待。

鏡面貼圖

由于我們的物體是個(gè)箱子,大部分是木頭靴患,我們知道木頭是不應(yīng)該有鏡面高光的仍侥。我們通過(guò)把物體設(shè)置specular材質(zhì)設(shè)置為vec3(0.0f)來(lái)修正它。但是這樣意味著鐵邊會(huì)不再顯示鏡面高光鸳君,我們知道鋼鐵是會(huì)顯示一些鏡面高光的农渊。我們會(huì)想要控制物體部分地顯示鏡面高光,它帶有修改了的亮度或颊。這個(gè)問(wèn)題看起來(lái)和diffuse貼圖的討論一樣砸紊。這是巧合嗎传于?我想不是。

我們同樣用一個(gè)紋理貼圖醉顽,來(lái)獲得鏡面高光沼溜。這意味著我們需要生成一個(gè)黑白(或者你喜歡的顏色)紋理來(lái)定義specular亮度,把它應(yīng)用到物體的每個(gè)部分游添。下面是一個(gè)specular貼圖的例子:


盛末、

一個(gè)specular高光的亮度可以通過(guò)圖片中每個(gè)紋理的亮度來(lái)獲得。specular貼圖的每個(gè)像素可以顯示為一個(gè)顏色向量否淤,比如:在那里黑色代表顏色向量vec3(0.0f)悄但,灰色是vec3(0.5f)。在片段著色器中石抡,我們采樣相應(yīng)的顏色值檐嚣,把它乘以光的specular亮度。像素越“白”啰扛,乘積的結(jié)果越大嚎京,物體的specualr部分越亮。

由于箱子幾乎是由木頭組成隐解,木頭作為一個(gè)材質(zhì)不會(huì)有鏡面高光鞍帝,整個(gè)木頭部分的diffuse紋理被用黑色覆蓋:黑色部分不會(huì)包含任何specular高光。箱子的鐵邊有一個(gè)修改的specular亮度煞茫,它自身更容易受到鏡面高光影響帕涌,木紋部分則不會(huì)。

從技術(shù)上來(lái)講续徽,木頭也有鏡面高光蚓曼,盡管這個(gè)閃亮值很小(更多的光被散射)钦扭,影響很小纫版,但是為了學(xué)習(xí)目的,我們可以假裝木頭不會(huì)有任何specular光反射客情。

使用Photoshop或Gimp之類(lèi)的工具其弊,通過(guò)將圖片進(jìn)行裁剪,將某部分調(diào)整成黑白圖樣膀斋,并調(diào)整亮度/對(duì)比度的做法梭伐,可以非常容易將一個(gè)diffuse紋理貼圖處理為specular貼圖。

鏡面貼圖采樣

一個(gè)specular貼圖和其他紋理一樣概页,所以代碼和diffuse貼圖的代碼也相似籽御。確保合理的加載了圖片练慕,生成一個(gè)紋理對(duì)象惰匙。由于我們?cè)谕瑯拥钠沃髦惺褂昧硪粋€(gè)紋理采樣器技掏,我們必須為specular貼圖使用一個(gè)不同的紋理單元(參見(jiàn)紋理),所以在渲染前讓我們把它綁定到合適的紋理單元

glActiveTexture (GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, specularMap);
glUniform1i (glGetUniformLocation (lightingShader.Program, "material.specular"), 1);

然后更新片段著色器材質(zhì)屬性项鬼,接受一個(gè)sampler2D作為這個(gè)specular部分的類(lèi)型哑梳,而不是vec3:

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

最后我們希望采樣這個(gè)specular貼圖,來(lái)獲取原始像素相應(yīng)的specular亮度:

vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));

通過(guò)使用一個(gè)specular貼圖我們可以定義極為精細(xì)的細(xì)節(jié)绘盟,物體的這個(gè)部分會(huì)獲得閃亮的屬性鸠真,我們可以設(shè)置它們相應(yīng)的亮度。specular貼圖給我們一個(gè)在diffuse貼圖上的控制層龄毡。

如果你不想成為主流吠卷,你可以在specular貼圖里使用顏色,不單單為每個(gè)原始像素設(shè)置specular亮度沦零,同時(shí)也設(shè)置specular高光的顏色祭隔。從真實(shí)角度來(lái)說(shuō),specular的顏色基本是由光源自身決定的路操,所以它不會(huì)生成真實(shí)的圖像(這就是為什么圖片通常是黑色和白色的:我們只關(guān)心亮度)疾渴。

如果你現(xiàn)在運(yùn)行應(yīng)用,你可以清晰地看到箱子的材質(zhì)現(xiàn)在非常類(lèi)似真實(shí)的鐵邊的木頭箱子了:

你可以在這里找到全部源碼屯仗。

使用diffuse和specular貼圖搞坝,我們可以給相關(guān)但簡(jiǎn)單物體添加一個(gè)極為明顯的細(xì)節(jié)。我們可以使用其他紋理貼圖魁袜,比如法線(xiàn)/bump貼圖或者反射貼圖桩撮,給物體添加更多的細(xì)節(jié)。但是這些在后面教程才會(huì)涉及峰弹。把你的箱子給你所有的朋友和家人看距境,有一天你會(huì)很滿(mǎn)足,我們的箱子會(huì)比現(xiàn)在更漂亮垮卓!

練習(xí)

  • 調(diào)整光源的ambient垫桂,diffuse和specular向量值,看看它們?nèi)绾斡绊憣?shí)際輸出的箱子外觀粟按。

  • 嘗試在片段著色器中反轉(zhuǎn)鏡面貼圖(Specular Map)的顏色值诬滩,然后木頭就會(huì)變得反光而邊框不會(huì)反光了(由于貼圖中鋼邊依然有一些殘余顏色,所以鋼邊依然會(huì)有一些高光灭将,不過(guò)反光明顯小了很多)疼鸟。

解答:

vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));       // texture函數(shù)使用前面設(shè)置的紋理參數(shù)對(duì)相應(yīng)顏色值進(jìn)行采樣,返回vec4類(lèi)型
  • Try creating a specular map from the diffuse texture that uses actual colors instead of black and white and see that the result doesn't look too realistic. 如果你不會(huì)處理圖片庙曙,你可以使用這個(gè)帶顏色的鏡面貼圖空镜。

最終效果:

Image 072.png

-添加一個(gè)叫做放射光貼圖(Emission Map)的東西,即記錄每個(gè)片段發(fā)光值(Emission Value)大小的貼圖,發(fā)光值是(模擬)物體自身發(fā)光(Emit)時(shí)可能產(chǎn)生的顏色吴攒。這樣的話(huà)物體就可以忽略環(huán)境光自身發(fā)光张抄。通常在你看到游戲里某個(gè)東西(比如 機(jī)器人的眼,或是箱子上的小燈)在發(fā)光時(shí),使用的就是放射光貼圖洼怔。使用這個(gè)貼圖(作者為 creativesam)作為放射光貼圖并使用在箱子上署惯,你就會(huì)看到箱子上有會(huì)發(fā)光的字了。

機(jī)器人的眼

項(xiàng)目代碼镣隶。
實(shí)驗(yàn)結(jié)果如下:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末极谊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子安岂,更是在濱河造成了極大的恐慌轻猖,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件域那,死亡現(xiàn)場(chǎng)離奇詭異蜕依,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)琉雳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)样眠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人翠肘,你說(shuō)我怎么就攤上這事檐束。” “怎么了束倍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵被丧,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我绪妹,道長(zhǎng)甥桂,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任邮旷,我火速辦了婚禮黄选,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘婶肩。我一直安慰自己办陷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布律歼。 她就那樣靜靜地躺著民镜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪险毁。 梳的紋絲不亂的頭發(fā)上制圈,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天们童,我揣著相機(jī)與錄音,去河邊找鬼鲸鹦。 笑死慧库,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的亥鬓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼域庇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼嵌戈!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起听皿,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤熟呛,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后尉姨,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體庵朝,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年又厉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了九府。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡覆致,死狀恐怖侄旬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情煌妈,我是刑警寧澤儡羔,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站璧诵,受9級(jí)特大地震影響汰蜘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜之宿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一族操、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧比被,春花似錦坪创、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至项滑,卻和暖如春依沮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工危喉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宋渔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓辜限,卻偏偏與公主長(zhǎng)得像皇拣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子薄嫡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容