蘭伯特 Lambert 模型

2021-08-16 20:37:21 字數 3701 閱讀 5982

漫反射

,是投射在粗糙表面上的光向各個方向反射的現象。當一束平行的入射光線射到粗糙的表面時,表面會把光線向著四面八方反射,所以入射線雖然互相平行,由於各點的法線方向不一致,造成反射光線向不同的方向無規則地反射,這種反射稱之為「漫反射」或「漫射」。這種反射的光稱為漫射光。很多物體,如植物、牆壁、衣服等,其表面粗看起來似乎是平滑,但用放大鏡仔細觀察,就會看到其表面是凹凸不平的,所以本來是平行的太陽光被這些表面反射後,瀰漫地射向不同方向。

(這圖盜的別人的,直觀,非原創)

漫反射光照符合蘭伯特定律:反射光線的強度與表面法線和光源方向之間的夾角的余弦成正比,因此漫反射的部分計算如下:

cdiffuse =(clight *mdiffuse )max(0,dot(n,l))

n是表面法線,l是光源方向的單位向量,mdiffuse是材質的漫反射顏色,clight是光源顏色。我們使用取最大值函式來將其擷取到0,還可以防止物體被從後面來的光源照亮。

逐頂點計算著色shader

我們在shader中需要計算輸出的顏色,逐頂點著色也就是說我們的計算主要放在了vertex shader中,根據頂點來計算,每個頂點中計算出了該點的顏色,直接作為vertex shader的輸出,pixel(fragment) shader的輸入,當到達pixel階段時,直接輸出頂點shader的結果。比如乙個三角形麵片,在vertex階段,分別計算了每個頂點的顏色值,在pixel階段時,這個麵片經過投影,最終顯示在螢幕上的畫素,會根據該畫素周圍的頂點來插值計算畫素的最終顏色,這種著色方式也叫做

高洛德著色。

shader "apcshader/diffusepervetex"

//子著色器

subshader

cgprogram

//引入標頭檔案 ,一些內建變數,如_lightcolor0,需要使用到

#include "lighting.cginc"

//定義properties中的變數

fixed4 _diffuse;

//使用vert函式和frag函式

#pragma vertex vert

#pragma fragment frag

//定義結構體:應用階段到vertex shader階段的資料,如果定義了

struct a2v

; //定義結構體:vertex shader階段輸出的內容

struct v2f

; //定義頂點shader

v2f vert(a2v v)

//定義片元shader

fixed4 frag(v2f i) : sv_target

endcg

} }//前面的subshader失效的話,使用預設的diffuse

fallback "diffuse"

}

逐畫素計算時,我們的主要計算放到了pixel shader裡,在vertex shader階段只是進行了基本的頂點變換操作,以及頂點的法線轉化到世界空間的操作,然後將轉化後的法線作為引數傳遞給pixel shader。其他的計算都放到了pixel shader階段,這樣,針對每個畫素,我們都可以來計算這個畫素的光照情況,而不是像逐頂點計算時,先計算好頂點的顏色,然後差值得到中間的畫素顏色。這種逐畫素著色的方式也叫作phone著色(非phone光照模型)

shader "custom1/lambertfragment"

//子著色器

subshader

cgprogram

//引入標頭檔案

#include "lighting.cginc"

//定義properties中的變數

fixed4 _diffuse;

//定義結構體:應用階段到vertex shader階段的資料

struct a2v

; //定義結構體:vertex shader階段輸出的內容

struct v2f

; //定義頂點shader

v2f vert(a2v v)

//定義片元shader

fixed4 frag(v2f i) : sv_target

//使用vert函式和frag函式

#pragma vertex vert

#pragma fragment frag

endcg

} }

//前面的shader失效的話,使用預設的diffuse

fallback "diffuse"

}

半蘭伯特模型

廣義的半蘭伯特模型公式如下:

cdiffuse

=(clight 

*mdiffuse 

)*(阿魯法dot(

n,

l)+貝塔)

可以看到與原蘭伯特模型相比,半蘭伯特沒有使用max操作來防止點積為負,而是對結果進行了乙個阿魯法倍的縮放再加上乙個貝塔大小的偏移。當然絕大多情況阿魯法和貝塔的值都為0.5

shader "custom1/lambertfragment"

//子著色器

subshader

cgprogram

//引入標頭檔案

#include "lighting.cginc"

//定義properties中的變數

fixed4 _diffuse;

//定義結構體:應用階段到vertex shader階段的資料

struct a2v

; //定義結構體:vertex shader階段輸出的內容

struct v2f

; //定義頂點shader

v2f vert(a2v v)

//定義片元shader

fixed4 frag(v2f i) : sv_target

//使用vert函式和frag函式

#pragma vertex vert

#pragma fragment frag

endcg

} }

//前面的shader失效的話,使用預設的diffuse

如圖,左邊是蘭伯特,右邊是半蘭伯特。對比效果還是比較明顯的

.half lambert最初是由valve(遊戲半條命2使用的引擎即是其開發的)提出來,用於提高物體在一些光線無法照射到的區域的亮度的。簡單說來,它提高了漫反射光照的亮度,使得漫反射光線可以看起來照射到乙個物體的各個表面。而half lambert最初也是被用於遊戲半條命的畫面渲染,為了防止某個物體的背光面丟失形狀並且顯得太過平面化。這個技術是完全沒有基於任何物理原理的,而僅僅是一種感性的視覺增強

簡單光照模型(Lambert 光照模型)

環境光是對光照現像的最簡單抽象,因而侷限性很大。它僅能描述光線在空間中無方向並均勻散布時的狀態。很多情況下,入射光是帶有方向的,比如典型的陽光。如果光照射到比較粗糙的物體表面,如粉筆,由於這些表面從各個方向等強度地反射光,因而從各個視角出發,物體表面呈現相同的亮度,所看到的物體表面某點的明暗程度不隨...

8 光照模型 蘭伯特光照模型

光照模型就是乙個公式,使用這個公式來計算在某個點的光照效果。標準光照模型 在標準光照模型裡,我們把進入攝像機的光分為下面幾個部分 自發光 self luminous 如螢火蟲 高光反射 specular 漫反射 diffuse 向量點乘和叉乘 點乘 標量 代表a在b上的投影和b的乘積 a b a b...

漫反射 蘭伯特和半蘭伯特

蘭伯特定律 lambert is law 反射光線的強度與表面法線和光源方向之間夾角的余弦值成正比 漫反射公式 c diffuse c light m diffuse max 0,入射光線 的顏色和強度 材質 的漫反射係數 max 0,表面法線 光源方向的點積 弊端就是在模型光照無法達到的區域通常是...