Hello all,今天跟大家嘮一下unity shader中的diffuse,我們在遊戲開發的過程中光照是必不可少的,而為了使遊戲更加真實,獲得更好的體驗,也會模擬因光照產生的各種鏡麵反射(sprcular),漫反射(diffuse),所以這裏我們先討論一下漫反射(diffuse)。
1、漫反射原理
如果我們的物體表麵凹凸不平,其表麵上每個點的法線方向就不一致。當一束外來光照射到這個物體表麵的時候,入射光線都是平行的,但是每個點由於法線方向不一致而產生不同的反射光線,如圖;

如果照在物體上的入射角為0的時候,說明光線垂直於物體表麵,看到的表麵就會越亮,即漫反射光強也是最大的;當入射角為九十度時,即光線與物體表麵平行,物體接收不到任何光線,就會產生暗部。
而漫反射光的強度到底是怎麼樣子計算的呢?
漫反射光的強度可以用lambert(可參考維基百科)定律進行計算,即漫反射的光強僅與入射光的方向和反射點處表麵法線夾角的餘弦成正比,即;
Idiffuse=Id*Kd*cosθ
Idiffuse就是表麵點的漫反射光強,Id是點光源強度,Kd(0<Kd<1)表示物體表麵該點對漫反射光的反射屬性,θ是入射光線的方向與物體表麵該點處法線N的夾角,或稱為入射角(0≤θ≤90°),而根據向量點乘N*L=|N|*|L|cosΘ (N是法線,L是太陽光的反方向)。如果對N向量和L向量進行歸一化處理的話,即讓N*L這個向量的模等於1,就會得到N*L= cosθ;而對於上麵公式中,Id和Kd對同一物體在同一個光照下參數值都是一樣的,所以影響一個物體不同點的漫反射強度的就隻有N*L了。
下圖就是最簡單的diffuse效果,一束光打在小球上因為表麵法線不一樣而呈現不同的明暗效果。

所以接下來我們就在引擎中親手實現上麵這種diffuse效果
2、場景設置
新開一個unity場景,拉一個小球在中間,修改場景light設置,去掉Sky Material,Environment Lighting設置為color(避免小球受環境光的影響),並將color改完全黑,然後Environment Reflection也設置為Custom。

此時場景中的效果應該如圖,

此時小球的並不隻受漫反射光,根據亮部可以看到還有鏡麵反射效果。
現在我們就開始用可視化shader編程為其添加一個shader,讓他隻有一個diffuse的效果。由於隻是一個簡單的材質,所以官方的shader graph和野生的shader forge都可以使用。這裏的舉例使用shader graph,畢竟親生的以後更新比較方便。
創建一個新的shader graph並雙擊打開

打開進去裏麵是一個默認的shader預設值PBR Master,對於今天所以呈現的diffuse效果來說,這個預設太過於複雜,加了很多其他的效果,specular等,所以我們要將其刪掉,然後創建一個新的node叫做Unlit。

然後我們就得到了隻有color和alpha的一個Unlit Master(無光的shader)

如果更改其color的值,整個shader都會變成這個純色,而沒有陰影高光等

所以接下來我們就按照上麵說的公式N*L(為簡化省略掉了其他點光源強度等數值)來實現diffuse效果。
場景中新建一個材質球material,然後把材質球的shader選成上麵我們新建的那個shader名字,然後將其賦給場景中的小球。

現在我們就可以在場景中直接看到我的修改shader以後的效果。
先將裏麵的color值暴露出去,shader中新建Property,並命名為DiffuseColor,然後直接將DiffuseColor拖到編輯器中,就可以看到加載了DiffuseColor的一個Property節點,將節點直接連接到Color中保存這個shader graph,在外部小球material就可以看到我們暴露出去的Diffuse Color。

3、添加法向量N
Shader graph中自帶有獲取物體法向量的節點,Normal Vector,將Normal Vector直接連接到Color中保存以後,場景中的小球顏色就會直接呈現法線的顏色。


將我們的法線小球的顏色和unity坐標軸對比可以發現,x軸正方向上的小球會更偏紅,y軸正方向的會更綠,而z軸的會更藍,這個因為在軸上的坐標值分別是(1,0,0),(0,1,0)(0,0,1),而這些坐標值所對應的顏色值就是紅綠藍,所以我們的坐標值和法線顏色值是對應的,我們就可以通過顏色值來求得法線值。

4、獲取L值
法線向量和光源方向的運算是點乘,graph裏麵對應的節點是dot,所以我們搜索添加dot節點,然後將其中N輸入進去

輸入N以後我們剩下就要給L值,但是怎麼獲取場景中點光源的L值呢?
在當前shader graph的節點中沒有獲取光線方向的節點,但是我們可以自己為其輸入L參數。新建一個三維property命名為L,然後拉到graph中與N點乘。現在默認L還沒有任何取值,即沒有光線進入,我們將x的值給個1,說明x軸方向有一束光打過來,就可以在預覽裏麵看到小球產生了明暗變化。

當前的效果隻是一個明暗變化的效果,如果我們要將diffusecolor加進來與其混合的話,就需要用Multiply將兩個值進行相乘然後輸入到unlit的color中然後保存。

回到場景中在material屬性欄可修改color和光源方向的值,我們將光源方向調到(1,1,1),然後就得到了我們經典的lambert光!

5、獲取L值
我們調節場景中的光方向到(1,0,0),然後觀察到其實光的來源方向不是x軸的正方向而是負方向。

所以實際上L的值應該取一個負號,因為計算的時候我們不能直接取入射光的方向,如果取得是入射光方向,和法線向量之間的夾角就會是一個大於九十度的鈍角,而我們算的入射角一般都是銳角,所以我們要取的是入射光方向的反方向與法線向量的點乘來得到cosθ。
所以我們在節點中將L的值或者點乘以後的值乘以-1即可取得反方向。

保存以後就可以在外部material屬性中自由調節光源方向啦
以上就實現了我們在開篇所講的diffuse效果啦。
感恩圍觀
來源:公眾號Thepoly
熱門課程
專業講師指導 快速擺脫技能困惑相關文章
多種教程 總有一個適合自己專業問題谘詢
你擔心的問題,火星幫你解答在廣州這座繁華的都市中,數字創意產業正蓬勃發展,廣州視頻剪輯培訓成為許多影視愛好者的理想起點。隨著短視頻平台和影視製作需求的激......
在北京這樣一座充滿創意活力的都市,UI設計培訓正成為無數年輕人追逐職業夢想的跳板。隨著數字經濟的蓬勃發展,UI設計行業在北京展......
在當今創意經濟蓬勃發展的浪潮中,北京平麵設計培訓成為眾多職業追求者的理想起點。這座城市的活力與機遇吸引著無數人投身視覺藝術領域......
在影視和設計行業蓬勃發展的今天,虛幻引擎作為核心技術工具,正引領著視覺創作的革命。越來越多的人渴望掌握這門技能,而專業的培訓成......
在北京這座文化創意中心,平麵設計培訓行業蓬勃發展,為渴望入行的學員提供了豐富機遇。隨著數字媒體和影視產業的崛起,掌握視覺傳達技......
在上海這座充滿活力的城市,影視和設計行業正迎來前所未有的發展機遇,數字技術的進步讓3D建模成為創意產業的核心驅動力。參加專業的......
同學您好!