MME編寫入門(四)一個(gè)簡(jiǎn)單光照模型
糾結(jié)了半天,錯(cuò)誤和各種不規(guī)范,最后看到一句話:計(jì)算機(jī)圖形學(xué)的第一定律:如果他看起來(lái)是對(duì)的,那么他就是對(duì)的。
《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》的作者鄧恩說(shuō)的。
“他的話看起來(lái)是對(duì)的,所以是對(duì)的?!蔽疫@么理解道。
嗯……大概是對(duì)的吧……這個(gè)光照模型還缺少Sph,不過(guò)問(wèn)題倒也不大。
嗯……下次再考慮加上spa吧。看舞力介入的full.fx中是將影色單獨(dú)拿出來(lái)寫的……
首先是準(zhǔn)備數(shù)據(jù)。這次需要的數(shù)據(jù)比上次多很多。
矩陣是必須的。接下來(lái)是這些。(唉我是真的麻了……我寫的整整齊齊的代碼扔進(jìn)這個(gè)網(wǎng)頁(yè)就不給我對(duì)齊,手動(dòng)對(duì)齊好幾遍還不齊)
參考MME手冊(cè)。即可明白書寫的格式。把語(yǔ)義寫對(duì)了就沒(méi)太大問(wèn)題。


顏色計(jì)算。static的作用應(yīng)該和C語(yǔ)言里的一樣,用來(lái)說(shuō)明靜態(tài)變量,聲明了static后變量就是內(nèi)部變量。
簡(jiǎn)單光照模型,假定物體為非透明物體,物體表面所呈現(xiàn)的顏色僅由反射光決定,不考慮透射光。反射光部分被細(xì)分為漫反射光 DiffuseColor 和 鏡面反射光SpecularColor兩種。
簡(jiǎn)單光照模型分為 環(huán)境光模型、漫反射光模型、鏡面反射光模型,全部屬于經(jīng)驗(yàn)?zāi)P?,表現(xiàn)為:

I表示物體表面上一點(diǎn)反射到視點(diǎn)的光強(qiáng),e、d、s分別為環(huán)境光光強(qiáng)、漫反射光光強(qiáng)、鏡面反射光光強(qiáng)。
材質(zhì)部分,要考慮材質(zhì)屬性,材質(zhì)屬性是指物體表面對(duì)光的吸收、反射和透射的性能。由于是簡(jiǎn)單光照模型,所以只考慮材質(zhì)的反射屬性。
鏡面反射光較為特殊,要考慮鏡面反射率,所以引用了float?SPECULARPOWER
然后是

然后是采樣器。
如果要調(diào)用紋理,那么就需要采樣器。

然而紋理,是沒(méi)法直接使用的。需要濾波。不理解也沒(méi)關(guān)系,這東西絕大部分情況下都不用改,復(fù)制粘貼調(diào)用就行。
結(jié)構(gòu)體準(zhǔn)備我們需要的用到的數(shù)據(jù)。然后是頂點(diǎn)著色,輸入輸出都很正常。這里我們呢需要準(zhǔn)備 一個(gè)Eye的視點(diǎn)位置的數(shù)據(jù)。這個(gè)視點(diǎn)位置這樣計(jì)算。
Normal 頂點(diǎn)法線的轉(zhuǎn)換,然后單位化。
這里用到了新的函數(shù)normalize(x),意思是返回單位化向量,定義為 x / length(x)。
然后是像素著色器的部分。
首先得定義個(gè)Color,后面才能用。
Color.rgb,意思是取得Color的前三維,我在上一篇有說(shuō)但是沒(méi)舉例子。
舉個(gè)例子,如果float4 Color = float4(1,0.2,0.3,1),那么Color.rgb 的意思就是調(diào)用1,0.2,0.3,這三維。Color.r,同理,調(diào)用第一維。
同理,xyzw,也可以。Color.xyzw 和?Color.rgba等效,但是不能混著用。
這里用到了新的函數(shù)saturate(x),意思是把x截取到[0, 1]之間。
函數(shù)max(x, y),意思是取x,y兩者中較大的。
這里是計(jì)算物體的rgb值。就是物體的法向*漫反射顏色+環(huán)境色。
接下來(lái)計(jì)算反射光顏色。這里用到了一個(gè)半程向量,通過(guò)對(duì)觀察向量和光向量取平均然后歸一化得到一個(gè)新的向量,新向量稱為半程向量(bisector),使用半程向量與法線點(diǎn)乘來(lái)計(jì)算高光。
這里有個(gè)新函數(shù)pow,pow(x, y),意思是x^y。
使用半程向量,是為了簡(jiǎn)化計(jì)算。

Phong提出的一個(gè)計(jì)算鏡面反射光的經(jīng)驗(yàn)公式,成為Phong模型。模型上一點(diǎn)P的鏡面反射光強(qiáng)為:
為入射光強(qiáng),
為鏡面反射率
對(duì)于單位向量R、V,有,考慮有大于90的情況,R·V的結(jié)果為負(fù),應(yīng)該取0,所以改寫為
不難看出鏡面反射的光強(qiáng)不僅取決于物體表面的法線方向,而且依賴于光遠(yuǎn)與視線的相對(duì)位置。只有當(dāng)視點(diǎn)位于比較合適的位置時(shí),才可以觀察到物體表面某些區(qū)域呈現(xiàn)的高光。所以在簡(jiǎn)單光照模型中,“視點(diǎn)固定,旋轉(zhuǎn)物體”和“視點(diǎn)旋轉(zhuǎn),物體固定”所看到的物體是有差別的。
V的計(jì)算很簡(jiǎn)單,R的計(jì)算稍微復(fù)雜。

圖片源于《三維計(jì)算機(jī)圖形學(xué)》
總結(jié)下來(lái),Phong模型的計(jì)算非常復(fù)雜,再加上環(huán)境光和漫射光,會(huì)讓式子變得更長(zhǎng)。
Blinn指出中分向量H的方向是最大反射光強(qiáng)方向,對(duì)模型進(jìn)行改進(jìn),改進(jìn)后的模型成為Blinn-Phong模型。Blinn用N·H代替R·V,其中H為中分向量,是單位光向量L和單位觀察向量V的平分向量。
改進(jìn)后的公式表述為

圖片源于《三維計(jì)算機(jī)圖形學(xué)》
這里用到了新的函數(shù)tex2D(s,t),意思是返回紋理s在t位置的顏色。
接下來(lái)做個(gè)判斷,woc我這里寫錯(cuò)了,前邊的插入的代碼塊不知道怎么變更了……麻煩把這個(gè)UseTexture改成UseToon,這里是在判斷是否使用toon,做了一個(gè)插值計(jì)算。
雖然可能對(duì)結(jié)果影響不大,因?yàn)楝F(xiàn)在絕大部分模型都有toon。
這里用了一個(gè)新函數(shù)lerp,lerp(x, y, s),對(duì)x、y進(jìn)行插值計(jì)算。Returns x + s(y - x)。
最后是個(gè)pass
注意

